diff options
author | gdb-2.8 <gdb@fsf.org> | 1988-09-03 08:00:00 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2012-06-03 15:36:31 +0100 |
commit | 3bf57d210832b28e9361990830eb722a619f031b (patch) | |
tree | ba506d293bde0f6500d0cee3e643ebf8890d9cf7 | |
parent | 7c75bab3d3ef344a6a0b13b9ab59ecd5855aceb5 (diff) | |
download | gdb-3bf57d210832b28e9361990830eb722a619f031b.zip gdb-3bf57d210832b28e9361990830eb722a619f031b.tar.gz gdb-3bf57d210832b28e9361990830eb722a619f031b.tar.bz2 |
gdb-2.8
-rw-r--r-- | gdb/COPYING | 146 | ||||
-rw-r--r-- | gdb/ChangeLog | 1609 | ||||
-rw-r--r-- | gdb/Makefile | 48 | ||||
-rw-r--r-- | gdb/ORIGIN | 16 | ||||
-rw-r--r-- | gdb/ORIGIN.ls.lag | 95 | ||||
-rw-r--r-- | gdb/ORIGIN.ls.pmax | 95 | ||||
-rw-r--r-- | gdb/README | 32 | ||||
-rw-r--r-- | gdb/TAGS | 1191 | ||||
-rw-r--r-- | gdb/blockframe.c | 4 | ||||
-rw-r--r-- | gdb/breakpoint.c | 205 | ||||
-rw-r--r-- | gdb/coffread.c | 1423 | ||||
-rw-r--r-- | gdb/coffread.c.README | 12 | ||||
-rw-r--r-- | gdb/coffread.c.pmax | 1851 | ||||
-rw-r--r-- | gdb/command.c | 2 | ||||
-rw-r--r-- | gdb/config.gdb | 119 | ||||
-rw-r--r-- | gdb/core.c | 84 | ||||
-rw-r--r-- | gdb/dbxread.c | 1309 | ||||
-rw-r--r-- | gdb/defs.h | 1 | ||||
-rw-r--r-- | gdb/eval.c | 408 | ||||
-rw-r--r-- | gdb/expprint.c | 22 | ||||
-rw-r--r-- | gdb/expread.tab.c | 2152 | ||||
-rw-r--r-- | gdb/expread.y | 194 | ||||
-rw-r--r-- | gdb/expression.h | 25 | ||||
-rw-r--r-- | gdb/findvar.c | 8 | ||||
-rw-r--r-- | gdb/gdb+.texinfo | 2795 | ||||
-rw-r--r-- | gdb/gdb.1 | 91 | ||||
-rw-r--r-- | gdb/gdb.ideas | 1277 | ||||
-rw-r--r-- | gdb/gld-pinsn.c | 284 | ||||
-rw-r--r-- | gdb/infcmd.c | 31 | ||||
-rw-r--r-- | gdb/inflow.c | 337 | ||||
-rw-r--r-- | gdb/infrun.c | 88 | ||||
-rw-r--r-- | gdb/initialize.h | 2 | ||||
-rw-r--r-- | gdb/m-hp9k320.h | 542 | ||||
-rw-r--r-- | gdb/m-hp9k320bsd.h | 508 | ||||
-rw-r--r-- | gdb/m-init.h (renamed from gdb/m-suninit.h) | 0 | ||||
-rw-r--r-- | gdb/m-isi.h (renamed from gdb/m-isi-ov.h) | 15 | ||||
-rw-r--r-- | gdb/m-isiinit.h | 11 | ||||
-rw-r--r-- | gdb/m-merlin.h | 440 | ||||
-rw-r--r-- | gdb/m-news.h | 534 | ||||
-rw-r--r-- | gdb/m-newsinit.h | 4 | ||||
-rw-r--r-- | gdb/m-npl.h | 502 | ||||
-rw-r--r-- | gdb/m-nplinit.h | 4 | ||||
-rw-r--r-- | gdb/m-pn.h | 486 | ||||
-rw-r--r-- | gdb/m-pninit.h | 4 | ||||
-rw-r--r-- | gdb/m-sun2.h | 2 | ||||
-rw-r--r-- | gdb/m-sun2init.h | 5 | ||||
-rw-r--r-- | gdb/m-sun3.h | 2 | ||||
-rw-r--r-- | gdb/m-sun3init.h | 5 | ||||
-rw-r--r-- | gdb/m-umax.h | 436 | ||||
-rw-r--r-- | gdb/m-umaxinit.h | 4 | ||||
-rw-r--r-- | gdb/m-vax.h | 3 | ||||
-rw-r--r-- | gdb/m68k-opcode.h | 8 | ||||
-rw-r--r-- | gdb/m68k-pinsn.c | 16 | ||||
-rw-r--r-- | gdb/main.c | 167 | ||||
-rw-r--r-- | gdb/npl-opcode.h | 423 | ||||
-rw-r--r-- | gdb/ns32k-opcode.h | 307 | ||||
-rw-r--r-- | gdb/ns32k-pinsn.c | 457 | ||||
-rw-r--r-- | gdb/obstack.c | 55 | ||||
-rw-r--r-- | gdb/obstack.h | 102 | ||||
-rw-r--r-- | gdb/opcode.h | 1272 | ||||
-rw-r--r-- | gdb/param.h | 478 | ||||
-rw-r--r-- | gdb/parent.c | 126 | ||||
-rw-r--r-- | gdb/pinsn.c | 770 | ||||
-rw-r--r-- | gdb/pn-opcode.h | 283 | ||||
-rw-r--r-- | gdb/printcmd.c | 415 | ||||
-rw-r--r-- | gdb/remote.c | 28 | ||||
-rw-r--r-- | gdb/source.c | 118 | ||||
-rw-r--r-- | gdb/stack.c | 14 | ||||
-rw-r--r-- | gdb/standalone.c | 3 | ||||
-rw-r--r-- | gdb/symmisc.c | 2 | ||||
-rw-r--r-- | gdb/symseg.h | 85 | ||||
-rw-r--r-- | gdb/symtab.c | 592 | ||||
-rw-r--r-- | gdb/symtab.h | 78 | ||||
-rw-r--r-- | gdb/test2.c | 13 | ||||
-rw-r--r-- | gdb/testbit.c | 12 | ||||
-rw-r--r-- | gdb/testbpt.c | 33 | ||||
-rw-r--r-- | gdb/testkill.c | 5 | ||||
-rw-r--r-- | gdb/utils.c | 21 | ||||
-rw-r--r-- | gdb/valarith.c | 163 | ||||
-rw-r--r-- | gdb/valops.c | 452 | ||||
-rw-r--r-- | gdb/valprint.c | 456 | ||||
-rw-r--r-- | gdb/value.h | 22 | ||||
-rw-r--r-- | gdb/values.c | 119 | ||||
-rw-r--r-- | gdb/vax-pinsn.c | 2 | ||||
-rw-r--r-- | gdb/version.c | 2 | ||||
-rw-r--r-- | gdb/wait.h | 4 | ||||
-rw-r--r-- | gdb/xgdb.c | 644 |
87 files changed, 16657 insertions, 10553 deletions
diff --git a/gdb/COPYING b/gdb/COPYING new file mode 100644 index 0000000..eb1bf4f --- /dev/null +++ b/gdb/COPYING @@ -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. diff --git a/gdb/ChangeLog b/gdb/ChangeLog new file mode 100644 index 0000000..7099697 --- /dev/null +++ b/gdb/ChangeLog @@ -0,0 +1,1609 @@ +Sat Sep 3 12:05:36 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu) + + * Version 2.8 released. + + * valprint.c: include param.h. + + * inflow.c (store_inferior_registers): Fix typo and missing decl. + +Thu Sep 1 13:18:22 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu) + + * Version 2.7 released. + + * m-hp9k320bsd.h: New file supports BSD on hp9000 series 300. + +Tue Aug 30 17:54:50 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu) + + * m-news.h ({EXTRACT,STORE}_RETURN_VALUE): Handle floating pt values. + + * inflow.c (store_inferior_registers) [usual case]: + Handle registers longer than one word. + +Sat Aug 27 00:19:32 1988 Richard Stallman (rms at spiff) + + * inflow.c (create_inferior): Use execve to avoid NEWSOS bug in execle. + +Wed Aug 10 20:36:36 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu) + + * m-news.h: Define READ_DBX_FORMAT, {EXTRACT,STORE}_RETURN_VALUE. + (INVALID_FLOAT): Add 2nd argument. + (vprintf): Define to call _doprnt. + +Tue Jul 26 03:05:28 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * symmisc.c: (print_symtabs) Check the status of the fopen and + call perror_with_name if needed. + +Sat Jul 23 00:14:20 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * printcmd.c: (delete_display) Check for existence of display + chain before deleting anything. + +Thu Jul 7 08:47:03 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu) + + * main.c: New vars win_argv, win_argc, win_prgm to talk to xgdb. + +Thu Jul 7 02:05:29 1988 Pete TerMaat (pete at frosted-flakes.ai.mit.edu) + + * dbxread.c: (define_symbol) store static functions ('f') in the + same way as global functions ('F') -- that is, as `function of + type X' rather than as `X'. + +Mon Jul 4 17:07:31 1988 Pete TerMaat (pete at frosted-flakes.ai.mit.edu) + + * dbxread.c: (read_dbx_symtab) Avoid reading symbol tables of + libraries by checking for symbols which begin with "-l" (in + addition to those which end with ".o"). + +Mon Jun 27 23:27:51 1988 Pete TerMaat (pete at frosted-flakes.ai.mit.edu) + + * dbxread.c: (define_symbol) and coffread.c: (process_coff_symbol) + If the current symbol is a function, assign its type to be + `function of type X' rather than `X'. TYPE_TARGET_TYPE (symbol) + is `X' + + * findvar.c: (locate_var_value, read_var_value) got rid of checks + for LOC_BLOCK which called `lookup_function_type'. These checks + are no longer needed because of the change to dbxread.c. + + * infcmd.c: (finish_command) Now uses target_type instead of type + for functions, in keeping with the change to dbxread.c. + +Sat Jun 25 00:24:09 1988 Pete TerMaat (pete at corn-chex.ai.mit.edu) + + * infrun.c: (normal_stop) Added a check for permissions on the + exec file before printing the "You have encountered a bug in sh" + message. Apparently on some systems an attempt by the shell to + exec an unexecutable file had resulted in the "You have + encountered" message. + +Wed Jun 22 00:00:02 1988 Pete TerMaat (pete at corn-chex.ai.mit.edu) + + * config.gdb: installed shell script to make the proper links to + param.h, m-init.h, opcode.h, and pinsn.c, given a machine name. + +Tue Jun 21 23:55:09 1988 Pete TerMaat (pete at corn-chex.ai.mit.edu) + + * m-suninit.h, m-isi-ov.h, m-news800.h: moved to m-sun3init.h, + m-isi.h, m-news.h for consistency. + +Fri Jun 17 21:24:48 1988 Pete TerMaat (pete at lucky-charms.ai.mit.edu) + + * m-umax.h: (FIX_CALL_DUMMY): fixed typo (the last `flipped' was + `fliped') + + * m-pn.h, m-npl.h: added #define gould, since this is needed in + core.c. + +Tue Jun 14 04:07:50 1988 Pete TerMaat (pete at lucky-charms.ai.mit.edu) + + * Removed unused variables from m-pn.h, m-npl.h in + FRAME_FIND_SAVED_REGS, PUSH_DUMMY_FRAME, and POP_FRAME. + +Mon Jun 13 05:57:47 1988 Richard Stallman (rms at corn-chex.ai.mit.edu) + + * inflow.c (create_inferior): Allow two macros SHELL_FILE and + SHELL_COMMAND_CONCAT, if defined, to customize how the shell is run. + +Thu Jun 9 05:42:20 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu) + + * breakpoint.c (ignore_command): P was used before initialized. + +Fri Jun 3 06:52:25 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu) + + * dbxread.c (read_dbx_symtab): Change handling of N_NBTEXT (Gould). + +Mon May 30 22:48:48 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu) + + * main.c (main, disconnect): Handle SIGHUP by killing inferior. + * inflow.c (kill_inferior_fast): New function used to do that. + + * utils.c (printchar): New 3rd arg is the string's delimiter, + which is the char that needs backslashing. + * valprint.c (value_print, val_print): Pass new arg. + * expprint.c (print_subexp): Pass new arg. + +Mon May 23 14:54:54 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * source.c (print_source_lines): New arg NOERROR nonzero means + if file is not found just print message and return (don't throw). + Callers changed here and in stack.c. + +Sun May 22 14:22:54 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * source.c (identify_source_line): Set defaults for `list' command. + + * dbxread.c (sort_syms): If not sorting the block, reverse it, so + that for a parm declared register the register comes before the parm. + + * defs.h: declare alloca. + +Fri May 20 15:02:50 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * values.c (value_of_internalvar): `return' stmt was missing. + +Tue May 10 23:03:29 1988 Richard Stallman (rms at corn-chex.ai.mit.edu) + + * source.c ({forward,reverse}_search_command, print_source_lines): + Line number symtab->nlines is just barely in range. + (find_source_lines): Newline as last char in file doesn't start a line. + +Thu May 5 15:04:40 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * Version 2.6. + + * printcmd.c (do_one_display): New fn, display one auto-display. + (do_displays): Use that fn. + (display_command): If cmd is from tty, display the new display now. + + * printcmd.c (do_display): Record # of display being displayed. + (delete_current_display): New fn: delete that display (if any). + * main.c (return_to_top_level): Call delete_current_display. + * infrun.c (normal_stop): Likewise. + + * main.c (catch_error): New fn: like list `errset'. + * breakpoint.c (breakpoint_cond_eval): Eval an expression and + return 1 if the expression is zero. + (breakpoint_stop_status): Use those two fcns; avoid lossage on error + in evalling a breakpoint condition. + + * infcmd.c (jump_command): Typo in call to `query'. + +Tue May 3 10:52:08 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * core.c (exec_file_command): If no file, pass 0 to display-hook. + + * core.c (get_exec_file): New arg ERR says whether to err if no file. + All callers changed. + + * main.c (print_prompt): New fn to print the prompt string. + + * xgdb.c: Numerous changes. It now semi-works but the text display + often gets messed up. + +Sun May 1 12:12:43 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * wait.h [HAVE_WAIT_STRUCT] (WSETSTOP): Fix typos. + +Sat Apr 30 10:18:56 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * expread.y: BLOCK::NAME action called copy_name in wrong place. + +Fri Apr 15 01:01:40 1988 Chris Hanson (cph at kleph) + + * inflow.c [! TIOCGPGRP]: Do not call `setpgrp' for inferior. + Instead, disable SIGINT and SIGQUIT while the inferior is running. + Unfortunately this means that C-c typed while GDB is running will + cause the inferior to receive SIGINT when it is resumed. + * utils.c (quit) [! TIOCGPGRP]: Cause quit message to remind user + that the inferior will see SIGINT. + +Thu Apr 14 23:38:02 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * infrun.c (wait_for_inferior): If step into a function, and + immediately arrive at start of first line of user code, + don't step: stop immediately. + Set prev_pc before, not after, calling `resume'. + + * source.c (identify_source_line): New 3rd arg controls additional + output datum: `beg' or `middle', saying whether pc is at beg of line. + * stack.c (print_frame_info): Pass that argument. + + * main.c (cd_command): Convert any relative pathname to absolute. + Simplify if `.' or `..' appear. + +Thu Apr 14 21:17:11 1988 Chris Hanson (cph at kleph) + + * infrun.c: Add new flag `trap_expected_after_continue' to + compensate for spurious trace trap generated by HP-UX after + running a stack dummy. + + * inflow.c (term_status_command) [HAVE_TERMIO]: Show all available + terminal status information. + +Tue Apr 12 19:11:00 1988 Chris Hanson (cph at kleph) + + * stack.c (print_frame_info): When -fullname is given and + `identify_source_line' succeeds, do not print real pc even if it + differs from the start pc for the source line. This information + is not very useful and tends to screw up gdb-mode in emacs. + +Mon Apr 11 14:22:10 1988 Chris Hanson (cph at kleph) + + * dbxread.c (define_symbol): Don't forget to terminate + SYMBOL_NAME. + + * m-hp9k320.h (CALL_DUMMY): Fix bug -- breakpoint instruction is + TRAP #1 not TRAP #15. + + * inflow.c (store_inferior_register_1) [HP9K320]: Ignore `errno', + as there is a bug in HP-UX which (mistakenly) causes errno to be + non-zero when writing fp7. + +Sat Apr 9 01:04:23 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * dbxread.c (symbol_file_command): Check stringtab size by doing `stat' + and, if it is ridiculous, complain and don't call alloca. + Don't discard existing symtab until after that check. + +Fri Apr 8 16:39:11 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * Makefile: Delete `-lg' entirely; not needed now that linking is done + with $(CC). + +Fri Apr 8 13:41:46 1988 Chris Hanson (cph at kleph) + + * m68k-opcode.h: Fix operand-string of fmovel insns. + + * Makefile: Put "-lg" in CLIBS because there is no such library in + HPUX. Update the comment for HPUX. + +Fri Apr 8 03:30:23 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * findvar.c (locate_var_value): For &FCN, do lookup_function_type. + + * valprint.c (val_print): Fix typo testing whether ptr is a string. + +Thu Apr 7 21:11:00 1988 Chris Hanson (cph at frosted-flakes.ai.mit.edu) + + * m-hp9k320.h: New file. + + * main.c (stop_sig, read_line): #ifdef SIGTSTP around uses of SIGTSTP. + + * wait.h: Fix bug in WSETEXIT. + + * remote.c: If HAVE_TERMIO, use termio and fake it to look like stty. + Include wait.h + (remote_wait): Use the wait.h interface. + + * utils.c (quit): Need HAVE_TERMIO conditional. Also include param.h. + + * inflow.c: If HAVE_TERMIO, use termio and fake it to look like stty. + Define TERMINAL for data type of terminal data. + Use of tchars, ltchars, pgrp conditional on existence of the + ioctls that handle them. + (terminal_init_inferior, terminal_inferior, terminal_ours, + term_status_command, initialize): + Conditionals for HAVE_TERMIO and existence of various ioctls. + ({fetch,store}_inferior_registers): Separate versions for HP9K320. + + * m68k-pinsn.c (convert_{to,from}_68881): Alternate asms for HPUX_ASM. + + * core.c (register_addr): Change #ifdef to REGISTER_U_ADDR + (core_file_command) [HP9K320]: Special code to get regs from HPUX + core file. + +Thu Apr 7 01:15:56 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * dbxread.c (add_symbol_to_list, finish_block, read_enum_type): + Symbol-lists now hold up to 20 symbols in each `struct pending' + to save time in malloc. When a `struct pending' becomes free, + don't call `free'; put it on a free-list `free_pendings'. + (really_free_pendings): Call `free' for each `struct pending' + on the free-list, and others that are easily found. + (symbol_file_command): Set up `really_free_pendings' as a cleanup. + + * dbxread.c (start_symtab, end_symtab, process_one_symbol): + Context_stack is now contiguous, to save malloc-time. + + * dbxread.c (read_enum_type): Allocate the enum const syms + in the symbol_obstack. + (obsavestring): New fn, like savestring but alloc in symbol_obstack. + (obconcat): New fn, like concat but etc. + Most calls to savestring and concat changed to call these fns. + (define_symbol): Open-code bcopy; don't bother to zero the symbol. + (compare_symbols): Compare 1st char of name before calling strcmp. + + * Do explicit buffering to read symtab--don't use stdio. + Variables symbuf... hold the buffer and indices. + * dbxread.c (fill_symbuf): Fill the buffer, record how much was read. + (read_dbx_symbols, next_symbol_text): Fetch data direct from buffer; + call fill_symbuf when necessary. + + * dbxread.c (sort_syms): Don't sort blocks with < 40 syms. + * symtab.c (lookup_block_symbol): Don't binary search such blocks. + Compare 1st char of name before calling strcmp, and other speedups. + + * symtab.c (sort_block_syms): New fn, sort one block's syms. + (list_symbols): If block not normally sorted, sort it here. + + * dbxread.c (define_symbol): Ignore sym if name is empty. + (process_one_symbol): Ignore N_ENTRY sym if no N_SO seen yet. + (read_dbx_symtab): Recognize N_NBTEXT like N_TEXT (if it's defined). + Set end_of_text_addr from END_OF_TEXT_DEFAULT (if it's defined). + (NUMBER_OF_SYMBOLS): New macro for # entries in symtab. + (SYMBOL_TABLE_OFFSET): New macro for file-offset of symtab. + (STRING_TABLE_OFFSET): New macro for file-offset of string tab. + (READ_STRING_TABLE_SIZE): New macro to store size of string tab. + (DECLARE_FILE_HEADERS): New macro to declare vars to hold header info. + (READ_FILE_HEADERS): New macro to read that info from a descriptor. + All these macros can be overriden by the m-....h file. + (symbol_file_command): These macros replace open code. + + * values.c (unpack_double): When fetching `double' from memory, + make it double-aligned, since some machines need that. + + * core.c (exec_file_command): Insert conditionals for `gould'. + + * m-sun[23].h, m-isi-ov.h, m-news800.h (ABOUT_TO_RETURN): + Fix typo in opcode number. + + * main.c (read_line): Ignore backslash-newline. + +Fri Apr 1 17:37:25 1988 Richard M. Stallman (rms at frosted-flakes.ai.mit.edu) + + * main.c (main): New -c switch specifies current directory. + Discard trailing slash from arg. + (pwd_command): Call getwd. Print its result as well as + current_directory if they differ. + (cd_command): Leave user's form of path in current_directory. + Discard trailing slash from arg. + + * source.c (init_source_path, directory_command): + Use current_directory rather than calling getwd. + +Fri Mar 25 14:51:39 1988 Richard M. Stallman (rms at frosted-flakes.ai.mit.edu) + + * dbxread.c (read_struct_type): Only ints and enums can be bit-fields. + + * command.c (lookup_command): Allow 0 in command name. + + * valprint.c (value_print): New arg FORMAT. Most callers pass 0. + Pass FORMAT to val_print. + (val_print): New arg FORMAT. Most callers pass 0. + When FORMAT is nonzero, use `print_scalar_formatted' to print a scalar + and inhibit special treatment of char-pointers and arrays. + + * printcmd.c (print_scalar_formatted): Guts of `print_formatted' + broken out, except for `i', `s' and 0 formats. + Type and data-address passed separately. + + * valprint.c (val_print): Any array of 1-byte ints is a string; + any 1-byte int is a character. + +Thu Mar 24 23:01:24 1988 Richard M. Stallman (rms at frosted-flakes.ai.mit.edu) + + * coffread.c: + Make read_coff_symtab interruptible. + Use obstack rather than xmalloc for blocks, blockvectors and symbols. + Fix error checking for reading the stringtab. + + * ns32k-pinsn.c (fbit_extract): New function. + (print_insn_arg): Use it for immediate floating args. + Also print float reg args as `f<digit>', not `r<digit>'. + + * m68k-opcode.h: mulu and muluw had wrong arg-format-string. + + * valprint.c (value_print): Any pointer to 1-byte ints + is printed as a string. + + * inflow.c (attach, detach): Change conditional on these to + ATTACH_DETACH. In a UMAX_PTRACE conditional, define the Sun + attach/detach names in terms of the Umax ones. + + * m-umax.h: Define ATTACH_DETACH. + + * infcmd.c (attach_command): `remote' was not being initialized. + + * m-umax.h: Include defs.h if nec so that CORE_ADDR is defined. + + * m-umax.h, m-vax.h: Define vprintf to use _doprnt. + * m-isi-ov.h, m-merlin.h: Likewise. + + * inflow.c [UMAX_PTRACE]: Don't include user.h; do include sys/ptrace.h + + * m-umax.h: Rename `n32k...' to `ns32k...'. + * ns32k-pinsn.c: Likewise. + + * stack.c (print_block_frame_locals): Mention static locals as well. + + * main.c (validate_comname): Allow 0 in a command name. + + * core.c (myread): If successful, return # chars read. + + * blockframe.c (find_pc_misc_function): Don't die due to index -1 + if there are no misc functions. + +Sun Mar 20 17:52:00 1988 Richard M. Stallman (rms at frosted-flakes.ai.mit.edu) + + * m-isiinit.h: New file needed on ISI machines. + Symbol BSD43_ISI40D controls choice of system version. + + * m-isi-ov.h: BSD43_ISI40D affects REGISTER_U_ADDR. + +Sat Mar 19 17:56:02 1988 Richard M. Stallman (rms at frosted-flakes.ai.mit.edu) + + * dbxread.c (symbol_file_command): Clear global_sym_chain here + before read_symsegs + (read_dbx_symtab): instead of clearing it here. + + * valprint.c (type_print_base): Handle if TYPE is 0. + (type_print_varspec_{prefix,suffix}): Do nothing if TYPE is 0. + + * main.c (copyright_info): Fix typo in string. + * symseg.h: Fix typo in struct. + +Fri Mar 18 01:07:10 1988 Chris Hanson (cph at kleph) + + * breakpoint.c (commands_command): Flush stdout after printing + message for benefit of terminals which are pipes. + +Tue Feb 16 18:28:24 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * dbxread.c (process_one_symbol): Ignore some Fortran symbol types. + +Wed Feb 10 15:48:30 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * Version 2.5. + + * symtab.h: Delete free_explicit. + * symmisc.c (free_all_symtabs): Delete free_explicit case. + + * symseg.h (struct source): It contains a linetable. Define linetable. + * symtab.h: Don't define linetable here. + + * symmisc.c (relocate_source): Relocate the linetable it contains. + * dbxread.c (symbol_file_command): Convert each symseg to one or + more symtabs according to its sourcevector. Give each symtab + a linetable that comes from the sourcevector. + + Free old symtabs and Print "Reading..." before reading symsegs. + + * dbxread.c (start_symtab): If find a current_symseg, return + doing nothing more. + * dbxread.c (end_symtab): If have a current_symseg, + just zero a couple of variables and return. Delete the rest + of the if-statement for current_symseg != 0. + +Sat Feb 6 12:59:29 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * findvar.c (locate_var_value): Remove space from middle of `+ ='. + + * symtab.h (struct symtab): New field `fullname'. + * source.c: Callers of `openp' store the `fullname' field. + + * source.c (identify_source_line): New function prints + ^z^zFILENAME:LINENUM:CHARPOS\n. For Emacs interface (gdb.el). + + * main.c (main): `-fullname' option sets `frame_file_full_name'. + * stack.c (print_stack_frame): After printing source line, + if `frame_file_full_name', call `identify_source_line'. + +Fri Feb 5 00:07:44 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * core.c (core_file_command): For UMAX, print the core file's + program name. For UMAX and Sun, print the signal number. + + * printcmd.c (decode_format): Don't let size `g' be used for integers. + + * coffread.c (read_coff_symtab): Don't lose a file + just because it contains only data and types (no text). + + * source.c: Rename line_info_default_line to last_line_listed. + * source.c (*_search_command): Use that as default place to start. + Set current_source_line so that `list' with no args is centered + on that line. + +Thu Feb 4 19:32:31 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * dbxread.c (end_symtab): Always initialize symtab->free_ptr. + + * main.c (main, cd_command): Set up `dirbuf' and `current_directory' + * main.c (pwd_command): Use `current_directory'. + +Wed Feb 3 11:49:10 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * remote.c: New file, for communication to remote debugger. + + * defs.h (current_directory): New variable. + + * core.c (core_file_command): Use current_directory instead of getwd. + + * inflow.c (callers of ptrace): If remote_debugging, call another + function named remote_... instead of ptrace. + + * infcmd.c (start_inferior): Special things if remote_debugging. + + * infcmd.c (attach_command): If arg starts with a slash, + call `remote_open' and `start_remote'. + + * infcmd.c (run_command): if remote_debugging, + don't hassle the args and don't fork. + + * infrun.c, inferior.h (remote_debugging): New variable. + * infrun.c (wait_for_inferior): If remote_debugging, use remote_wait. + * infrun.c (start_remote): New function. + + * symtab.c (find_line_common): Find the linetable entry + for a specified source line, of the first following line that has one. + No longer assumes lines are in increasing order. + + * symtab.c (find_line_pc, find_line_pc_range): Use find_line_common. + + * symtab.c (lookup_misc_func): New function to return the index + in misc_function_vector of a specified name. + + * symtab.c (decode_line_1): Use `lookup_misc_func'. + + * source.c (forward_search_command, reverse_search_command): + New functions to search a source file. + + * source.c (openp): Get dir from `current_directory', not getwd. + + * source.c (line_info): 2nd arg to decode_line_spec was missing. + + * printcmd.c (printf_command): New command to do printf + with specified string and arguments. Thoroughly rewritten from + Next's version. + + * eval.c (parse_to_comma_and_eval): New function. + + * expread.y (parse_c_1): New arg COMMA means stop parsing at a comma. + * breakpoint.c (condition_command, break_command): Pass 0 for COMMA. + * eval.c (parse_and_eval_address_1): Pass 0 for COMMA. + + * printcmd.c (print_formatted): New arg SIZE so hex nums line up. + Changed all callers (all in this file). + + * dbxread.c (symbol_file_command): Error-check result of alloca. + On some systems it seems it can return zero. + + * dbxread.c (read_dbx_symtab): Make this interruptable. + + * blockframe.c (find_pc_misc_function): Use binary search. + +Thu Jan 28 08:48:00 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * m68k-pinsn.c (print_insn_arg): For operand type 'd', + operand value is a register-name. + +Sat Jan 23 01:04:51 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * symseg.h: Add `struct sourcevector', etc., for describing + line number info. + +Fri Jan 15 05:09:18 1988 Richard Stallman (rms at frosted-flakes) + + * valprint.c [IEEE_FLOAT]: New function `is_nan' checks + whether a double is a nan. + + * printcmd.c (print_formatted) [IEEE_FLOAT]: + Detect nans and print specially. + * valprint.c (val_print) [IEEE_FLOAT]: Same thing. + + * m68k-pinsn.c (convert_{to,from}_68881): Hand-assemble + all the assembler code. + + * m-newsinit.h, m-news800.h: Two new files. + +Thu Jan 7 22:25:16 1988 Richard Stallman (rms at frosted-flakes) + + * valops.c (value_assign): Don't coerce the arg being stored in. + Coercion is not right either for an array or for an enum. + +Tue Jan 5 00:59:29 1988 Richard Stallman (rms at frosted-flakes) + + * symtab.c (decode_line_1): Don't complain about no symtabs loaded + until after trying the misc function table. + +Sat Jan 2 13:16:08 1988 Richard Stallman (rms at frosted-flakes) + + * stack.c (record_selected_frame): New fn to access + the selected frame and its level. + * infcmd.c (run_stack_dummy): Save and restore the selected + frame and its level. + +Wed Dec 30 18:44:41 1987 Richard Stallman (rms at frosted-flakes) + + * valprint.c (type_print_varspec_prefix): + Treat arrays just like functions. + * valprint.c (type_print_varspec_{prefix,suffix}): + When passed_a_ptr is handled, pass 0 for it in the recursive call. + +Fri Dec 18 10:24:14 1987 Richard Stallman (rms at frosted-flakes) + + * findvar.c (read_var_value): Share code between values really + in registers and values in saved registers. + Register short on a big-endian machine needs a VALUE_OFFSET. + + * findvar.c (locate_var_value): Offset the address of a + saved register variable that's shorter than the register. + +Thu Dec 17 08:26:31 1987 Richard Stallman (rms at lucky-charms) + + * valprint.c (type_print_base): Print nameless bit fields + to indicate gaps before bit fields. + + * source.c (select_source_symtab): Ignore .h files. + Also, if a function `main' exists, make the default listing line + the beginning of `main'. + + * breakpoint.c ({get,set}_breakpoint_commands): + Commands to examine or set the pending breakpoint-commands. + + * infcmd.c (run_stack_dummy): Save and restore the breakpoint + commands around the function call. + + * stack.c (return_command): Don't query or print if not interactive. + + * value.h (COERCE_ENUM): New macro: if arg is enum, convert to int. + * value.h (COERCE_ARRAY): Do that, as well as old job. + + * valarith.c (value_binop, value_neg, value_lognot): + Use COERCE_ENUM on the arguments. + * valops.c (value_arg_coerce): Likewise. + * valops.c (value_cast): AVOID coercing enums when arrays are. + + * eval.c (evaluate_subexp): In the BINOP_SUB case, + use evaluate_subexp_with_coercion. + + * inflow.c (terminal_ours_1, terminal_inferior): + Ignore inferior_thisrun_terminal since our terminal + is the inferior's controlling terminal regardless. + + * m-sun3.h: Fix assembler syntax for kdb macros. + + * infcmd.c ({attach,detach}_command): New functions from Dave Taylor. + * inflow.c (attach, detach): New functions from Dave Taylor. + * infrun.c (attach_process): New function, middle-level. + Does all the work of attaching a process, assuming there is no + inferior yet, except for printing and querying. + + * infrun.c (clear_proceed_status): Clear `stop_after_attach'. + * infrun.c (wait_for_inferior): Handle `stop_after_attach'. + +Sat Dec 12 04:36:39 1987 Richard Stallman (rms at corn-chex) + + * dbxread.c (end_symtab): The free_code for a symseg got + from a file should be free_linetable. + + * dbxread.c: Allocate blockvector, blocks, symbols and symbol names + from the symbol-obstack, and use free_linetable for all files. + The typevector is still malloc'd, so put it in the free_ptr + to get it freed. + + * symmisc.c (free_symtab): Always free the `free_ptr' if nonzero. + `free_explicit' therefore now the same as `free_nothing'. + + * dbxread.c (define_symbol): Handle defn code 'c', used by + fortran, which defines integer and real constant symbols. + + * symseg.h: Define LOC_CONST_BYTES for constants longer than a + word. New `bytes' alternative for the value of a symbol. + + * symtab.h (SYMBOL_VALUE_BYTES): Macro to access `bytes'. + + * findvar.c ({read,locate}_var_value): Handle LOC_CONST_BYTES. + * printcmd.c (address_info): Handle LOC_CONST_BYTES. + * symmisc.c (print_symbol): Handle LOC_CONST_BYTES. + +Tue Dec 8 20:26:37 1987 Richard Stallman (rms at frosted-flakes) + + * symtab.c (find_line_pc_range): Detection of last line in file + was erroneous. + +Fri Dec 4 21:52:52 1987 Richard Stallman (rms at frosted-flakes) + + * dbxread.c (read_range_type): Accept the typenums as argument. + Use read_type_number to read the subrange-of type. + A type defined as a subrange of itself is void. + +Thu Dec 3 12:45:10 1987 Richard Stallman (rms at frosted-flakes) + + * inflow.c ({fetch,store}_inferior_registers): Support UMAX_PTRACE. + + * m-umax.h: New file, for Encore machines. + + * core.c (exec_file_command, etc): Decode COFF files. + * core.c (core_file_command): Support UMAX_CORE format. + * core.c (validate_files, exec_file_command): + Set exec_mtime in exec_file_command so that COFF vs non-COFF + differences appear all in one place. + + * coffread.c: New file from Dave Johnson. + + * core.c (specify_exec_file_hook): New function to specify + a hook to be called by exec_file_command. Last #ifdef X_WINDOWS gone. + * xgdb.c (initialize): Specify a hook. + + * infrun.c, inferior.h: Replace stop_r0 and stop_r1 with an array + `stop_registers' that will hold ALL the registers. + * infcmd.c (run_stack_dummy): Get the value from `stop_registers' + and copy all of that into BUFFER. + * infcmd.c (finish_command): Specify `stop_registers' + to `value_being_returned'. + * values.c (value_being_returned): Use the new EXTRACT... macros. + * values.c (set_return_value): Use new STORE_RETURN_VALUE macro. + * valops.c (call_function): Allocate retbuf long enough for all regs. + * m-*.h: New macros EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE and + EXTRACT_STRUCT_VALUE_ADDRESS that express machine-dependencies + in where return values are stored. + + * valops.c (call_function): Flush default for CALL_DUMMY_START_OFFSET. + Assume it is defined. + * m-vax.h: Define CALL_DUMMY_START_OFFSET. + + * ns32k-pinsn.c (ns32k-localcount): Fix decoding of `enter' insn. + * ns32k-pinsn.c (n32k_get_enter_addr): New fn used from m-umax.h. + + * m-*.h: Change INVALID_FLOAT to accept 2nd arg which is length + of the float. + * values.c (unpack_double): Pass the 2nd arg. + * vax-pinsn.c (print_insn_arg): Pass the 2nd arg. + * infcmd.c (registers_info): Pass the 2nd arg. + +Wed Nov 25 15:06:55 1987 Richard Stallman (rms at frosted-flakes) + + * Bug fixes by David Johnson (ddj%cs.brown.edu@relay.cs.net). + + * symtab.c (list_symbols): Print typedef names, and don't call + them `static'. + + * symmisc.c (print_symtabs): Allow immediate quit, and close the + output file if that happens. + + * stack.c (frame_command): Declare args `unsigned' so a negative + number is a frame address, not a level number. + + * source.c: Check for error-return from calls to `getwd'. + + * printcmd.c (address_info): Fix error in case of a function name. + + * inflow.c (create_inferior): Return the inferior pid properly. + + * inferior.h: Define `inferior_io_terminal'. + * infrun.c (tty_command): New command to specify inferior_io_terminal. + * inflow.c (new_tty): Open specified terminal for the inferior. + * inflow.c (terminal_{ours,inferior}): Do nothing if inferior was + started with its own terminal. + * main.c (main): -t switch calls `tty_command'. + + * expread.y (rule for `block'): `copy_name' was called in wrong + place and with wrong args. + + * dbxread.c: Entire file #ifdef READ_DBX_FORMAT. + * m-*.h: Define READ_DBX_FORMAT. + + * breakpoint.c (initialize): Error in doc string of `info breakpoints'. + +Wed Nov 11 12:57:28 1987 Richard Stallman (rms at frosted-flakes) + + * ns32k-opcode.h, ns32k-pinsn.c: Two new files. + * m-merlin.h: New file, for one 32000 box. + +Mon Nov 9 10:31:42 1987 Brian Fox (bfox at sugar-smacks) + + * eval.c (evaluate_subexp): Made the case of OP_FUNCALL use + evaluate_subexp_with_coercion, so that array references would + get converted into pointer references. + +Mon Nov 9 05:50:24 1987 Richard Stallman (rms at sugar-smacks) + + * breakpoint.c (ignore_command): Error if no arg. + +Sat Nov 7 13:57:40 1987 Richard Stallman (rms at frosted-flakes) + + * main.c (quit_command): Get rid of execfile before the kill_inferior. + + * xgdb.c: New file, interface to X windows. + + * main.c (main): Look for flag arguments before + calling the initialization functions. -nw switch sets + `inhibit_windows' which xgdb.c looks at. + * main.c (command_loop): Call the window hook function, if any. + + * source.c (get_filename_and_charpos): New function + that interfaces to find_source_lines. + * source.c (source_line_charpos, source_charpos_line): + New functions translate source line number to char pos and vice versa. + + * breakpoint.c (describe_other_breakpoints): New subroutine + to list all breakpoints at PC in a message about "other + breakpoints". + * breakpoint.c (break_command_1): Use describe_other_breakpoints. + * breakpoint.c (set_breakpoint): Like break_command_1 + but takes arg predecoded into symtab and line. + + * core.c (exec_file_command): Call xgdb_display_exec_file. + + * valprint.c (type_print_base): For struct bitfields, + print the bit size. + +Thu Aug 20 02:46:47 1987 Richard M. Stallman (rms at prep) + + * Version 2.4. + + * m68k-pinsn.c (print_insn_arg): Implement place = '3'. + + * findvar.c (write_register_bytes): Arg to + store_inferior_registers should be -1: write all registers. + + * dbxread.c (symbol_file_command): If no arg, + just discard all symbols. + + * core.c (myread): Flush the 4th arg (filename). + * source.c (find_source_lines): Don't pass 4th arg. + * symmisc.c (read_symsegs): Ditto. + + * dbxread.c (process_one_symbol): One call to `define_symbol' + lacked 3rd arg. + + * inflow.c (write_inferior_memory): On failure, return the errno value. + * core.c (write_memory): ditto. + * breakpoint.c ({insert,remove}_breakpoints): ditto. + * utils.c (print_sys_errmsg): Like perror_with_name but don't + signal an error; also, the error code is an arg instead of from + `errno'. + * infrun.c : Save the value from insert_breakpoints and pass it to + print_sys_errmsg. + + * main.c (input_from_terminal_p): Put in omitted `return'. + + * Makefile (expread.o): Use $(CC). + +Sun Jun 7 04:42:51 1987 Richard M. Stallman (rms at prep) + + * version.c: Version 2.3. + + * inflow.c (terminal_ours): Save fcntl flags correctly. + * inflow.c (term_status_command): + Print the tchars and ltchars structures, byte by byte. + +Mon May 25 14:37:14 1987 Richard M. Stallman (rms at prep) + + * version.c: Version 2.2. + + * breakpoint.c (do_breakpoint_commands): + Advance breakpoint_commands before executing the command, + in case command is `cont' and it hits another bpt with commands. + +Sun May 24 20:45:04 1987 Richard M. Stallman (rms at prep) + + * value.h: Declare `contents' long and cast its address to char *. + + * expread.y (prefixify_expression): Don't call alloca among the decls. + + * printcmd.c (print_variable_value): Flush unused local `space'. + + * main.c (execute_command): Barf on "user" like other class names. + +Fri May 22 01:34:37 1987 Richard M. Stallman (rms at prep) + + * m68k-pinsn.c (fetch_arg): New arg position 'j', for movec. + (print_insn_arg): New arg syntax 'J', for movec. + * m68k-opcode.h: movec uses 'Jj'. Everything reformatted. + bf... and cas... insns were corrected. + + * inflow.c (create_inferior): Fork and exec with given args and env. + Call close_exec_file. + (inferior_died): Record the fact that the inferior no longer exists. + Call reopen_exec_file. + + * core.c (close_exec_file): New fn: Close the execchan if it's open. + (reopen_exec_file): New fn: Reopen execchan if not currently open. + + * infrun.c (wait_for_inferior): Call inferior_died if it exits. + + * infcmd.c (run_command): Don't fork and exec; call create_inferior. + + * findvar.c (read_var_value): For reg var in a convertable reg, + fetch reg in its own virtual type and then cast to variable's type. + + * symtab.h: Declare xmalloc to return char *. + + * dbxread.c (read_dbx_symtab): Record static text syms as + misc-functions. But if an assembler symbol supplies the address + for a debugger symbol, don't record it as a misc-function. + + * utils.c (query): Do clearerr (stdin) frequently in case of C-d. + + * dbxread.c (process_one_symbol, define_symbol): + Pass the stab's DESC down to define_symbol. + DESC = 0 means GCC output: if type is "short", believe it. + + * dbxread.c (read_enum_type): Don't allocate the type here; + take it as an argument. (Like read_struct_type.) + (read_type)): Before call to read_enum_type, allocate the type + or get the one already allocated. + + * printcmd.c (print_frame_args): Print a comma before + every arg except the first. + +Wed May 13 00:36:00 1987 Richard M. Stallman (rms at prep) + + * m68k-pinsn.c (convert_{to,from}_68881): + Hand-assemble the fmoved and fmovex insns. + + * dbxread.c (define_symbol): For case 'p', a parameter, + if specified type is short or char, change it to int. + This is for how PCC handles arguments. + Define new case 'P' that does what 'p' used to do. + Maybe GCC will use this. + +Mon May 4 21:52:44 1987 Richard M. Stallman (rms at prep) + + * main.c (main): If SET_STACK_LIMIT_HUGE, set the + run-time stack limit as high as it can go. + * m-sun3.h, m-vax.h: define SET_STACK_LIMIT_HUGE. + +Sun May 3 08:46:23 1987 Richard Mlynarik (mly at prep) + + * command.c, expread.y, findvar.c, infcmd.c, inflow.c, utils.c, + values.c, defs.h: Various ANSI C compatibility changes + (fouts@wilbur.arpa <8705010117.AA13112@wilbur.arpa>) + + * core.c, inflow.c: Fix calls to supply_register. + * findvar.c (supply_register): Instead of register value as int, + pass address of buffer in core containing contents in raw form. + +Sat Apr 18 17:09:42 1987 Richard Mlynarik (mly at prep) + + * main.c (command_loop): + Do any cleanups made by a executing a command each time around. + + * source.c (directory_command): + make_cleanup (free, dirname), not + make_cleanup (free_current_contents, &dirname) + (rlk <8704180416.AA29572@PARIS.MIT.EDU>) + +Mon Apr 13 20:28:26 1987 Leonard H. Tower Jr. (tower at prep) + + * gdb.1: fixed typo and italicization errors. + (<kgk%cs.brown.edu@RELAY.CS.NET> id AA16470;Sun,12 Apr 87 14:30:07 EST) + +Sat Apr 11 15:41:01 1987 Richard Mlynarik (mly at prep) + + * dbxread.c (read_dbx_symtab): + No name for symbol => "" not 0 (avoid referencing memory 0) + (tower <8704081854.AA00135@buit3.bu.edu>) + +Mon Mar 30 22:24:07 1987 Leonard H. Tower Jr. (tower at prep) + + * gdb.1: Unix style manual page pointing at internal gdb + documentation, and info sub-system in GNU Emacs. + +Fri Mar 20 12:07:15 1987 Richard M. Stallman (rms at prep) + + * COPYING: Clarifications about distribution fees and mixing. + * main.c (copying_info): Same changes. + +Tue Mar 17 17:40:14 1987 Richard M. Stallman (rms at prep) + + * values.c (unpack_field_as_long): Avoid >>= operator + since ISI compiler has a bug. + +Sat Mar 7 12:19:35 1987 Richard M. Stallman (rms at prep) + + * GDB version 2.1. + + * values.c (unpack-field-as-long): Tests for endianness were broken. + * findvar.c (read_var_value): + Now we initialize the union as an int and test it as a char. + +Sun Mar 1 16:16:20 1987 Richard M. Stallman (rms at prep) + + * main.c (define_command): Command class symbols + must be cast to int. + +Mon Feb 23 02:47:44 1987 Richard M. Stallman (rms at prep) + + * source.c (list_command): Reword error messages. + New message for case of first arg not just a line-number + and no symtab specified by it. + +Sun Feb 22 21:15:19 1987 Richard M. Stallman (rms at prep) + + * dbxread.c (compare_misc_functions): + Compare the addresses as unsigned numbers. + +Sun Feb 22 13:11:45 1987 Richard Mlynarik (mly at prep) + + * main.c (define_command, document_command): + Stuff was being unnecessarily malloced (-and- not freed!) + + * main.c (execute_command): + User-defined commands don't take args. + Don't confuse empty user command with no command. + Replace bogus `etext' test with a comparison against + class_user. + + * main.c (define_command): + If the command of the specified name is built-in, note that when + asking whether to redefine it (this is suppressed for class_alias + -- should it not be?) + + * main.c (define_command): + If command was previously built-in, don't preserve its + documentation (otherwise could get error later when trying to free + the non-malloced text of built-in documentation strings) + +Tue Feb 17 16:23:57 1987 Richard Mlynarik (mly at prep) + + * main.c (echo_command): Don't die if not given any arg. + * main.c (cd_command): Echo new cwd if interactive. + +Thu Feb 12 11:22:56 1987 Richard M. Stallman (rms at prep) + + * stack.c (initialize): "bt" now appears in help aliases. + + * Version 2.0 released. + +Wed Feb 11 17:45:45 1987 Richard M. Stallman (rms at prep) + + * m68k-opcode.h: Errors corrected in several instructions + and reordering done for assembler's sake. + + * m-vax.h (POP_FRAME): End with call to set_current_frame. + +Tue Feb 10 15:06:07 1987 Richard M. Stallman (rms at prep) + + * infrun.c (wait_for_inferior): Set stop_print_frame to 1 + after checking breakpoint condition. + + * infcmd.c (run_stack_dummy): Save many flags. + +Thu Feb 5 07:12:20 1987 Richard Mlynarik (mly at prep) + + * source.c (directory_command): + Step over `:' + +Mon Feb 2 23:40:32 1987 Richard M. Stallman (rms at prep) + + * infcmd.c (set_environment_command): Fix stupid error + for case where no "=" appears in the string. + +Mon Jan 26 13:46:52 1987 Richard M. Stallman (rms at prep) + + * printcmd.c (print_frame_args): Round end-of-arg offset + up rather than down to multiple of int. + +Fri Jan 23 15:11:50 1987 Richard M. Stallman (rms at prep) + + * source.c (directory_command): If dir is not added cause already + present, print explanation. + + * infrun.c (proceed): Use read_pc (), not stop_pc, + to get current pc to think about. stop_pc could have been + clobbered by call_function. + +Fri Jan 23 15:00:55 1987 Richard Mlynarik (mly at prep) + + * source.c (directory_command): + If dir is already in source_path, don't append another copy of it. + +Thu Jan 22 00:31:03 1987 Richard M. Stallman (rms at prep) + + * Version 2.0. + + * blockframe.c (get_pc_function_start): + Understand misc functions. + + * core.c (core_file_command): + Copy all register contents into the array `registers' + Save a.out header of executable file in core_aouthdr. + Print name of executable file that was running, if we know + where to find it. + + * core.c (exec_file_command): + Save a.out header in exec_aouthdr and file's mtime + in exec_mtime. + + * core.c (validate_files): Check that core file's a.out hdr + matches exec file's. + + * New handling of registers: + Now all registers are fetched once when the program stops or + when a core file is selected. Their contents are kept in + `registers', an array of bytes. This is done by + `fetch_inferior_registers'. `read_register', etc., just look + there. Writing a register works through + `store_inferior_registers' which writes one or all registers + from `registers' back to the inferior. + + A register now can have a "raw" data format and a "virtual" + data format, which may require conversion or even be different sizes. + The conversion can be different for different registers. + For example, the 68000 cpu registers need no conversion + and both raw and virtual size is 4, but the 68881 floating point + registers have raw size 12 (for extended fmt) and virtual size 8 + (for double). Macros in the m- file such as REGISTER_BYTES, + REGISTER_BYTE, REGISTER_{RAW,VIRTUAL}_SIZE, and + REGISTER_CONVERT_TO_{RAW,VIRTUAL} control these things. + + `read_register' and `write_register' are usable only on registers + which hold an int and need no conversion (raw fmt = virtual fmt). + For other registers, `read_register_bytes' is used, or + `read_relative_register_raw_bytes'. + + * m-sun3.h: Define the 68881 fp registers. + Know how to recognize insns that save them. + Make dummy frames save them. + + * core.c (read_register, write_registers): Functions deleted. + * findvar.c (read_register, write_registers): New functions, + not the same as the old ones of the same name. + + * findvar.c (supply_register): Function used by + fetch_inferior_registers, etc., to install the register + values fetched from the inferior. + + * findvar.c (read_register_bytes, write_register_bytes): + Read spec'd number of bytes from the byte-array `registers'. + + * findvar.c (read_relative_register_raw_bytes): + Replaces old function `read_relative_register'; accepts + address of where to store the contents; # bytes stored is size + of the specified register in raw format. + + * findvar.c (value_of_register, read_var_value): + Convert register values and values of register variables + from raw format to virtual format. + + * findvar.c (locate_var_value): Like `read_var_value' but + returns value for variable's address. + + * value.h: Add new field VALUE_REGNO to each value. It holds + register number to control virtual-to-raw conversion + for assignments to the value. + + * valops.c (value_assign): Convert data from virtual to raw format + if value came from a register variable. + Use read_register_bytes and write_register_bytes. + + + * infcmd.c (continue_command): Subtract 1 from arg + before setting breakpoint's ignore-count. + + * infcmd.c (jump_command): Query if spec'd line is outside + of the current function. + + * infcmd.c (finish_command): Now finish the selected frame, + and no arg required. + + * infcmd.c (set_environment_command): Allow space to separate + varname and value. + + * infcmd.c (registers_info): Print both raw and virtual data + format if they differ. Allow register name as arg. + Ask for a Newline each 16 registers. + + * inflow.c (kill_inferior): call mark_breakpoints_out. + * inflow.c ({fetch,store}_inferior_registers for Sun): + Get the fp registers and store them in right places in + `registers'. + * inflow.c ({read,write}_inferior_register): Deleted. + + * infrun.c (wait_for_inferior): Single-stepping is not considered + to have hit a breakpoint unless the pc before the step matches the + address of the breakpoint. Necessary on machines where + breakpoints leave the pc incremented. + + If shell gets SIGSEGV, pass the signal silently to it. + + * m68k-pinsn.c, m68k-opcode.h: + Add the 68881 instructions. New operand codes `F', `I', `s' + and `k' are needed for them. New place codes `78tcik'. + NEXTBYTE now skips a word but fetches just a byte. + Explicit sign-extension removed from NEXTBYTE and NEXTWORD. + NEXTSINGLE, NEXTDOUBLE, NEXTEXTEND and NEXTPACKED defined. + Various changes to implement the new operand and place codes. + print_index changed because displacement-size codes for + word and long displacement were interchanged. + + * m68k-pinsn.c (convert_{from,to}_68881): Functions added + to support REGISTER_CONVERT_TO_{RAW,VIRTUAL} on 68000. + + * main.c (main): Move around calls to setjmp. + * main.c (define_command, document_command): + Accept a from_tty argument instead of calling input_from_terminal_p. + + * printcmd.c (address_info): Print info on class and address + of a specified symbol. For register symbols, gives name of register. + + * printcmd.c (print_command): Remember explicitly whether + `make_cleanup' was called. + + * printcmd.c (print_frame_args): Know how arg-addresses vary with + data type on big-endian machines. + + * source.c (directory_command): Detect `:' in arg and reject it. + Free the old directory-path. Simplify things like `/.' in + dirname. + + * source.c (openp): Simplify `./' in specified name. + + * source.c (find_source_lines): Compare source mtime against + `exec_mtime' and warn if source is newer. + + * source.c (line_info): No arg means use last line listed + or line following last one this command was used on. + If from tty, clear out argument so Return is like `i li' without + arg. + + * stack.c (frame_info): Print addresses registers are saved at. + + * stack.c (return_command): When asking for confirmation, give + name of function that will be made to return. + + * valops.c (call_function): If function type is + pointer-to-function, dereference it to compute return type. + If pointer-to-object, assume function returns int. + If char, assume that the value's address is the function address + (because it's a misc functon). If int, the value itself is the + function address. + + * dbxread.c (compare_symbols): Sort register symbols + before all others. + + * eval.c (evaluate_subexp_for_address): New function like + `evaluate_subexp' but returns a value for the address where + the subexpression's value would be located. + + * eval.c (evaluate_subexp_for_sizeof): New function like + `evaluate_subexp' but returns a value for the size of the subexp. + + * eval.c (evaluate_subexp_with_coercion): Like `evaluate_subexp' + but coerces arrays to pointers (without taking the time to + read the array contents). + + * eval.c (evaluate_subexp): Use the three new functions above + when appropriate instead of calling self recursively. + +Wed Jan 14 17:00:03 1987 Richard Mlynarik (mly at prep) + + * core.c (core_file_command): + Use correct file in calls to perror_with_name + +Mon Jan 12 03:34:35 1987 Richard Mlynarik (mly at prep) + + * breakpoint.c (map_breakpoint_numbers): + Err if no args not supplied, otherwise would get mpv. + + * main.c (main): + Command-line arg "-d dir" adds dir to source-file directory + search-list. + +Sun Jan 11 19:19:52 1987 Richard Mlynarik (mly at prep) + + * symmisc.c (free_all_symtabs): + Don't call free on 0. + + * core.c (exec_file_command): + Use correct name in call to perror_with_name. + Record absolute pathname. + Don't savestring an arg to concat. + + * dbxread.c (symbol_file_command): + Record absolute name of pathname opened. + Print a message if file doesn't have a symbol-table. + Don't savestring an arg to concat. + + * source.c (openp): + Add new arg filename_opened, which if non-zero will be set to a + malloced string of the absolute name of the actual filename opened. + + * breakpoint.c (clear_command): + If from_tty or cleared more than one breakpoint at location, + print which bpts were deleted. + + * breakpoint.c (break_command_1, break_command, tbreak_command): + If from_tty, mention any other breakpoints set at same location. + + * symtab.c (decode_line_1): + If no symtabs, err mentioning `symbol-file' command rather than + saying "function foo not defined" + +Fri Jan 9 01:25:19 1987 Richard Mlynarik (mly at prep) + + * main.c (set_prompt_command): + Add support command "set-prompt" + + * printcmd.c (undisplay_command): + Fix paren error to make "undisplay <number>" work. + +Wed Jan 7 12:06:09 1987 Richard Mlynarik (mly at prep) + + * main.c (print_gdb_version, gdb_version_info): + Add command "info version" to report the version + of gdb for use in bug reports. + + * infcmd.c: + Ensure inferior_args always points to string starting with a space + and is never 0. + + * printcmd.c: (clear_displays, undisplay_command): + Fix bug in clear_displays which led to looping. + Make undisplay_command call it instead of wrong-looking code which + looked at (display->number == 0) instead of (display == 0) to + determine if it were at the end of the chain. + +Mon Dec 15 20:57:06 1986 Richard M. Stallman (rms at prep) + + * utils.c (query): Don't ignore a second line if given a null line. + + * infrun.c (normal_stop): Print "bug in shell" message + only for a segmentation fault. + + * main.c (main): Read init file from home directory if any, + before init file from current directory. + +Thu Dec 4 09:05:35 1986 Richard M. Stallman (rms at prep) + + * source.c (select_source_symtab): Don't ref thru arg if null. + + * m68k.opcode.h: For trap instruction code, use type T. + * m68k-pinsn.c (print_insn_arg): Recognize new arg-code T + and print the trap vector properly. + + * m-sun[23].h (FRAME_FIND_SAVED_REGS): Recognize a movl REG,-(sp) + as a way to save one register. Recognize clrw -(sp); movw -(sp) + after saving regs as a way to save the PS register. Adjust the + way to find the starting pc of a stack dummy frame for the fact + that these frames now save the PS. + + * m-sun[23].h (POP_FRAME): Restore PS register if frame saved it. + + * m-sun[23].h (PUSH_DUMMY_FRAME): Push the old PS register. + + * m-sun[23].h (CALL_DUMMY, etc.): Fix erroneous binary code for + the addl #nnn,sp instruction. Insert clrw -(sp); movw -(sp) + to indicate that the PS has been saved. + + * infrun.c (wait_for_inferior): If inferior exits, call + mark_breakpoints_out so it works to delete breakpoints afterward. + + * infrun.c (normal_stop): After popping a stack dummy frame, + select the frame that we get to. + + * dbxread.c (process_one_symbol): Store new `depth' field + in all context_stack elements created. For N_RBRAC, test + that depth matches that in the context_stack; if not, error. + + * dbxread.c (all callers of error): Make all error messages + start "Invalid symbol data: " and end with value of symnum. + Also change a few aborts to errors. + +Mon Dec 1 20:20:37 1986 Richard M. Stallman (rms at prep) + + * version.c: Version 1.11. + + * breakpoint.c (condition_command): If no condition spec'd, + print "breakpoint N now unconditional". + + * breakpoint.c (commands_command): Give different error messages + for cases of args not containing a breakpoint number + and args containing anything after the breakpoint number. + + * commands.c (lookup_command): Don't store a zero in *p + if have an undefined subcommand that is not an error. + + * commands.c (lookup_command): For recursive call, + pass subcommand list properly. Was passing the address + of the word containing the list. + + * core.c ({core,exec}_file_name): If no arg, tell user + what the effect is. + + * dbxread.c (define_symbol): Accept class code 'v' + for static variable within a function. + + * dbxread.c (read_type): Now allow any plain number or + pair of numbers in parens, with no code letter. This means + define new type same as type with specified number, or define + it as void if specified number's type is not yet mentioned. + + * m68k-pinsn.c (print_insn_arg): Case of general operand + in byte insn that happened to be immediate used wrong arg-size. + + * printcmd.c (set_next_address): Set next_address from arg + and also set value of `$_' from it. + + * printcmd.c (do_examine): Save address in last_examine_address + and value fetched to examine in last_examine_value. + + * printcmd.c (x_command): Copy last_examine_{address,value} + into values of `$_' and `$__'. Change `x' documentation string. + + * source.c (directory_command): Query when no args now says + what new value it wants use for the path. + + * source.c (list_command): Don't die in cases like `list ,+30'. + + * source.c (line_info): Call `set_next_address' to make `x' + display the text of the line. Change `info list' doc string. + +Sat Nov 29 07:59:29 1986 Richard M. Stallman (rms at prep) + + * printcmd.c (undisplay_command): If get no arg, + rather than crashing, query and then delete undisplay everything. + +Fri Nov 28 15:43:52 1986 Richard M. Stallman (rms at prep) + + * dbxread.c (process_one_symbol): If N_LBRAC sym + has a greater value that N_RBRAC, ignore the + N_LBRAC value and give the block zero length. + +Tue Nov 25 03:10:12 1986 Richard M. Stallman (rms at prep) + + * dbxread.c (process_one_symbol): Ignore N_NSYMS symbols + that appear in Ultrix. + +Sat Nov 22 22:49:06 1986 Richard M. Stallman (rms at prep) + + * version.c: version 1.10. + + * valprint.c (type_print*): + SHOW < 0 now means abbreviate struct/union members + or enum values with `...'. SHOW now decremented on + each recursion in type_print_base. Several places + that used to check !show now check show <= 0. + + * valprint.c (val_print): Pass -1 for SHOW to type_print + when printing typename inside parens or braces. + + * printcmd.c (print_command): If no value specified to print, + print the value of $. + + * expression.h, expread.y, eval.c, expprint.c: + OP_MEMVAL renamed UNOP_MEMVAL + and now allows any expression, not just an integer address. + It now has same format as UNOP_CAST and works almost like it. + Each place that referred to it has been rewritten + starting with a copy of the code that handles UNOP_CAST. + Doc for `print' command changed for this. + + * source.c (init_source_path): + Free and zero out any line_charpos's saved in source symtabs. + + * breakpoint.c (condition_command): + Parse the condition in the environment of the code where the + breakpoint is set. This requires finding the breakpoint + before parsing, so code is rearranged. + + * dbxread.c (dbx_alloc_type): + New function given typenums returns the type for those typenums + or allocates a new, empty type for those typenums and returns it. + + * symtab.c (smash_type_to_{pointer,function}): + New functions modify an already-allocated type object + to be a pointer to or function returning some given type. + + * dbxread.c (read_type): Uses dbx_alloc_type in many cases. + Reading a pointer or function type now works by doing that, + then reading the value type or type pointed to, then smashing + it into the type already allocated. This makes some fwd refs win. + Likewise for structs and unions. + + * dbxread.c (read_struct_type): Now receives the type object + as args. Used to get typenums as args and look up the type + itself. + + * dbxread.c (symbol_file_command): + At very end, clear out any type name that `char *' has received. + +Thu Nov 20 16:43:53 1986 Richard M. Stallman (rms at prep) + + * m-sun2.h, m-sun3.h (FIND_FRAME_SAVED_REGS): + Was incrementing address even for regs not saved. + +Sun Nov 16 14:59:07 1986 Richard M. Stallman (rms at prep) + + * values.c (value_field): Was adding in byte offset + before calling unpack_field_as_long, which itself + adds in the offset. Now pass addr of start of structure. + + * infrun.c (normal_stop): Clean up inferior_pid conditionals: + just return early if no inferior. + +Thu Nov 13 15:45:50 1986 Richard M. Stallman (rms at prep) + + * dbxread.c (struct header_file): add new field .instance + to distinguish the various entries for one header file. + + * dbxread.c (process_one_symbol): Use the `value' of + a N_BINCL or N_EXCL as the instance code for the header file. + + * dbxread.c (add_{new,old}_header_file): + Accept an instance code as arg and treat it as if it were + part of the file name for distinguishing and finding entries. + + * dbxread.c (add_new_header_file, read_type): + Turn off the header_file_prev_index feature with #if 0. + + * values.c (unpack_field_as_long, modify_field): + Run-time test to distinguish big and little endian machines + and do shifting accordingly. + +Tue Nov 11 00:31:18 1986 Richard M. Stallman (rms at prep) + + * version.c: version 1.9. + + * breakpoint.c (delete_command): + Don't query if 2nd arg is zero. + + * breakpoint.c (clear_breakpoints): + Pass 2nd arg of zero to delete_command. + +Sat Nov 8 23:29:19 1986 Richard M. Stallman (rms at prep) + + * breakpoint.c (delete_command): + Ask for confirmation when used with no arg (delete all). + +Fri Nov 7 11:23:09 1986 Richard M. Stallman (rms at prep) + + * infrun.c (start_inferior, wait_for_inferior): + Eliminate `stop_in_shell' which was not being maintained right. + New variable `running_in_shell' is set to 1 or 0 when the + expected SIGTRAPs happen, and is simply examined at other times. + + * infrun.c (wait_for_inferior): + If get SIGSEGV with running_in_shell == 1, it is sh + allocating memory. Pass the signal silently to the shell. + + * core.c (exec_file_command): + data_{start,end} are adjusted unconditionally when an + exec file is opened, so closing counter-adjustment is + now unconditional as well. + + * printcmd.c (x_command): + Don't erase the expression from the calling args + if cllaed noninteractively (used to be clobbering + definitions of user-defined commands). + + * source.c (list_command): likewise. + +Wed Nov 5 09:41:00 1986 Richard M. Stallman (rms at prep) + + * Makefile: New variable OBSTACK1 that people can use + to make obstack.o a dependency of gdb. + + * breakpoint.c (initialize): + Define new aliases "br", "bre" and "brea" for "break". + +Sun Nov 2 21:16:06 1986 Richard Mlynarik (mly at prep) + + * symmisc.c (read_symsegs): + Add an extra protection against invalid symbol-file + + * m-vax.h: + Set KERNEL_U_ADDR and STACK_END_ADDR non-4.2-specifically + +Tue Oct 21 13:34:14 1986 Richard Mlynarik (mly at prep) + + * breakpoints.c (initialize): + Delet reference to non-existent command "tenable" from doc of "enable" + +Tue Oct 14 19:58:27 1986 Richard Mlynarik (mly at prep) + + * printcmd.c (display_command, undisplay_command): + * infcmd.c (run_command): + Call dont_repeat. + + +Local Variables: +mode: indented-text +eval: (auto-fill-mode 1) +left-margin: 8 +fill-column: 74 +version-control: never +End: diff --git a/gdb/Makefile b/gdb/Makefile index 070ee70..fefd8da 100644 --- a/gdb/Makefile +++ b/gdb/Makefile @@ -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 diff --git a/gdb/ORIGIN b/gdb/ORIGIN new file mode 100644 index 0000000..f113819 --- /dev/null +++ b/gdb/ORIGIN @@ -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 diff --git a/gdb/ORIGIN.ls.lag b/gdb/ORIGIN.ls.lag new file mode 100644 index 0000000..e46be36 --- /dev/null +++ b/gdb/ORIGIN.ls.lag @@ -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 diff --git a/gdb/ORIGIN.ls.pmax b/gdb/ORIGIN.ls.pmax new file mode 100644 index 0000000..b9a552f --- /dev/null +++ b/gdb/ORIGIN.ls.pmax @@ -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 diff --git a/gdb/README b/gdb/README new file mode 100644 index 0000000..095136b --- /dev/null +++ b/gdb/README @@ -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. diff --git a/gdb/TAGS b/gdb/TAGS new file mode 100644 index 0000000..3c45dac --- /dev/null +++ b/gdb/TAGS @@ -0,0 +1,1191 @@ + +expread.y,349 +copy_name 952,21388 +end_arglist 516,11399 +free_funcalls 530,11701 +length_of_subexp 986,22292 +parse_c_1 1167,26460 +parse_c_expression 1208,27550 +parse_number 616,14066 +prefixify_expression 966,21724 +prefixify_subexp 1058,23629 +start_arglist 502,11040 +write_exp_elt 547,12040 +write_exp_string 564,12494 +yyerror 943,21233 +yylex 714,16109 + +command.h,0 + +defs.h,42 +#define max(24,1043 +#define min(23,1001 + +environ.h,0 + +expression.h,0 + +frame.h,0 + +inferior.h,0 + +initialize.h,0 + +m-hp9k320.h,1013 +#define ABOUT_TO_RETURN(105,3032 +#define EXTRACT_RETURN_VALUE(208,6644 +#define EXTRACT_STRUCT_VALUE_ADDRESS(221,7151 +#define FIX_CALL_DUMMY(446,16959 +#define FP_REGISTER_ADDR(230,7519 +#define FRAME_ARGS_ADDRESS(267,8872 +#define FRAME_CHAIN(256,8511 +#define FRAME_CHAIN_COMBINE(261,8700 +#define FRAME_CHAIN_VALID(258,8581 +#define FRAME_FIND_SAVED_REGS(303,10241 +#define FRAME_LOCALS_ADDRESS(269,8915 +#define FRAME_NUM_ARGS(276,9170 +#define FRAME_NUM_ARGS(279,9219 +#define FRAME_SAVED_PC(265,8804 +#define INIT_STACK(472,17773 +#define INIT_STACK(510,18982 +#define INVALID_FLOAT(109,3166 +#define REGISTER_ADDR(223,7216 +#define REGISTER_BYTE(150,4692 +#define REGISTER_CONVERTIBLE(178,5623 +#define REGISTER_CONVERT_TO_RAW(192,6086 +#define REGISTER_CONVERT_TO_VIRTUAL(183,5790 +#define REGISTER_RAW_SIZE(159,5027 +#define REGISTER_VIRTUAL_SIZE(165,5283 +#define REGISTER_VIRTUAL_TYPE(201,6367 +#define SAVED_PC_AFTER_CALL(73,2290 +#define SKIP_PROLOGUE(60,1854 +#define STORE_RETURN_VALUE(214,6848 + +m-isi-ov.h,1008 +#define ABOUT_TO_RETURN(140,5051 +#define EXTRACT_RETURN_VALUE(262,9368 +#define EXTRACT_STRUCT_VALUE_ADDRESS(275,9875 +#define FIX_CALL_DUMMY(479,18585 +#define FRAME_ARGS_ADDRESS(304,10929 +#define FRAME_CHAIN(293,10568 +#define FRAME_CHAIN_COMBINE(298,10757 +#define FRAME_CHAIN_VALID(295,10638 +#define FRAME_FIND_SAVED_REGS(334,12123 +#define FRAME_LOCALS_ADDRESS(306,10972 +#define FRAME_NUM_ARGS(311,11108 +#define FRAME_SAVED_PC(302,10861 +#define INIT_STACK(503,19381 +#define INVALID_FLOAT(144,5185 +#define N_DATADDR(124,4514 +#define N_TXTADDR(129,4693 +#define REGISTER_BYTE(204,7416 +#define REGISTER_CONVERTIBLE(232,8347 +#define REGISTER_CONVERT_TO_RAW(246,8810 +#define REGISTER_CONVERT_TO_VIRTUAL(237,8514 +#define REGISTER_RAW_SIZE(213,7751 +#define REGISTER_U_ADDR(183,6543 +#define REGISTER_VIRTUAL_SIZE(219,8007 +#define REGISTER_VIRTUAL_TYPE(255,9091 +#define SAVED_PC_AFTER_CALL(101,3958 +#define SKIP_PROLOGUE(81,3287 +#define STORE_RETURN_VALUE(268,9572 +#define vprintf(403,15501 + +m-isiinit.h,61 +#define FILEADDR_ROUND(8,252 +#define FILEADDR_ROUND(10,294 + +m-merlin.h,942 +#define ABOUT_TO_RETURN(86,2669 +#define EXTRACT_RETURN_VALUE(223,7393 +#define EXTRACT_STRUCT_VALUE_ADDRESS(236,7900 +#define FIX_CALL_DUMMY(378,12958 +#define FRAME_ARGS_ADDRESS(266,8999 +#define FRAME_CHAIN(254,8606 +#define FRAME_CHAIN_COMBINE(259,8795 +#define FRAME_CHAIN_VALID(256,8676 +#define FRAME_FIND_SAVED_REGS(308,10367 +#define FRAME_LOCALS_ADDRESS(268,9044 +#define FRAME_NUM_ARGS(273,9182 +#define FRAME_SAVED_PC(263,8899 +#define INIT_STACK(407,13935 +#define INVALID_FLOAT(90,2801 +#define REGISTER_BYTE(169,5699 +#define REGISTER_CONVERTIBLE(195,6521 +#define REGISTER_CONVERT_TO_RAW(206,6864 +#define REGISTER_CONVERT_TO_VIRTUAL(200,6655 +#define REGISTER_RAW_SIZE(176,5972 +#define REGISTER_U_ADDR(133,4302 +#define REGISTER_VIRTUAL_SIZE(182,6197 +#define REGISTER_VIRTUAL_TYPE(212,7060 +#define SAVED_PC_AFTER_CALL(58,2000 +#define SKIP_PROLOGUE(44,1503 +#define STORE_RETURN_VALUE(229,7597 +#define vprintf(327,11196 + +m-news800.h,823 +#define ABOUT_TO_RETURN(113,3361 +#define FIX_CALL_DUMMY(424,15770 +#define FRAME_ARGS_ADDRESS(252,8217 +#define FRAME_CHAIN(241,7856 +#define FRAME_CHAIN_COMBINE(246,8045 +#define FRAME_CHAIN_VALID(243,7926 +#define FRAME_FIND_SAVED_REGS(282,9411 +#define FRAME_LOCALS_ADDRESS(254,8260 +#define FRAME_NUM_ARGS(259,8396 +#define FRAME_SAVED_PC(250,8149 +#define INIT_STACK(449,16582 +#define INIT_STACK(454,16709 +#define INVALID_FLOAT(117,3495 +#define REGISTER_BYTE(171,5439 +#define REGISTER_CONVERTIBLE(199,6370 +#define REGISTER_CONVERT_TO_RAW(213,6833 +#define REGISTER_CONVERT_TO_VIRTUAL(204,6537 +#define REGISTER_RAW_SIZE(180,5774 +#define REGISTER_U_ADDR(151,4766 +#define REGISTER_VIRTUAL_SIZE(186,6030 +#define REGISTER_VIRTUAL_TYPE(222,7114 +#define SAVED_PC_AFTER_CALL(85,2672 +#define SKIP_PROLOGUE(71,2209 + +m-newsinit.h,29 +#define FILEADDR_ROUND(4,99 + +m-sun2.h,947 +#define ABOUT_TO_RETURN(83,2582 +#define EXTRACT_RETURN_VALUE(169,5390 +#define EXTRACT_STRUCT_VALUE_ADDRESS(182,5897 +#define FIX_CALL_DUMMY(367,13680 +#define FRAME_ARGS_ADDRESS(219,7266 +#define FRAME_CHAIN(208,6905 +#define FRAME_CHAIN_COMBINE(213,7094 +#define FRAME_CHAIN_VALID(210,6975 +#define FRAME_FIND_SAVED_REGS(255,8635 +#define FRAME_LOCALS_ADDRESS(221,7309 +#define FRAME_NUM_ARGS(228,7564 +#define FRAME_NUM_ARGS(231,7613 +#define FRAME_SAVED_PC(217,7198 +#define INIT_STACK(391,14476 +#define INVALID_FLOAT(87,2716 +#define REGISTER_BYTE(125,4079 +#define REGISTER_CONVERTIBLE(148,4697 +#define REGISTER_CONVERT_TO_RAW(158,5009 +#define REGISTER_CONVERT_TO_VIRTUAL(153,4831 +#define REGISTER_RAW_SIZE(130,4244 +#define REGISTER_U_ADDR(189,6193 +#define REGISTER_VIRTUAL_SIZE(135,4399 +#define REGISTER_VIRTUAL_TYPE(163,5174 +#define SAVED_PC_AFTER_CALL(55,1913 +#define SKIP_PROLOGUE(42,1477 +#define STORE_RETURN_VALUE(175,5594 + +m-sun2init.h,29 +#define FILEADDR_ROUND(5,94 + +m-sun3.h,913 +#define ABOUT_TO_RETURN(82,2531 +#define EXTRACT_RETURN_VALUE(185,6164 +#define EXTRACT_STRUCT_VALUE_ADDRESS(198,6671 +#define FIX_CALL_DUMMY(423,16227 +#define FRAME_ARGS_ADDRESS(244,8135 +#define FRAME_CHAIN(233,7774 +#define FRAME_CHAIN_COMBINE(238,7963 +#define FRAME_CHAIN_VALID(235,7844 +#define FRAME_FIND_SAVED_REGS(280,9504 +#define FRAME_LOCALS_ADDRESS(246,8178 +#define FRAME_NUM_ARGS(253,8433 +#define FRAME_NUM_ARGS(256,8482 +#define FRAME_SAVED_PC(242,8067 +#define INIT_STACK(447,17023 +#define INVALID_FLOAT(86,2665 +#define REGISTER_BYTE(127,4212 +#define REGISTER_CONVERTIBLE(155,5143 +#define REGISTER_CONVERT_TO_RAW(169,5606 +#define REGISTER_CONVERT_TO_VIRTUAL(160,5310 +#define REGISTER_RAW_SIZE(136,4547 +#define REGISTER_VIRTUAL_SIZE(142,4803 +#define REGISTER_VIRTUAL_TYPE(178,5887 +#define SAVED_PC_AFTER_CALL(59,2006 +#define SKIP_PROLOGUE(46,1570 +#define STORE_RETURN_VALUE(191,6368 + +m-suninit.h,29 +#define FILEADDR_ROUND(5,94 + +m-umax.h,913 +#define ABOUT_TO_RETURN(93,2734 +#define EXTRACT_RETURN_VALUE(235,7459 +#define EXTRACT_STRUCT_VALUE_ADDRESS(248,8098 +#define FIX_CALL_DUMMY(427,14369 +#define FRAME_ARGS_ADDRESS(279,9207 +#define FRAME_CHAIN(266,8812 +#define FRAME_CHAIN_COMBINE(271,9001 +#define FRAME_CHAIN_VALID(268,8882 +#define FRAME_FIND_SAVED_REGS(345,11372 +#define FRAME_LOCALS_ADDRESS(283,9332 +#define FRAME_NUM_ARGS(301,9969 +#define FRAME_SAVED_PC(275,9105 +#define INVALID_FLOAT(101,2907 +#define REGISTER_BYTE(179,5711 +#define REGISTER_CONVERTIBLE(205,6533 +#define REGISTER_CONVERT_TO_RAW(216,6876 +#define REGISTER_CONVERT_TO_VIRTUAL(210,6667 +#define REGISTER_RAW_SIZE(186,5984 +#define REGISTER_U_ADDR(143,4391 +#define REGISTER_VIRTUAL_SIZE(192,6209 +#define REGISTER_VIRTUAL_TYPE(222,7072 +#define SAVED_PC_AFTER_CALL(70,2211 +#define SKIP_PROLOGUE(56,1709 +#define STORE_RETURN_VALUE(241,7730 +#define vprintf(376,12597 + +m-umaxinit.h,30 +#define FILEADDR_ROUND(4,100 + +m-vax.h,940 +#define ABOUT_TO_RETURN(84,2628 +#define EXTRACT_RETURN_VALUE(178,5780 +#define EXTRACT_STRUCT_VALUE_ADDRESS(191,6287 +#define FIX_CALL_DUMMY(323,11747 +#define FRAME_ARGS_ADDRESS(226,7647 +#define FRAME_CHAIN(212,7106 +#define FRAME_CHAIN_COMBINE(217,7300 +#define FRAME_CHAIN_VALID(214,7181 +#define FRAME_FIND_SAVED_REGS(249,8503 +#define FRAME_LOCALS_ADDRESS(231,7822 +#define FRAME_NUM_ARGS(236,7958 +#define FRAME_SAVED_PC(221,7404 +#define INIT_STACK(346,12521 +#define INVALID_FLOAT(89,2816 +#define REGISTER_BYTE(132,4469 +#define REGISTER_CONVERTIBLE(155,5082 +#define REGISTER_CONVERT_TO_RAW(166,5397 +#define REGISTER_CONVERT_TO_VIRTUAL(160,5216 +#define REGISTER_RAW_SIZE(137,4631 +#define REGISTER_U_ADDR(117,3893 +#define REGISTER_VIRTUAL_SIZE(142,4784 +#define REGISTER_VIRTUAL_TYPE(172,5565 +#define SAVED_PC_AFTER_CALL(57,1954 +#define SKIP_PROLOGUE(46,1557 +#define STORE_RETURN_VALUE(184,5984 +#define vprintf(194,6403 + +m-vaxinit.h,29 +#define FILEADDR_ROUND(5,94 + +m68k-opcode.h,138 +#define one(130,5680 +int numopcodes=sizeof(1270,68164 +struct m68k_opcode *endop = m68k_opcodes+sizeof(1272,68226 +#define two(131,5707 + +ns32k-opcode.h,0 + +obstack.h,1054 +#define obstack_1grow(314,13600 +#define obstack_1grow(391,16272 +#define obstack_1grow_fast(277,12314 +#define obstack_alignment_mask(269,12044 +#define obstack_alloc(329,14107 +#define obstack_alloc(402,16645 +#define obstack_base(257,11715 +#define obstack_begin(274,12205 +#define obstack_blank(321,13836 +#define obstack_blank(396,16436 +#define obstack_blank_fast(279,12381 +#define obstack_chunk_size(261,11804 +#define obstack_copy(334,14262 +#define obstack_copy(405,16740 +#define obstack_copy0(339,14428 +#define obstack_copy0(408,16847 +#define obstack_finish(344,14596 +#define obstack_finish(411,16956 +#define obstack_free(356,15060 +#define obstack_free(423,17388 +#define obstack_free(430,17721 +#define obstack_grow(295,12915 +#define obstack_grow(376,15705 +#define obstack_grow0(304,13236 +#define obstack_grow0(383,15967 +#define obstack_init(271,12101 +#define obstack_next_free(265,11918 +#define obstack_object_size(287,12633 +#define obstack_object_size(370,15515 +#define obstack_room(291,12777 +#define obstack_room(373,15613 + +param.h,0 + +symseg.h,0 + +symtab.h,1364 +#define BLOCKLIST(110,3965 +#define BLOCKLIST_BLOCK(121,4342 +#define BLOCKLIST_NBLOCKS(120,4284 +#define BLOCKVECTOR(111,4013 +#define BLOCKVECTOR_BLOCK(123,4461 +#define BLOCKVECTOR_NBLOCKS(122,4401 +#define BLOCK_END(129,4675 +#define BLOCK_FUNCTION(132,4785 +#define BLOCK_NSYMS(130,4711 +#define BLOCK_SHOULD_SORT(136,4945 +#define BLOCK_START(128,4635 +#define BLOCK_SUPERBLOCK(133,4827 +#define BLOCK_SYM(131,4747 +#define LINELIST(115,4113 +#define LINETABLE(116,4158 +#define SYMBOL_BLOCK_VALUE(143,5245 +#define SYMBOL_CLASS(140,5092 +#define SYMBOL_NAME(138,4996 +#define SYMBOL_NAMESPACE(139,5039 +#define SYMBOL_TYPE(144,5302 +#define SYMBOL_VALUE(141,5137 +#define SYMBOL_VALUE_BYTES(142,5188 +#define TYPEVECTOR(113,4064 +#define TYPEVECTOR_NTYPES(125,4523 +#define TYPEVECTOR_TYPE(126,4578 +#define TYPE_CODE(158,5917 +#define TYPE_FIELD(162,6063 +#define TYPE_FIELDS(160,6013 +#define TYPE_FIELD_BITPOS(166,6322 +#define TYPE_FIELD_BITSIZE(167,6390 +#define TYPE_FIELD_NAME(164,6181 +#define TYPE_FIELD_PACKED(168,6460 +#define TYPE_FIELD_TYPE(163,6117 +#define TYPE_FIELD_VALUE(165,6245 +#define TYPE_FLAGS(156,5797 +#define TYPE_FUNCTION_TYPE(154,5685 +#define TYPE_LENGTH(155,5748 +#define TYPE_NAME(151,5520 +#define TYPE_NFIELDS(159,5962 +#define TYPE_POINTER_TYPE(153,5624 +#define TYPE_TARGET_TYPE(152,5565 +#define TYPE_UNSIGNED(157,5844 + +value.h,428 +#define COERCE_ARRAY(61,2062 +#define COERCE_ENUM(71,2403 +#define VALUE_ADDRESS(48,1560 +#define VALUE_BITPOS(52,1752 +#define VALUE_BITSIZE(51,1710 +#define VALUE_CONTENTS(46,1469 +#define VALUE_INTERNALVAR(49,1611 +#define VALUE_LVAL(47,1524 +#define VALUE_NEXT(53,1792 +#define VALUE_OFFSET(50,1670 +#define VALUE_REGNO(56,1922 +#define VALUE_REPEATED(54,1828 +#define VALUE_REPETITIONS(55,1872 +#define VALUE_TYPE(45,1433 + +vax-opcode.h,0 + +wait.h,381 +#define WCOREDUMP(13,439 +#define WCOREDUMP(22,735 +#define WIFEXITED(10,338 +#define WIFSIGNALED(9,274 +#define WIFSTOPPED(8,231 +#define WRETCODE(11,377 +#define WRETCODE(20,667 +#define WSETEXIT(15,511 +#define WSETEXIT(24,805 +#define WSETSTOP(16,556 +#define WSETSTOP(25,859 +#define WSTOPSIG(12,408 +#define WSTOPSIG(21,701 +#define WTERMSIG(14,478 +#define WTERMSIG(23,771 + +blockframe.c,436 +block_for_pc 221,5343 +block_innermost_frame 328,7854 +find_pc_function 276,6479 +find_pc_misc_function 290,6812 +get_current_block 182,4491 +get_current_frame 47,1559 +get_frame_block 172,4342 +get_frame_function 208,5059 +get_frame_info 90,2667 +get_frame_pc 150,3806 +get_frame_saved_regs 161,3992 +get_pc_function_start 188,4563 +get_prev_frame 66,1899 +get_prev_frame_info 128,3461 +initialize 349,8257 +set_current_frame 56,1711 + +breakpoint.c,1268 +#define ALL_BREAKPOINTS(71,2545 +break_command 685,16863 +break_command_1 628,15527 +breakpoint_1 394,10213 +breakpoint_auto_delete 768,18842 +breakpoint_cond_eval 326,8672 +breakpoint_here_p 310,8342 +breakpoint_stop_status 340,9123 +breakpoints_info 443,11295 +check_duplicates 508,12789 +clear_breakpoint_commands 223,6282 +clear_breakpoints 838,20224 +clear_command 701,17105 +clear_momentary_breakpoints 578,14320 +commands_command 156,4505 +condition_command 109,3533 +delete_breakpoint 785,19147 +delete_command 814,19667 +describe_other_breakpoints 462,11663 +disable_breakpoint 957,22641 +disable_command 966,22774 +do_breakpoint_commands 205,5722 +enable_breakpoint 941,22402 +enable_command 950,22533 +enable_delete_breakpoint 994,23259 +enable_delete_command 1003,23396 +enable_once_breakpoint 978,23003 +enable_once_command 987,23141 +get_breakpoint_commands 234,6567 +ignore_command 878,21116 +initialize 1017,23649 +insert_breakpoints 252,6958 +map_breakpoint_numbers 906,21721 +mark_breakpoints_out 297,8031 +remove_breakpoints 273,7497 +set_breakpoint 594,14672 +set_breakpoint_commands 240,6634 +set_default_breakpoint 491,12319 +set_ignore_count 848,20449 +set_momentary_breakpoint 566,14096 +set_raw_breakpoint 529,13309 +tbreak_command 693,16983 + +coffread.c,1050 +add_symbol_to_list 225,6438 +coff_alloc_type 202,5823 +coff_lookup_type 182,5228 +compare_misc_functions 529,14918 +compare_symbols 598,16344 +complete_symtab 413,11870 +condense_misc_bunches 555,15422 +decode_base_type 1563,39950 +decode_function_type 1548,39618 +decode_type 1479,37981 +discard_misc_bunches 542,15230 +end_symtab 429,12358 +enter_linenos 1212,30818 +finish_block 241,6832 +free_stringtab 1133,29359 +get_sym_file 759,20200 +getfilename 1161,29821 +getsymname 1141,29455 +hashname 1234,31433 +init_lineno 1188,30416 +init_misc_functions 501,14285 +init_stringtab 1103,28765 +initialize 1839,46671 +make_blockvector 320,8988 +patch_opaque_types 1282,32593 +patch_type 1255,31713 +process_coff_symbol 1343,34294 +read_aout_hdr 1039,27250 +read_coff_symtab 782,20785 +read_enum_type 1760,44558 +read_file_hdr 1020,26946 +read_one_sym 1073,27964 +read_section_hdr 1052,27503 +read_struct_type 1667,42201 +record_line 358,10096 +record_misc_function 509,14399 +sort_syms 610,16735 +start_symtab 391,11203 +symbol_file_command 634,17279 + +command.c,151 +add_alias_cmd 149,6542 +add_cmd 124,5994 +add_prefix_cmd 185,7605 +delete_cmd 206,8146 +help_cmd 238,8980 +lookup_cmd 344,12116 +savestring 454,14356 + +core.c,438 +#define N_DATADDR(61,1786 +#define N_TXTADDR(57,1716 +close_exec_file 457,12255 +core_file_command 152,3832 +exec_file_command 337,9034 +files_info 517,13575 +get_exec_file 501,13324 +have_core_file_p 511,13514 +initialize 736,18877 +myread 692,18121 +read_memory 560,14568 +register_addr 719,18606 +reopen_exec_file 464,12339 +specify_exec_file_hook 447,12026 +validate_files 480,12745 +write_memory 576,14975 +xfer_core_file 587,15240 + +dbxread.c,1312 +#define READ_FILE_HEADERS(85,2865 +#define READ_STRING_TABLE_SIZE(72,2434 +add_new_header_file 442,13085 +add_old_header_file 413,12067 +add_symbol_to_list 592,17369 +add_this_object_header_file 393,11440 +compare_misc_functions 1095,30835 +compare_symbols 1164,32278 +condense_misc_bunches 1121,31339 +dbx_alloc_type 550,16297 +dbx_lookup_type 500,14858 +define_symbol 1796,49277 +discard_misc_bunches 1108,31147 +end_symtab 919,26460 +explicit_lookup_type 571,16837 +fill_symbuf 1408,38674 +finish_block 657,18912 +free_header_files 369,10858 +get_sym_file 1384,38016 +hash_symsegs 1604,43801 +hashname 1577,43278 +init_header_files 356,10507 +init_misc_functions 1067,30229 +initialize 2474,68397 +make_blockvector 744,21323 +new_object_header_files 382,11168 +next_symbol_text 1424,39150 +obconcat 282,7896 +obsavestring 260,7389 +pop_subfile 1025,29388 +process_one_symbol 1635,44619 +push_subfile 1011,29037 +read_dbx_symtab 1439,39629 +read_enum_type 2264,62603 +read_number 2437,67832 +read_range_type 2345,64877 +read_struct_type 2177,60020 +read_type 2028,56226 +read_type_number 2001,55571 +really_free_pendings 621,18127 +record_line 783,22506 +record_misc_function 1075,30343 +sort_syms 1183,32828 +start_subfile 862,24702 +start_symtab 818,23480 +symbol_file_command 1208,33406 +xxmalloc 247,7121 + +environ.c,215 +environ_vector 172,6802 +free_environ 126,5799 +get_in_environ 181,6937 +init_environ 142,6126 +make_environ 111,5501 +#define max(104,5377 +#define min(103,5335 +set_in_environ 200,7272 +unset_in_environ 240,8026 + +eval.c,343 +evaluate_expression 113,3186 +evaluate_subexp 132,3574 +evaluate_subexp_for_address 461,13617 +evaluate_subexp_for_sizeof 530,15374 +evaluate_subexp_with_coercion 498,14564 +evaluate_type 124,3431 +initialize 571,16473 +parse_and_eval 64,1980 +parse_and_eval_address 33,1188 +parse_and_eval_address_1 50,1650 +parse_to_comma_and_eval 82,2437 + +expprint.c,49 +print_expression 88,3265 +print_subexp 102,3660 + +expread.tab.c,359 +copy_name 561,12554 +end_arglist 125,2565 +free_funcalls 139,2867 +length_of_subexp 595,13458 +parse_c_1 776,17626 +parse_c_expression 817,18716 +parse_number 225,5232 +prefixify_expression 575,12890 +prefixify_subexp 667,14795 +start_arglist 111,2206 +write_exp_elt 156,3206 +write_exp_string 173,3660 +yyerror 552,12399 +yylex 323,7275 +yyparse(1012,26510 + +findvar.c,309 +find_saved_register 38,1432 +initialize 410,10938 +locate_var_value 343,9217 +read_register 165,4621 +read_register_bytes 140,4050 +read_relative_register_raw_bytes 68,2095 +read_var_value 202,5600 +supply_register 190,5277 +value_of_register 102,2842 +write_register 175,4862 +write_register_bytes 151,4328 + +firstfile.c,89 +initialize_all_files 136,6474 +initialize_dummy_1 148,6803 +initialize_dummy_2 156,6962 + +infcmd.c,625 +attach_command 732,17281 +cont_command 193,4509 +detach_command 793,18554 +environment_info 512,12068 +finish_command 433,10153 +have_inferior_p 111,3062 +initialize 819,19055 +jump_command 297,6565 +next_command 230,5225 +nexti_command 244,5427 +program_info 490,11463 +read_memory_integer 575,13485 +read_pc 608,14081 +registers_info 622,14276 +run_command 136,3461 +run_stack_dummy 384,8700 +set_args_command 117,3127 +set_environment_command 532,12470 +signal_command 342,7530 +step_1 250,5504 +step_command 222,5073 +stepi_command 238,5350 +tty_command 126,3268 +unset_environment_command 564,13246 +write_pc 613,14145 + +inflow.c,863 +#define FP_REGISTER_ADDR_DIFF(525,12732 +#define INFERIOR_AR0(528,12842 +attach 439,10259 +create_inferior 337,8134 +detach 455,10564 +fetch_inferior_register 534,12998 +fetch_inferior_registers 469,10787 +fetch_inferior_registers 619,14955 +fetch_inferior_registers 665,16181 +inferior_died 405,9600 +initialize 859,21278 +kill_command 383,9216 +kill_inferior 394,9439 +new_tty 301,7373 +read_inferior_memory 746,18325 +resume 420,9929 +store_inferior_register 587,14202 +store_inferior_register_1 565,13702 +store_inferior_registers 497,11824 +store_inferior_registers 636,15505 +store_inferior_registers 696,16999 +term_status_command 261,6253 +terminal_inferior 140,3396 +terminal_init_inferior 115,2925 +terminal_ours 189,4596 +terminal_ours_1 198,4690 +terminal_ours_for_output 176,4359 +try_writing_regs_command 833,20768 +write_inferior_memory 779,19356 + +infrun.c,334 +attach_program 301,8446 +clear_proceed_status 130,3881 +handle_command 840,24097 +initialize 960,27506 +insert_step_breakpoint 818,23520 +normal_stop 726,20808 +proceed 158,4731 +remove_step_breakpoint 830,23822 +signals_info 922,26545 +start_inferior 243,6991 +start_remote 283,8086 +wait_for_inferior 324,9063 +writing_pc 231,6675 + +kdb-start.c,14 +start 10,140 + +lastfile.c,28 +initialize_last_file 4,144 + +m68k-pinsn.c,361 +#define NEXTBYTE(43,1554 +#define NEXTDOUBLE(54,1819 +#define NEXTEXTEND(57,1877 +#define NEXTLONG(48,1671 +#define NEXTPACKED(61,1995 +#define NEXTSINGLE(51,1762 +#define NEXTWORD(45,1602 +convert_from_68881 713,16403 +convert_to_68881 744,17120 +fetch_arg 504,12093 +print_base 693,15901 +print_indexed 603,13882 +print_insn 71,2389 +print_insn_arg 163,4738 + +main.c,898 +add_com 576,14145 +add_com_alias 588,14372 +add_info 544,13435 +add_info_alias 555,13621 +catch_errors 107,2877 +cd_command 1004,27712 +command_loop 358,9348 +copying_info 717,17065 +define_command 634,15182 +do_nothing 351,9248 +document_command 672,16144 +dont_repeat 398,10258 +dump_me_command 1122,29783 +echo_command 1096,29399 +error_no_arg 598,14570 +execute_command 316,8410 +free_command_lines 526,13126 +help_command 605,14664 +info_command 567,13949 +initialize_main 1132,29938 +input_from_terminal_p 983,27266 +main 129,3255 +print_gdb_version 898,25598 +print_prompt 918,26096 +pwd_command 989,27337 +quit_command 965,26902 +read_command_lines 475,11852 +read_line 409,10517 +return_to_top_level 90,2414 +set_prompt_command 927,26237 +source_cleanup 1065,28927 +source_command 1073,29029 +stop_sig 381,9897 +validate_comname 613,14815 +version_info 908,25948 +warranty_info 868,24187 + +ns32k-pinsn.c,239 +bit_extract 44,1387 +dbit_extract 84,1931 +fbit_extract 72,1766 +flip_bytes 104,2319 +get_displacement 374,8548 +ns32k_get_enter_addr 437,10241 +ns32k_localcount 408,9359 +print_insn 125,2670 +print_insn_arg 203,4273 +sign_extend 96,2170 + +obstack.c,333 +POINTER 235,9170 +POINTER 241,9271 +POINTER 303,10462 +POINTER 309,10567 +POINTER 316,10703 +POINTER 324,10877 +_obstack_begin 129,6001 +_obstack_free 199,8125 +_obstack_newchunk 160,6918 +int 247,9382 +int 253,9493 +obstack_free 196,8096 +void 259,9590 +void 267,9754 +void 275,9920 +void 282,10055 +void 289,10181 +void 296,10326 + +pinsn.c,0 + +printcmd.c,734 +address_info 454,10758 +clear_displays 736,17066 +decode_format 79,2326 +delete_current_display 870,19696 +delete_display 751,17277 +display_command 677,16025 +display_info 882,19974 +do_displays 858,19446 +do_examine 299,7212 +do_one_display 817,18479 +free_display 724,16848 +initialize 1169,26896 +output_command 415,9952 +print_address 276,6680 +print_command 375,9121 +print_formatted 124,3359 +print_frame_args 923,21059 +print_frame_nameless_args 986,22819 +print_scalar_formatted 167,4519 +print_variable_value 908,20615 +printf_command 1004,23196 +ptype_command 596,14000 +set_command 443,10508 +set_next_address 261,6316 +undisplay_command 781,17829 +validate_format 360,8682 +whatis_command 571,13527 +x_command 523,12221 + +remote.c,549 +dcache_alloc 548,11397 +dcache_fetch 565,11765 +dcache_flush 496,10383 +dcache_hit 513,10675 +dcache_init 606,12650 +dcache_poke 582,12129 +dcache_value 534,11060 +fromhex 142,3412 +getpkt 439,9223 +static initialize 619,12989 +putpkt 391,8356 +readchar 428,9019 +remote_fetch_registers 201,4442 +remote_fetch_word 253,5426 +remote_open 113,2896 +remote_read_bytes 322,6929 +remote_resume 168,3801 +remote_send 376,8094 +remote_store_registers 227,4964 +remote_store_word 274,5810 +remote_wait 184,4062 +remote_write_bytes 288,6178 +tohex 156,3656 + +source.c,445 +directories_info 91,2575 +directory_command 115,3092 +find_source_lines 283,7000 +forward_search_command 647,16430 +get_filename_and_charpos 362,8935 +identify_source_line 394,9804 +init_source_path 97,2666 +initialize 794,19866 +line_info 600,15220 +list_command 473,11569 +openp 219,5527 +print_source_lines 413,10296 +reverse_search_command 717,18054 +select_source_symtab 57,1795 +source_charpos_line 336,8295 +source_line_charpos 322,7999 + +stack.c,534 +args_info 363,9216 +backtrace_command 244,6624 +down_command 522,13553 +find_relative_frame 415,10615 +frame_command 468,12228 +frame_info 161,4481 +get_selected_block 395,9911 +initialize 582,14958 +locals_info 325,8515 +print_block_frame_locals 269,7164 +print_frame_arg_vars 331,8597 +print_frame_info 75,2329 +print_frame_local_vars 304,7997 +print_sel_frame 143,4033 +print_selected_frame 152,4238 +print_stack_frame 62,2126 +record_selected_frame 383,9619 +return_command 540,14053 +select_frame 372,9416 +up_command 501,12961 + +standalone.c,1165 +_exit 437,8550 +_flsbuf 326,6852 +access 76,1743 +chdir 62,1588 +close 164,4224 +core_file_command 340,7028 +exec_file_command 337,7003 +execle 434,8536 +exit 81,1771 +fault 515,9980 +fclose 189,4597 +fdopen 183,4539 +fflush 331,6910 +fgetc 247,5466 +fopen 175,4414 +fprintf 298,6263 +fputc 314,6593 +fread 229,5154 +fstat 195,4647 +fwrite 305,6422 +get_exec_file 344,7060 +getpid 54,1543 +getrlimit 475,9022 +getwd 66,1608 +have_core_file_p 351,7193 +initialize 586,11703 +ioctl 45,1478 +kill 51,1531 +kill_command 356,7230 +lseek 266,5714 +malloc_warning 442,8592 +myread 208,4831 +open 129,3606 +printf 291,6110 +ptrace 428,8507 +read_inferior_register 373,7378 +read_memory 376,7408 +read_register 398,7781 +restore_gdb 529,10299 +resume 491,9446 +save_frame_pointer 503,9650 +save_registers 541,10644 +sbrk 452,8708 +setpgrp 431,8521 +int (* signal 48,1506 +sigsetmask 59,1570 +int kdb_stack_beg[STACK_SIZE / sizeof 582,11630 +terminal_inferior 361,7271 +terminal_init_inferior 367,7317 +terminal_ours 364,7296 +ulimit 464,8930 +vfork 418,8217 +vlimit 470,8972 +wait 555,10992 +write_inferior_register 370,7347 +write_memory 386,7581 +write_register 407,7950 + +stuff.c,70 +err 162,5253 +find_symbol 141,4686 +get_offset 97,3038 +main 32,1184 + +symmisc.c,532 +#define CORE_RELOCATE(156,4674 +#define RELOCATE(146,4235 +#define TEXT_RELOCATE(160,4829 +#define UNRELOCATE(150,4430 +block_depth 546,15195 +free_all_symtabs 38,1310 +free_symtab 92,2701 +free_symtab_block 70,1994 +initialize 555,15336 +print_symbol 449,12827 +print_symtabs 383,11097 +read_symsegs 347,10121 +relocate_block 227,6794 +relocate_blockvector 215,6485 +relocate_source 324,9379 +relocate_sourcevector 312,9108 +relocate_symbol 252,7454 +relocate_symtab 181,5623 +relocate_type 293,8716 +relocate_typevector 273,8107 + +symtab.c,830 +block_function 411,11587 +compare_symbols 1095,28490 +decode_line_1 746,20110 +decode_line_spec 909,24191 +find_line_common 656,17799 +find_line_pc 591,16045 +find_line_pc_range 613,16574 +find_pc_line 453,12634 +find_pc_line_pc_range 707,18691 +find_pc_symtab 423,11820 +functions_info 1079,28240 +init_type 1118,29098 +initialize 1138,29548 +list_symbols 988,25907 +lookup_block_symbol 330,9558 +lookup_enum 166,4764 +lookup_function_type 211,6266 +lookup_misc_func 926,24619 +lookup_pointer_type 182,5275 +lookup_struct 134,3830 +lookup_symbol 285,8464 +lookup_symtab 58,1935 +lookup_typename 85,2565 +lookup_union 150,4299 +lookup_unsigned_typename 116,3352 +smash_to_function_type 262,7822 +smash_to_pointer_type 241,7212 +sort_block_syms 1107,28881 +sources_info 938,24850 +types_info 1086,28328 +variables_info 1072,28152 + +test2.c,11 +main 6,86 + +test3.c,25 +bar 12,123 +newfun 5,51 + +testbit.c,11 +main 7,58 + +testbpt.c,48 +after_dump 31,584 +int dump 15,351 +main 8,233 + +testfun.c,55 +do_add 12,86 +do_float_add 18,128 +foo 7,51 +main 1,0 + +testkill.c,11 + main(2,1 + +testrec.c,20 +foo 6,24 +main 1,0 + +testreg.c,22 +foo 19,341 +main 1,0 + +testregs.c,23 +foo 4,47 +main 17,357 + +testxx.c,20 +a(10,77 +main(3,20 + +utils.c,382 +concat 267,6227 +discard_cleanups 89,2568 +do_cleanups 73,2189 +error 226,5353 +fatal 241,5712 +free_current_contents 109,2978 +make_cleanup 53,1721 +parse_escape 336,8051 +perror_with_name 147,3761 +print_spaces 279,6469 +print_sys_errmsg 173,4320 +printchar 403,9096 +query 293,6833 +quit 196,4760 +request_quit 214,5114 +savestring 256,6060 +xmalloc 120,3191 +xrealloc 132,3411 + +valarith.c,215 +initialize 361,8346 +value_add 31,1128 +value_binop 116,3276 +value_equal 260,5580 +value_less 304,6791 +value_lognot 349,8075 +value_neg 331,7664 +value_sub 70,2102 +value_subscript 105,2971 +value_zerop 236,5229 + +valops.c,396 +call_function 394,10974 +initialize 597,16408 +push_bytes 316,9287 +push_word 296,8921 +value_addr 249,7552 +value_arg_coerce 356,10080 +value_arg_push 379,10527 +value_assign 88,2873 +value_at 71,2465 +value_cast 34,1302 +value_coerce_array 221,6762 +value_ind 276,8307 +value_of_variable 211,6556 +value_push 335,9628 +value_repeat 188,5971 +value_string 488,13694 +value_struct_elt 558,15616 + +valprint.c,256 +initialize 634,15818 +is_nan 312,7921 +set_maximum_command 626,15672 +type_print 341,8823 +type_print_1 352,9049 +type_print_base 474,12317 +type_print_varspec_prefix 385,10075 +type_print_varspec_suffix 420,10858 +val_print 115,3427 +value_print 47,1622 + +values.c,762 +access_value_history 212,5551 +allocate_repeat_value 83,2505 +allocate_value 59,1948 +clear_internalvars 371,9242 +clear_value_history 251,6511 +convenience_info 386,9478 +free_all_values 108,3143 +history_info 270,6920 +initialize 741,18461 +internalvar_name 361,9051 +lookup_internalvar 308,7855 +modify_field 608,14951 +record_latest_value 178,4634 +release_value 125,3410 +set_internalvar 351,8882 +set_internalvar_component 336,8488 +set_return_value 715,17910 +unpack_double 486,11857 +unpack_field_as_long 584,14377 +unpack_long 430,10621 +value_as_double 418,10258 +value_as_long 411,10138 +value_being_returned 694,17332 +value_copy 151,3834 +value_field 548,13336 +value_from_double 660,16290 +value_from_long 632,15530 +value_of_internalvar 327,8301 + +vax-pinsn.c,44 +print_insn 42,1456 +print_insn_arg 86,2396 + +version.c,0 + +xgdb.c,690 +addbutton 447,11022 +breakpoint_button 308,8599 +breakpoint_button_1 285,8127 +cont_button 385,10023 +create_buttons 461,11342 +create_label 486,12096 +create_text_widget 501,12496 +deiconify_button 402,10249 +down_button 430,10785 +explicit_breakpoint_button 334,9027 +finish_button 393,10131 +garbage 321,8760 +iconify_button 409,10382 +initialize 688,17526 +next_button 369,9807 +print_1 242,7251 +print_button 269,7835 +print_star_button 275,7884 +refresh_button 438,10893 +step_button 377,9915 +until_button 314,8664 +up_button 422,10681 +xgdb_create_window 523,13113 +xgdb_dispatch 646,16620 +xgdb_display_exec_file 224,6748 +xgdb_display_source 102,2745 +xgdb_window_hook 678,17364 diff --git a/gdb/blockframe.c b/gdb/blockframe.c index b337900..4acac1e 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -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) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index fc2155a..635cc49 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -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); - - b = set_raw_breakpoint (sal); - b->number = ++breakpoint_count; - b->cond = cond; - if (tempflag) - b->enable = temporary; + if (from_tty) + describe_other_breakpoints (sal.pc); - 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); + 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"); } 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; - } + 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; - } + 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 == 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'); + 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; } - free (sals.sals); + 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."); diff --git a/gdb/coffread.c b/gdb/coffread.c index 50005fd..16edc00 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -2,7 +2,7 @@ Design and support routines derived from dbxread.c, and UMAX COFF specific routines written 9/1/87 by David D. Johnson, Brown University. Revised 11/27/87 ddj@cs.brown.edu - Copyright (C) 1987 Free Software Foundation, Inc. + Copyright (C) 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 @@ -51,6 +51,8 @@ static char *getsymname (); static int init_lineno (); static void enter_linenos (); +extern void free_all_symtabs (); + START_FILE /* Name of source file whose symbol data we are now processing. @@ -252,7 +254,8 @@ finish_block (symbol, listhead, old_blocks, start, end) for (next = *listhead, i = 0; next; next = next->next, i++); - block = (struct block *) xmalloc (sizeof (struct block) + (i - 1) * sizeof (struct symbol *)); + block = (struct block *) + obstack_alloc (symbol_obstack, sizeof (struct block) + (i - 1) * sizeof (struct symbol *)); /* Copy the symbols into the block. */ @@ -324,7 +327,8 @@ make_blockvector () for (next = pending_blocks, i = 0; next; next = next->next, i++); - blockvector = (struct blockvector *) xmalloc (sizeof (struct blockvector) + (i - 1) * sizeof (struct block *)); + blockvector = (struct blockvector *) + obstack_alloc (symbol_obstack, sizeof (struct blockvector) + (i - 1) * sizeof (struct block *)); /* Copy the blocks into the blockvector. This is done in reverse order, which happens to put @@ -419,1415 +423,4 @@ complete_symtab (name, start_addr, size) /* Finish the symbol definitions for one main source file, close off all the lexical contexts for that file (creating struct block's for them), then make the - struct symtab for that file and put it in the list of all such. */ - -static void -end_symtab () -{ - register struct symtab *symtab; - register struct context_stack *cstk; - register struct blockvector *blockvector; - register struct linetable *lv; - - /* Finish the lexical context of the last function in the file. */ - - if (context_stack) - { - cstk = context_stack; - /* Make a block for the local symbols within. */ - finish_block (cstk->name, &local_symbols, cstk->old_blocks, - cstk->start_addr, cur_src_end_addr); - free (cstk); - } - - finish_block (0, &file_symbols, 0, cur_src_start_addr, cur_src_end_addr); - finish_block (0, &global_symbols, 0, cur_src_start_addr, cur_src_end_addr); - blockvector = make_blockvector (); - - /* Now create the symtab objects proper this source file. */ - - symtab = (struct symtab *) xmalloc (sizeof (struct symtab)); - /* Fill in its components. */ - symtab->blockvector = blockvector; - symtab->free_code = free_contents; - symtab->free_ptr = 0; - symtab->filename = last_source_file; - lv = line_vector; - lv->nitems = line_vector_index; - symtab->linetable = (struct linetable *) - xrealloc (lv, sizeof (struct linetable) + lv->nitems * sizeof (int)); - symtab->nlines = 0; - symtab->line_charpos = 0; - - /* Link the new symtab into the list of such. */ - symtab->next = symtab_list; - symtab_list = symtab; - - line_vector = 0; - line_vector_length = -1; - last_source_file = 0; -} - -/* Accumulate the misc functions in bunches of 127. - At the end, copy them all into one newly allocated structure. */ - -#define MISC_BUNCH_SIZE 127 - -struct misc_bunch -{ - struct misc_bunch *next; - struct misc_function contents[MISC_BUNCH_SIZE]; -}; - -/* Bunch currently being filled up. - The next field points to chain of filled bunches. */ - -static struct misc_bunch *misc_bunch; - -/* Number of slots filled in current bunch. */ - -static int misc_bunch_index; - -/* Total number of misc functions recorded so far. */ - -static int misc_count; - -static void -init_misc_functions () -{ - misc_count = 0; - misc_bunch = 0; - misc_bunch_index = MISC_BUNCH_SIZE; -} - -static void -record_misc_function (name, address) - char *name; - CORE_ADDR address; -{ - register struct misc_bunch *new; - - if (misc_bunch_index == MISC_BUNCH_SIZE) - { - new = (struct misc_bunch *) xmalloc (sizeof (struct misc_bunch)); - misc_bunch_index = 0; - new->next = misc_bunch; - misc_bunch = new; - } - misc_bunch->contents[misc_bunch_index].name = savestring (name, strlen (name)); - misc_bunch->contents[misc_bunch_index].address = address; - misc_bunch_index++; - misc_count++; -} - -static int -compare_misc_functions (fn1, fn2) - struct misc_function *fn1, *fn2; -{ - /* Return a signed result based on unsigned comparisons - so that we sort into unsigned numeric order. */ - if (fn1->address < fn2->address) - return -1; - if (fn1->address > fn2->address) - return 1; - return 0; -} - -static void -discard_misc_bunches () -{ - register struct misc_bunch *next; - - while (misc_bunch) - { - next = misc_bunch->next; - free (misc_bunch); - misc_bunch = next; - } -} - -static void -condense_misc_bunches () -{ - register int i, j; - register struct misc_bunch *bunch; -#ifdef NAMES_HAVE_UNDERSCORE - int offset = 1; -#else - int offset = 0; -#endif - - misc_function_vector - = (struct misc_function *) - xmalloc (misc_count * sizeof (struct misc_function)); - - j = 0; - bunch = misc_bunch; - while (bunch) - { - for (i = 0; i < misc_bunch_index; i++) - { - register char *tmp; - - misc_function_vector[j] = bunch->contents[i]; - tmp = misc_function_vector[j].name; - misc_function_vector[j].name = (tmp[0] == '_' ? tmp + offset : tmp); - j++; - } - bunch = bunch->next; - misc_bunch_index = MISC_BUNCH_SIZE; - } - - misc_function_count = j; - - /* Sort the misc functions by address. */ - - qsort (misc_function_vector, j, sizeof (struct misc_function), - compare_misc_functions); -} - -/* Call sort_syms to sort alphabetically - the symbols of each block of each symtab. */ - -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 -sort_syms () -{ - register struct symtab *s; - register int i, nbl; - register struct blockvector *bv; - register struct block *b; - - for (s = symtab_list; s; s = s->next) - { - bv = BLOCKVECTOR (s); - nbl = BLOCKVECTOR_NBLOCKS (bv); - for (i = 0; i < nbl; i++) - { - b = BLOCKVECTOR_BLOCK (bv, i); - qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b), - sizeof (struct symbol *), compare_symbols); - } - } -} - -/* This is the symbol-file command. Read the file, analyze its symbols, - and add a struct symtab to symtab_list. */ - -void -symbol_file_command (name) - char *name; -{ - int desc; - int num_symbols; - int num_sections; - int symtab_offset; - extern void close (); - register int val; - struct cleanup *old_chain; - - dont_repeat (); - - if (name == 0) - { - if (symtab_list && !query ("Discard symbol table? ", 0)) - error ("Not confirmed."); - free_all_symtabs (); - return; - } - - if (symtab_list && !query ("Load new symbol table from \"%s\"? ", name)) - error ("Not confirmed."); - - if (symfile) - free (symfile); - symfile = 0; - - { - char *absolute_name; - - desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name); - if (desc < 0) - perror_with_name (name); - else - name = absolute_name; - } - - old_chain = make_cleanup (close, desc); - make_cleanup (free_current_contents, &name); - - if ((num_symbols = read_file_hdr (desc, &file_hdr)) < 0) - error ("File \"%s\" not in executable format.", name); - - if (num_symbols == 0) - { - free_all_symtabs (); - printf ("%s does not have a symbol-table.\n", name); - fflush (stdout); - return; - } - - num_sections = file_hdr.f_nscns; - symtab_offset = file_hdr.f_symptr; - - if (read_section_hdr (desc, _TEXT, &text_hdr, num_sections) < 0) - error ("\"%s\": can't read text section header", name); - - /* Read the line number table, all at once. */ - - val = init_lineno (desc, text_hdr.s_lnnoptr, text_hdr.s_nlnno); - if (val < 0) - error ("\"%s\": error reading line numbers\n", name); - - /* Now read the string table, all at once. */ - - val = init_stringtab (desc, symtab_offset + num_symbols * SYMESZ); - if (val < 0) - error ("\"%s\": can't get string table", name); - make_cleanup (free_stringtab, 0); - - /* Position to read the symbol table. Do not read it all at once. */ - val = lseek (desc, (long)symtab_offset, 0); - if (val < 0) - perror_with_name (name); - - printf ("Reading symbol data from %s...", name); - fflush (stdout); - - /* Throw away the old symbol table. */ - - free_all_symtabs (); - - init_misc_functions (); - make_cleanup (discard_misc_bunches, 0); - - /* Now that the executable file is positioned at symbol table, - process it and define symbols accordingly. */ - - read_coff_symtab (desc, num_symbols); - - patch_opaque_types (); - - /* Sort symbols alphabetically within each block. */ - - sort_syms (); - - /* Go over the misc functions and install them in vector. */ - - condense_misc_bunches (); - - /* Don't allow char * to have a typename (else would get caddr_t.) */ - - TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0; - - /* Make a default for file to list. */ - - select_source_symtab (symtab_list); - - symfile = savestring (name, strlen (name)); - - do_cleanups (old_chain); - - printf ("done.\n"); - fflush (stdout); -} - -/* Return name of file symbols were loaded from, or 0 if none.. */ - -char * -get_sym_file () -{ - return symfile; -} - -/* Simplified internal version of coff symbol table information */ - -struct coff_symbol { - char *c_name; - int c_symnum; /* symbol number of this entry */ - int c_nsyms; /* 1 if syment only, 2 if syment + auxent */ - long c_value; - int c_sclass; - int c_secnum; - unsigned int c_type; -}; - -/* Given pointers to a symbol table in coff style exec file, - analyze them and create struct symtab's describing the symbols. - NSYMS is the number of symbols in the symbol table. - We read them one at a time using read_one_sym (). */ - -static void -read_coff_symtab (desc, nsyms) - int desc; - int nsyms; -{ - FILE *stream = fdopen (desc, "r"); - register struct context_stack *new; - struct coff_symbol coff_symbol; - register struct coff_symbol *cs = &coff_symbol; - static SYMENT main_sym; - static AUXENT main_aux; - - int num_object_files = 0; - int next_file_symnum; - char *filestring; - int depth; - int fcn_first_line; - int fcn_last_line; - long fcn_line_ptr; - - nlist_stream_global = stream; - nlist_nsyms_global = nsyms; - last_source_file = 0; - bzero (opaque_type_chain, sizeof opaque_type_chain); - - type_vector_length = 160; - type_vector = (struct typevector *) - xmalloc (sizeof (struct typevector) - + type_vector_length * sizeof (struct type *)); - bzero (type_vector->type, type_vector_length * sizeof (struct type *)); - - start_symtab (); - - symnum = 0; - while (symnum < nsyms) - { - read_one_sym (cs, &main_sym, &main_aux); - - if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE) - { - CORE_ADDR last_file_end = cur_src_end_addr; - - if (last_source_file) - end_symtab (); - - start_symtab (); - complete_symtab ("_globals_", 0, first_object_file_end); - /* done with all files, everything from here on out is globals */ - } - - /* Special case for file with type declarations only, no text. */ - if (!last_source_file && cs->c_type != T_NULL && cs->c_secnum == N_DEBUG) - complete_symtab (filestring, 0, 0); - - if (ISFCN (cs->c_type)) - { - /* - * gdb expects all functions to also be in misc_function - * list -- why not... - */ - record_misc_function (cs->c_name, cs->c_value); - - fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr; - within_function = 1; - - new = (struct context_stack *) - xmalloc (sizeof (struct context_stack)); - new->depth = depth = 0; - new->next = 0; - context_stack = new; - new->locals = 0; - new->old_blocks = pending_blocks; - new->start_addr = cs->c_value; - new->name = process_coff_symbol (cs, &main_aux); - continue; - } - - switch (cs->c_sclass) - { - case C_EFCN: - case C_EXTDEF: - case C_ULABEL: - case C_USTATIC: - case C_LINE: - case C_ALIAS: - case C_HIDDEN: - printf ("Bad n_sclass = %d\n", cs->c_sclass); - break; - - case C_FILE: - /* - * c_value field contains symnum of next .file entry in table - * or symnum of first global after last .file. - */ - next_file_symnum = cs->c_value; - filestring = getfilename (&main_aux); - /* - * Complete symbol table for last object file - * containing debugging information. - */ - if (last_source_file) - { - end_symtab (); - start_symtab (); - } - num_object_files++; - break; - - case C_EXT: - if (cs->c_secnum == N_ABS && strcmp (cs->c_name, _ETEXT) == 0) - { - end_of_text_addr = cs->c_value; - } - if (cs->c_type == T_NULL) - { - if (cs->c_secnum <= 1) /* text or abs */ - { - record_misc_function (cs->c_name, cs->c_value); - break; - } - else - cs->c_type = T_INT; - } - (void) process_coff_symbol (cs, &main_aux); - break; - - case C_STAT: - if (cs->c_type == T_NULL && cs->c_secnum > N_UNDEF) - { - if (strcmp (cs->c_name, _TEXT) == 0) - { - if (num_object_files == 1) - { - /* Record end address of first file, crt0.s */ - first_object_file_end = - cs->c_value + main_aux.x_scn.x_scnlen; - } - /* - * Fill in missing information for debugged - * object file only if we have line number info. - */ - if (main_aux.x_scn.x_nlinno > 0) - { - complete_symtab (filestring, cs->c_value, - main_aux.x_scn.x_scnlen); - } - break; - } - else if (strcmp (cs->c_name, _DATA) == 0) - break; - else if (strcmp (cs->c_name, _BSS) == 0) - break; - - /* get rid of assembly labels here */ - /* record_misc_function (cs->c_name, cs->c_value); */ - break; - } - (void) process_coff_symbol (cs, &main_aux); - break; - - case C_FCN: - if (strcmp (cs->c_name, ".bf") == 0) - { - /* value contains address of first non-init type code */ - /* main_aux.x_sym.x_misc.x_lnsz.x_lnno - contains line number of '{' } */ - fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; - } - else if (strcmp (cs->c_name, ".ef") == 0) - { - /* value contains address of exit/return from function */ - /* round it up to next multiple of 16 */ - cs->c_value = (cs->c_value + 15) & -16; - /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno - contains number of lines to '}' */ - fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; - enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line); - - new = context_stack; - finish_block (new->name, &local_symbols, new->old_blocks, - new->start_addr, cs->c_value); - context_stack = 0; - within_function = 0; - free (new); - } - break; - - case C_BLOCK: - if (strcmp (cs->c_name, ".bb") == 0) - { - new = (struct context_stack *) - xmalloc (sizeof (struct context_stack)); - depth++; - new->depth = depth; - new->next = context_stack; - context_stack = new; - new->locals = local_symbols; - new->old_blocks = pending_blocks; - new->start_addr = cs->c_value; - new->name = 0; - local_symbols = 0; - } - else if (strcmp (cs->c_name, ".eb") == 0) - { - new = context_stack; - if (new == 0 || depth != new->depth) - error ("Invalid symbol data: .bb/.eb symbol mismatch."); - if (local_symbols && context_stack->next) - { - /* Make a block for the local symbols within. */ - finish_block (0, &local_symbols, new->old_blocks, - new->start_addr, cs->c_value); - } - depth--; - local_symbols = new->locals; - context_stack = new->next; - free (new); - } - break; - - default: - (void) process_coff_symbol (cs, &main_aux); - break; - } - } - - if (last_source_file) - end_symtab (); - fclose (stream); -} - -/* Routines for reading headers and symbols from executable. */ - -/* Read COFF file header, check magic number, - and return number of symbols. */ -read_file_hdr (chan, file_hdr) - int chan; - FILHDR *file_hdr; -{ - lseek (chan, 0L, 0); - if (myread (chan, (char *)file_hdr, FILHSZ) < 0) - return -1; - - switch (file_hdr->f_magic) - { - case NS32GMAGIC: - case NS32SMAGIC: - return file_hdr->f_nsyms; - - default: - return -1; - } -} - -read_aout_hdr (chan, aout_hdr, size) - int chan; - AOUTHDR *aout_hdr; - int size; -{ - lseek (chan, (long)FILHSZ, 0); - if (size != sizeof (AOUTHDR)) - return -1; - if (myread (chan, (char *)aout_hdr, size) != size) - return -1; - return 0; -} - -read_section_hdr (chan, section_name, section_hdr, nsects) - register int chan; - register char *section_name; - SCNHDR *section_hdr; - register int nsects; -{ - register int i; - - if (lseek (chan, FILHSZ + sizeof (AOUTHDR), 0) < 0) - return -1; - - for (i = 0; i < nsects; i++) - { - if (myread (chan, (char *)section_hdr, SCNHSZ) < 0) - return -1; - if (strncmp (section_hdr->s_name, section_name, 8) == 0) - return 0; - } - return -1; -} - -read_one_sym (cs, sym, aux) - register struct coff_symbol *cs; - register SYMENT *sym; - register AUXENT *aux; -{ - cs->c_symnum = symnum; - fread ((char *)sym, SYMESZ, 1, nlist_stream_global); - cs->c_nsyms = (sym->n_numaux & 0xff) + 1; - if (cs->c_nsyms == 2) - { - /* doc for coff says there is either no aux entry or just one */ - fread ((char *)aux, AUXESZ, 1, nlist_stream_global); - } - else if (cs->c_nsyms > 2) - error ("more than one aux symbol table entry at symnum=%d\n", symnum); - - cs->c_name = getsymname (sym); - cs->c_value = sym->n_value; - cs->c_sclass = (sym->n_sclass & 0xff); - cs->c_secnum = sym->n_scnum; - cs->c_type = (unsigned) sym->n_type; - - symnum += cs->c_nsyms; -} - -/* Support for string table handling */ - -static char *stringtab = NULL; - -static int -init_stringtab (chan, offset) - int chan; - long offset; -{ - long buffer; - int val; - - if (lseek (chan, offset, 0) < 0) - return -1; - - val = myread (chan, (char *)&buffer, sizeof buffer); - if (val != sizeof buffer) - return -1; - - if (stringtab) - free (stringtab); - stringtab = (char *) xmalloc (buffer); - bcopy (&buffer, stringtab, sizeof buffer); - - val = myread (chan, stringtab + sizeof buffer, buffer - sizeof buffer); - if (val != buffer - sizeof buffer || stringtab[buffer - 1] != '\0') - return -1; - - return 0; -} - -static void -free_stringtab () -{ - if (stringtab) - free (stringtab); - stringtab = NULL; -} - -static char * -getsymname (symbol_entry) - SYMENT *symbol_entry; -{ - static char buffer[SYMNMLEN+1]; - char *result; - - if (symbol_entry->n_zeroes == 0) - { - result = stringtab + symbol_entry->n_offset; - } - else - { - strncpy (buffer, symbol_entry->n_name, SYMNMLEN); - buffer[SYMNMLEN] = '\0'; - result = buffer; - } - return result; -} - -static char * -getfilename (aux_entry) - AUXENT *aux_entry; -{ - static char buffer[BUFSIZ]; - register char *temp; - char *result; - extern char *rindex (); - - if (aux_entry->x_file.x_foff != 0) - strcpy (buffer, stringtab + aux_entry->x_file.x_foff); - else - { - strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN); - buffer[FILNMLEN] = '\0'; - } - result = buffer; - if ((temp = rindex (result, '/')) != NULL) - result = temp + 1; - return (result); -} - -/* Support for line number handling */ -static char *linetab = NULL; -static long linetab_offset; -static int linetab_count; - -static int -init_lineno (chan, offset, count) - int chan; - long offset; - int count; -{ - int val; - - if (lseek (chan, offset, 0) < 0) - return -1; - - if (linetab) - free (linetab); - linetab = (char *) xmalloc (count * LINESZ); - - val = myread (chan, linetab, count * LINESZ); - if (val != count * LINESZ) - return -1; - - linetab_offset = offset; - linetab_count = count; - return 0; -} - -static void -enter_linenos (file_offset, first_line, last_line) - long file_offset; - register int first_line; - register int last_line; -{ - register char *rawptr = &linetab[file_offset - linetab_offset]; - register struct lineno *lptr; - - /* skip first line entry for each function */ - rawptr += LINESZ; - /* line numbers start at one for the first line of the function */ - first_line--; - - for (lptr = (struct lineno *)rawptr; - lptr->l_lnno && lptr->l_lnno <= last_line; - rawptr += LINESZ, lptr = (struct lineno *)rawptr) - { - record_line (first_line + lptr->l_lnno, lptr->l_addr.l_paddr); - } -} - -static int -hashname (name) - char *name; -{ - register char *p = name; - register int total = p[0]; - register int c; - - c = p[1]; - total += c << 2; - if (c) - { - c = p[2]; - total += c << 4; - if (c) - total += p[3] << 6; - } - - return total % HASHSIZE; -} - -static void -patch_type (type, real_type) - struct type *type; - struct type *real_type; -{ - register struct type *target = TYPE_TARGET_TYPE (type); - register struct type *real_target = TYPE_TARGET_TYPE (real_type); - int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field); - - TYPE_LENGTH (target) = TYPE_LENGTH (real_target); - TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target); - TYPE_FIELDS (target) = (struct field *) - obstack_alloc (symbol_obstack, field_size); - - bcopy (TYPE_FIELDS (real_target), TYPE_FIELDS (target), field_size); - - if (TYPE_NAME (real_target)) - { - if (TYPE_NAME (target)) - free (TYPE_NAME (target)); - TYPE_NAME (target) = concat (TYPE_NAME (real_target), "", ""); - } -} - -/* Patch up all appropriate typdef symbols in the opaque_type_chains - so that they can be used to print out opaque data structures properly */ - -static void -patch_opaque_types () -{ - struct symtab *s; - - /* Look at each symbol in the per-file block of each symtab. */ - for (s = symtab_list; s; s = s->next) - { - register struct block *b; - register int i; - - /* Go through the per-file symbols only */ - b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1); - for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--) - { - register struct symbol *real_sym; - - /* Find completed typedefs to use to fix opaque ones. - Remove syms from the chain when their types are stored, - but search the whole chain, as there may be several syms - from different files with the same name. */ - real_sym = BLOCK_SYM (b, i); - if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF && - SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE && - TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR && - TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0) - { - register char *name = SYMBOL_NAME (real_sym); - register int hash = hashname (name); - register struct symbol *sym, *prev; - - prev = 0; - for (sym = opaque_type_chain[hash]; sym;) - { - if (name[0] == SYMBOL_NAME (sym)[0] && - !strcmp (name + 1, SYMBOL_NAME (sym) + 1)) - { - if (prev) - SYMBOL_VALUE (prev) = SYMBOL_VALUE (sym); - else - opaque_type_chain[hash] - = (struct symbol *) SYMBOL_VALUE (sym); - - patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym)); - - if (prev) - sym = (struct symbol *) SYMBOL_VALUE (prev); - else - sym = opaque_type_chain[hash]; - } - else - { - prev = sym; - sym = (struct symbol *) SYMBOL_VALUE (sym); - } - } - } - } - } -} - -static struct symbol * -process_coff_symbol (cs, aux) - register struct coff_symbol *cs; - register AUXENT *aux; -{ - register struct symbol *sym = (struct symbol *) - xmalloc (sizeof (struct symbol)); - char *name; - char *dot; -#ifdef NAMES_HAVE_UNDERSCORE - int offset = 1; -#else - int offset = 0; -#endif - - bzero (sym, sizeof (struct symbol)); - name = cs->c_name; - name = (name[0] == '_' ? name + offset : name); - SYMBOL_NAME (sym) = savestring (name, strlen (name)); - - /* default assumptions */ - SYMBOL_VALUE (sym) = cs->c_value; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - - if (ISFCN (cs->c_type)) - { - SYMBOL_TYPE (sym) = decode_function_type (cs, cs->c_type, aux); - SYMBOL_CLASS (sym) = LOC_BLOCK; - if (cs->c_sclass == C_STAT) - add_symbol_to_list (sym, &file_symbols); - else if (cs->c_sclass == C_EXT) - add_symbol_to_list (sym, &global_symbols); - } - else - { - SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux); - switch (cs->c_sclass) - { - case C_NULL: - break; - - case C_AUTO: - SYMBOL_CLASS (sym) = LOC_LOCAL; - add_symbol_to_list (sym, &local_symbols); - break; - - case C_EXT: - SYMBOL_CLASS (sym) = LOC_STATIC; - add_symbol_to_list (sym, &global_symbols); - break; - - case C_STAT: - SYMBOL_CLASS (sym) = LOC_STATIC; - if (within_function) { - /* Static symbol of local scope */ - add_symbol_to_list (sym, &local_symbols); - } - else { - /* Static symbol at top level of file */ - add_symbol_to_list (sym, &file_symbols); - } - break; - - case C_REG: - case C_REGPARM: - SYMBOL_CLASS (sym) = LOC_REGISTER; - add_symbol_to_list (sym, &local_symbols); - break; - - case C_LABEL: - break; - - case C_ARG: - SYMBOL_CLASS (sym) = LOC_ARG; - add_symbol_to_list (sym, &local_symbols); - /* If PCC says a parameter is a short or a char, - it is really an int. */ - if (SYMBOL_TYPE (sym) == builtin_type_char - || SYMBOL_TYPE (sym) == builtin_type_short) - SYMBOL_TYPE (sym) = builtin_type_int; - else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char - || SYMBOL_TYPE (sym) == builtin_type_unsigned_short) - SYMBOL_TYPE (sym) = builtin_type_unsigned_int; - break; - - case C_TPDEF: - SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - - /* If type has no name, give it one */ - if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0 - && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0) - TYPE_NAME (SYMBOL_TYPE (sym)) - = concat (SYMBOL_NAME (sym), "", ""); - - /* Keep track of any type which points to empty structured type, - so it can be filled from a definition from another file */ - if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR && - TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0) - { - register int i = hashname (SYMBOL_NAME (sym)); - - SYMBOL_VALUE (sym) = (int) opaque_type_chain[i]; - opaque_type_chain[i] = sym; - } - add_symbol_to_list (sym, &file_symbols); - break; - - case C_STRTAG: - case C_UNTAG: - case C_ENTAG: - SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; - if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0 - && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0) - TYPE_NAME (SYMBOL_TYPE (sym)) - = concat ("", - (cs->c_sclass == C_ENTAG - ? "enum " - : (cs->c_sclass == C_STRTAG - ? "struct " : "union ")), - SYMBOL_NAME (sym)); - add_symbol_to_list (sym, &file_symbols); - break; - - default: - break; - } - } - return sym; -} - -/* Decode a coff type specifier; - return the type that is meant. */ - -static -struct type * -decode_type (cs, c_type, aux) - register struct coff_symbol *cs; - unsigned int c_type; - register AUXENT *aux; -{ - register struct type *type = 0; - register int n; - unsigned int new_c_type; - - if (c_type & ~N_BTMASK) - { - new_c_type = DECREF (c_type); - if (ISPTR (c_type)) - { - type = decode_type (cs, new_c_type, aux); - type = lookup_pointer_type (type); - } - else if (ISFCN (c_type)) - { - type = decode_type (cs, new_c_type, aux); - type = lookup_function_type (type); - } - else if (ISARY (c_type)) - { - int i, n; - register unsigned short *dim; - struct type *base_type; - - /* Define an array type. */ - /* auxent refers to array, not base type */ - if (aux->x_sym.x_tagndx == 0) - cs->c_nsyms = 1; - - /* shift the indices down */ - dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0]; - i = 1; - n = dim[0]; - for (i = 0; *dim && i < DIMNUM - 1; i++, dim++) - *dim = *(dim + 1); - *dim = 0; - - type = (struct type *) - obstack_alloc (symbol_obstack, sizeof (struct type)); - bzero (type, sizeof (struct type)); - - base_type = decode_type (cs, new_c_type, aux); - - TYPE_CODE (type) = TYPE_CODE_ARRAY; - TYPE_TARGET_TYPE (type) = base_type; - TYPE_LENGTH (type) = n * TYPE_LENGTH (base_type); - } - return type; - } - - /* Reference to existing type */ - if (cs->c_nsyms > 1 && aux->x_sym.x_tagndx != 0) - { - type = coff_alloc_type (aux->x_sym.x_tagndx); - return type; - } - - return decode_base_type (cs, BTYPE (c_type), aux); -} - -/* Decode a coff type specifier for function definition; - return the type that the function returns. */ - -static -struct type * -decode_function_type (cs, c_type, aux) - register struct coff_symbol *cs; - unsigned int c_type; - register AUXENT *aux; -{ - if (aux->x_sym.x_tagndx == 0) - cs->c_nsyms = 1; /* auxent refers to function, not base type */ - - return decode_type (cs, DECREF (cs->c_type), aux); -} - -/* basic C types */ - -static -struct type * -decode_base_type (cs, c_type, aux) - register struct coff_symbol *cs; - unsigned int c_type; - register AUXENT *aux; -{ - struct type *type; - - switch (c_type) - { - case T_NULL: - /* shouldn't show up here */ - break; - - case T_ARG: - /* shouldn't show up here */ - break; - - case T_CHAR: - return builtin_type_char; - - case T_SHORT: - return builtin_type_short; - - case T_INT: - return builtin_type_int; - - case T_LONG: - return builtin_type_long; - - case T_FLOAT: - return builtin_type_float; - - case T_DOUBLE: - return builtin_type_double; - - case T_STRUCT: - if (cs->c_nsyms != 2) - { - /* anonymous structure type */ - type = coff_alloc_type (cs->c_symnum); - TYPE_CODE (type) = TYPE_CODE_STRUCT; - TYPE_NAME (type) = concat ("struct ", "<opaque>", ""); - TYPE_LENGTH (type) = 0; - TYPE_FIELDS (type) = 0; - TYPE_NFIELDS (type) = 0; - } - else - { - type = read_struct_type (cs->c_symnum, - aux->x_sym.x_misc.x_lnsz.x_size, - aux->x_sym.x_fcnary.x_fcn.x_endndx); - } - return type; - - case T_UNION: - if (cs->c_nsyms != 2) - { - /* anonymous union type */ - type = coff_alloc_type (cs->c_symnum); - TYPE_NAME (type) = concat ("union ", "<opaque>", ""); - TYPE_LENGTH (type) = 0; - TYPE_FIELDS (type) = 0; - TYPE_NFIELDS (type) = 0; - } - else - { - type = read_struct_type (cs->c_symnum, - aux->x_sym.x_misc.x_lnsz.x_size, - aux->x_sym.x_fcnary.x_fcn.x_endndx); - } - TYPE_CODE (type) = TYPE_CODE_UNION; - return type; - - case T_ENUM: - return read_enum_type (cs->c_symnum, - aux->x_sym.x_misc.x_lnsz.x_size, - aux->x_sym.x_fcnary.x_fcn.x_endndx); - - case T_MOE: - /* shouldn't show up here */ - break; - - case T_UCHAR: - return builtin_type_unsigned_char; - - case T_USHORT: - return builtin_type_unsigned_short; - - case T_UINT: - return builtin_type_unsigned_int; - - case T_ULONG: - return builtin_type_unsigned_long; - } - printf ("unexpected type %d at symnum %d\n", c_type, cs->c_symnum); - return builtin_type_void; -} - -/* This page contains subroutines of read_type. */ - -/* Read the description of a structure (or union type) - and return an object describing the type. */ - -static struct type * -read_struct_type (index, length, lastsym) - int index; - int length; - int lastsym; -{ - struct nextfield - { - struct nextfield *next; - struct field field; - }; - - register struct type *type; - register struct nextfield *list = 0; - struct nextfield *new; - int nfields = 0; - register int n; - char *name; -#ifdef NAMES_HAVE_UNDERSCORE - int offset = 1; -#else - int offset = 0; -#endif - struct coff_symbol member_sym; - register struct coff_symbol *ms = &member_sym; - SYMENT sub_sym; - AUXENT sub_aux; - - type = coff_alloc_type (index); - TYPE_CODE (type) = TYPE_CODE_STRUCT; - TYPE_LENGTH (type) = length; - - while (symnum < lastsym && symnum < nlist_nsyms_global) - { - read_one_sym (ms, &sub_sym, &sub_aux); - name = ms->c_name; - name = (name[0] == '_' ? name + offset : name); - - switch (ms->c_sclass) - { - case C_MOS: - case C_MOU: - - /* Get space to record the next field's data. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - /* Save the data. */ - list->field.name = savestring (name, strlen (name)); - list->field.type = decode_type (ms, ms->c_type, &sub_aux); - list->field.bitpos = 8 * ms->c_value; - list->field.bitsize = 0; - nfields++; - break; - - case C_FIELD: - - /* Get space to record the next field's data. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - /* Save the data. */ - list->field.name = savestring (name, strlen (name)); - list->field.type = decode_type (ms, ms->c_type, &sub_aux); - list->field.bitpos = ms->c_value; - list->field.bitsize = sub_aux.x_sym.x_misc.x_lnsz.x_size; - nfields++; - break; - - case C_EOS: - break; - } - } - /* Now create the vector of fields, and record how big it is. */ - - TYPE_NFIELDS (type) = nfields; - TYPE_FIELDS (type) = (struct field *) - obstack_alloc (symbol_obstack, sizeof (struct field) * nfields); - - /* Copy the saved-up fields into the field vector. */ - - for (n = nfields; list; list = list->next) - TYPE_FIELD (type, --n) = list->field; - - return type; -} - -/* Read a definition of an enumeration type, - and create and return a suitable type object. - Also defines the symbols that represent the values of the type. */ - -static struct type * -read_enum_type (index, length, lastsym) - int index; - int length; - int lastsym; -{ - register struct symbol *sym; - register struct type *type; - int nsyms = 0; - struct pending **symlist; - struct coff_symbol member_sym; - register struct coff_symbol *ms = &member_sym; - SYMENT sub_sym; - AUXENT sub_aux; - struct pending *osyms, *syms; - register int n; - char *name; -#ifdef NAMES_HAVE_UNDERSCORE - int offset = 1; -#else - int offset = 0; -#endif - - type = coff_alloc_type (index); - if (within_function) - symlist = &local_symbols; - else - symlist = &file_symbols; - osyms = *symlist; - - while (symnum < lastsym && symnum < nlist_nsyms_global) - { - read_one_sym (ms, &sub_sym, &sub_aux); - name = ms->c_name; - name = (name[0] == '_' ? name + offset : name); - - switch (ms->c_sclass) - { - case C_MOE: - sym = (struct symbol *) xmalloc (sizeof (struct symbol)); - bzero (sym, sizeof (struct symbol)); - - SYMBOL_NAME (sym) = savestring (name, strlen (name)); - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - SYMBOL_VALUE (sym) = ms->c_value; - add_symbol_to_list (sym, symlist); - nsyms++; - break; - - case C_EOS: - break; - } - } - - /* Now fill in the fields of the type-structure. */ - - TYPE_LENGTH (type) = sizeof (int); - TYPE_CODE (type) = TYPE_CODE_ENUM; - TYPE_NFIELDS (type) = nsyms; - TYPE_FIELDS (type) = (struct field *) - obstack_alloc (symbol_obstack, sizeof (struct field) * nsyms); - - /* Find the symbols for the values and put them into the type. - The symbols can be found in the symlist that we put them on - to cause them to be defined. osyms contains the old value - of that symlist; everything up to there was defined by us. */ - - for (syms = *symlist, n = nsyms; syms != osyms; syms = syms->next) - { - SYMBOL_TYPE (syms->symbol) = type; - TYPE_FIELD_NAME (type, --n) = SYMBOL_NAME (syms->symbol); - TYPE_FIELD_VALUE (type, n) = SYMBOL_VALUE (syms->symbol); - TYPE_FIELD_BITPOS (type, n) = 0; - TYPE_FIELD_BITSIZE (type, n) = 0; - } - return type; -} - -static -initialize () -{ - symfile = 0; - - add_com ("symbol-file", class_files, symbol_file_command, - "Load symbol table (in coff format) from executable file FILE."); -} - -END_FILE - -#endif /* COFF_FORMAT */ - + struct sym
\ No newline at end of file diff --git a/gdb/coffread.c.README b/gdb/coffread.c.README new file mode 100644 index 0000000..922e50c --- /dev/null +++ b/gdb/coffread.c.README @@ -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). diff --git a/gdb/coffread.c.pmax b/gdb/coffread.c.pmax new file mode 100644 index 0000000..17b53bd --- /dev/null +++ b/gdb/coffread.c.pmax @@ -0,0 +1,1851 @@ +/* Read coff symbol tables and convert to internal format, for GDB. + Design and support routines derived from dbxread.c, and UMAX COFF + specific routines written 9/1/87 by David D. Johnson, Brown University. + Revised 11/27/87 ddj@cs.brown.edu + Copyright (C) 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 +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 "defs.h" +#include "param.h" +#ifdef COFF_FORMAT +#include "initialize.h" +#include "symtab.h" + +#include <a.out.h> +#include <stdio.h> +#include <obstack.h> +#include <sys/param.h> +#include <sys/file.h> + +static void add_symbol_to_list (); +static void read_coff_symtab (); +static void patch_opaque_types (); +static struct type *decode_function_type (); +static struct type *decode_type (); +static struct type *decode_base_type (); +static struct type *read_enum_type (); +static struct type *read_struct_type (); +static void finish_block (); +static struct blockvector *make_blockvector (); +static struct symbol *process_coff_symbol (); +static int init_stringtab (); +static void free_stringtab (); +static char *getfilename (); +static char *getsymname (); +static int init_lineno (); +static void enter_linenos (); + +extern void free_all_symtabs (); + +START_FILE + +/* Name of source file whose symbol data we are now processing. + This comes from a symbol named ".file". */ + +static char *last_source_file; + +/* Core address of start and end of text of current source file. + This comes from a ".text" symbol where x_nlinno > 0. */ + +static CORE_ADDR cur_src_start_addr; +static CORE_ADDR cur_src_end_addr; + +/* End of the text segment of the executable file, + as found in the symbol _etext. */ + +static CORE_ADDR end_of_text_addr; + +/* The addresses of the symbol table stream and number of symbols + of the object file we are reading (as copied into core). */ + +static FILE *nlist_stream_global; +static int nlist_nsyms_global; + +/* The file and text section headers of the symbol file */ + +static FILHDR file_hdr; +static SCNHDR text_hdr; + +/* The index in the symbol table of the last coff symbol that was processed. */ + +static int symnum; + +/* Vector of types defined so far, indexed by their coff symnum. */ + +static struct typevector *type_vector; + +/* Number of elements allocated for type_vector currently. */ + +static int type_vector_length; + +/* Vector of line number information. */ + +static struct linetable *line_vector; + +/* Index of next entry to go in line_vector_index. */ + +static int line_vector_index; + +/* Last line number recorded in the line vector. */ + +static int prev_line_number; + +/* Number of elements allocated for line_vector currently. */ + +static int line_vector_length; + +/* Chain of typedefs of pointers to empty struct/union types. + They are chained thru the SYMBOL_VALUE. */ + +#define HASHSIZE 127 +static struct symbol *opaque_type_chain[HASHSIZE]; + +/* Record the symbols defined for each context in a list. + We don't create a struct block for the context until we + know how long to make it. */ + +struct pending +{ + struct pending *next; + struct symbol *symbol; +}; + +/* Here are the three lists that symbols are put on. */ + +struct pending *file_symbols; /* static at top level, and types */ + +struct pending *global_symbols; /* global functions and variables */ + +struct pending *local_symbols; /* everything local to lexical context */ + +/* List of unclosed lexical contexts + (that will become blocks, eventually). */ + +struct context_stack +{ + struct context_stack *next; + struct pending *locals; + struct pending_block *old_blocks; + struct symbol *name; + CORE_ADDR start_addr; + int depth; +}; + +struct context_stack *context_stack; + +/* Nonzero if within a function (so symbols should be local, + if nothing says specifically). */ + +int within_function; + +/* List of blocks already made (lexical contexts already closed). + This is used at the end to make the blockvector. */ + +struct pending_block +{ + struct pending_block *next; + struct block *block; +}; + +struct pending_block *pending_blocks; + +extern CORE_ADDR first_object_file_end; /* From blockframe.c */ + +/* File name symbols were loaded from. */ + +static char *symfile; + +/* Look up a coff type-number index. Return the address of the slot + where the type for that index is stored. + The type-number is in INDEX. + + This can be used for finding the type associated with that index + or for associating a new type with the index. */ + +static struct type ** +coff_lookup_type (index) + register int index; +{ + if (index >= type_vector_length) + { + type_vector_length *= 2; + type_vector = (struct typevector *) + xrealloc (type_vector, sizeof (struct typevector) + + type_vector_length * sizeof (struct type *)); + bzero (&type_vector->type[type_vector_length / 2], + type_vector_length * sizeof (struct type *) / 2); + } + return &type_vector->type[index]; +} + +/* Make sure there is a type allocated for type number index + and return the type object. + This can create an empty (zeroed) type object. */ + +static struct type * +coff_alloc_type (index) + int index; +{ + register struct type **type_addr = coff_lookup_type (index); + register struct type *type = *type_addr; + + /* If we are referring to a type not known at all yet, + allocate an empty type for it. + We will fill it in later if we find out how. */ + if (type == 0) + { + type = (struct type *) obstack_alloc (symbol_obstack, + sizeof (struct type)); + bzero (type, sizeof (struct type)); + *type_addr = type; + } + return type; +} + +/* maintain the lists of symbols and blocks */ + +/* Add a symbol to one of the lists of symbols. */ +static void +add_symbol_to_list (symbol, listhead) + struct symbol *symbol; + struct pending **listhead; +{ + register struct pending *link + = (struct pending *) xmalloc (sizeof (struct pending)); + + link->next = *listhead; + link->symbol = symbol; + *listhead = link; +} + +/* Take one of the lists of symbols and make a block from it. + Put the block on the list of pending blocks. */ + +static void +finish_block (symbol, listhead, old_blocks, start, end) + struct symbol *symbol; + struct pending **listhead; + struct pending_block *old_blocks; + CORE_ADDR start, end; +{ + register struct pending *next, *next1; + register struct block *block; + register struct pending_block *pblock; + struct pending_block *opblock; + register int i; + + /* Count the length of the list of symbols. */ + + for (next = *listhead, i = 0; next; next = next->next, i++); + + block = (struct block *) + obstack_alloc (symbol_obstack, sizeof (struct block) + (i - 1) * sizeof (struct symbol *)); + + /* Copy the symbols into the block. */ + + BLOCK_NSYMS (block) = i; + for (next = *listhead; next; next = next->next) + BLOCK_SYM (block, --i) = next->symbol; + + BLOCK_START (block) = start; + BLOCK_END (block) = end; + BLOCK_SUPERBLOCK (block) = 0; /* Filled in when containing block is made */ + + /* Put the block in as the value of the symbol that names it. */ + + if (symbol) + { + SYMBOL_BLOCK_VALUE (symbol) = block; + BLOCK_FUNCTION (block) = symbol; + } + else + BLOCK_FUNCTION (block) = 0; + + /* Now free the links of the list, and empty the list. */ + + for (next = *listhead; next; next = next1) + { + next1 = next->next; + free (next); + } + *listhead = 0; + + /* Install this block as the superblock + of all blocks made since the start of this scope + that don't have superblocks yet. */ + + opblock = 0; + for (pblock = pending_blocks; pblock != old_blocks; pblock = pblock->next) + { + if (BLOCK_SUPERBLOCK (pblock->block) == 0) + BLOCK_SUPERBLOCK (pblock->block) = block; + opblock = pblock; + } + + /* Record this block on the list of all blocks in the file. + Put it after opblock, or at the beginning if opblock is 0. + This puts the block in the list after all its subblocks. */ + + pblock = (struct pending_block *) xmalloc (sizeof (struct pending_block)); + pblock->block = block; + if (opblock) + { + pblock->next = opblock->next; + opblock->next = pblock; + } + else + { + pblock->next = pending_blocks; + pending_blocks = pblock; + } +} + +static struct blockvector * +make_blockvector () +{ + register struct pending_block *next, *next1; + register struct blockvector *blockvector; + register int i; + + /* Count the length of the list of blocks. */ + + for (next = pending_blocks, i = 0; next; next = next->next, i++); + + blockvector = (struct blockvector *) + obstack_alloc (symbol_obstack, sizeof (struct blockvector) + (i - 1) * sizeof (struct block *)); + + /* Copy the blocks into the blockvector. + This is done in reverse order, which happens to put + the blocks into the proper order (ascending starting address). + finish_block has hair to insert each block into the list + after its subblocks in order to make sure this is true. */ + + BLOCKVECTOR_NBLOCKS (blockvector) = i; + for (next = pending_blocks; next; next = next->next) + BLOCKVECTOR_BLOCK (blockvector, --i) = next->block; + + /* Now free the links of the list, and empty the list. */ + + for (next = pending_blocks; next; next = next1) + { + next1 = next->next; + free (next); + } + pending_blocks = 0; + + return blockvector; +} + +/* Manage the vector of line numbers. */ + +static +record_line (line, pc) + int line; + CORE_ADDR pc; +{ + /* Make sure line vector is big enough. */ + + if (line_vector_index + 2 >= line_vector_length) + { + line_vector_length *= 2; + line_vector = (struct linetable *) + xrealloc (line_vector, sizeof (struct linetable) + + line_vector_length * sizeof (int)); + } + + /* If this line is not continguous with previous one recorded, + all lines between subsequent line and current one are same pc. + Add one item to line vector, and if more than one line skipped, + record a line-number entry for it. */ + if (prev_line_number > 0 && line != prev_line_number + 1) + line_vector->item[line_vector_index++] = pc; + if (prev_line_number < 0 || line > prev_line_number + 2) + line_vector->item[line_vector_index++] = - line; + prev_line_number = line; + + /* Record the core address of the line. */ + line_vector->item[line_vector_index++] = pc; +} + +/* Start a new symtab for a new source file. + This is called when a COFF ".file" symbol is seen; + it indicates the start of data for one original source file. */ + +static void +start_symtab () +{ + file_symbols = 0; + global_symbols = 0; + context_stack = 0; + within_function = 0; + last_source_file = 0; + + /* Initialize the source file information for this file. */ + + line_vector_index = 0; + line_vector_length = 1000; + prev_line_number = -2; /* Force first line number to be explicit */ + line_vector = (struct linetable *) + xmalloc (sizeof (struct linetable) + line_vector_length * sizeof (int)); +} + +/* Save the vital information for use when closing off the current file. + NAME is the file name the symbols came from, START_ADDR is the first + text address for the file, and SIZE is the number of bytes of text. */ + +static void +complete_symtab (name, start_addr, size) + char *name; + CORE_ADDR start_addr; + unsigned int size; +{ + last_source_file = savestring (name, strlen (name)); + cur_src_start_addr = start_addr; + cur_src_end_addr = start_addr + size; +} + +/* Finish the symbol definitions for one main source file, + close off all the lexical contexts for that file + (creating struct block's for them), then make the + struct symtab for that file and put it in the list of all such. */ + +static void +end_symtab () +{ + register struct symtab *symtab; + register struct context_stack *cstk; + register struct blockvector *blockvector; + register struct linetable *lv; + + /* Finish the lexical context of the last function in the file. */ + + if (context_stack) + { + cstk = context_stack; + /* Make a block for the local symbols within. */ + finish_block (cstk->name, &local_symbols, cstk->old_blocks, + cstk->start_addr, cur_src_end_addr); + free (cstk); + } + + finish_block (0, &file_symbols, 0, cur_src_start_addr, cur_src_end_addr); + finish_block (0, &global_symbols, 0, cur_src_start_addr, cur_src_end_addr); + blockvector = make_blockvector (); + + /* Now create the symtab object this source file. */ + + symtab = (struct symtab *) xmalloc (sizeof (struct symtab)); + symtab->free_ptr = 0; + + /* Fill in its components. */ + symtab->blockvector = blockvector; + symtab->free_code = free_linetable; + symtab->filename = last_source_file; + lv = line_vector; + lv->nitems = line_vector_index; + symtab->linetable = (struct linetable *) + xrealloc (lv, sizeof (struct linetable) + lv->nitems * sizeof (int)); + symtab->nlines = 0; + symtab->line_charpos = 0; + + /* Link the new symtab into the list of such. */ + symtab->next = symtab_list; + symtab_list = symtab; + + line_vector = 0; + line_vector_length = -1; + last_source_file = 0; +} + +/* Accumulate the misc functions in bunches of 127. + At the end, copy them all into one newly allocated structure. */ + +#define MISC_BUNCH_SIZE 127 + +struct misc_bunch +{ + struct misc_bunch *next; + struct misc_function contents[MISC_BUNCH_SIZE]; +}; + +/* Bunch currently being filled up. + The next field points to chain of filled bunches. */ + +static struct misc_bunch *misc_bunch; + +/* Number of slots filled in current bunch. */ + +static int misc_bunch_index; + +/* Total number of misc functions recorded so far. */ + +static int misc_count; + +static void +init_misc_functions () +{ + misc_count = 0; + misc_bunch = 0; + misc_bunch_index = MISC_BUNCH_SIZE; +} + +static void +record_misc_function (name, address) + char *name; + CORE_ADDR address; +{ + register struct misc_bunch *new; + + if (misc_bunch_index == MISC_BUNCH_SIZE) + { + new = (struct misc_bunch *) xmalloc (sizeof (struct misc_bunch)); + misc_bunch_index = 0; + new->next = misc_bunch; + misc_bunch = new; + } + misc_bunch->contents[misc_bunch_index].name = savestring (name, strlen (name)); + misc_bunch->contents[misc_bunch_index].address = address; + misc_bunch_index++; + misc_count++; +} + +static int +compare_misc_functions (fn1, fn2) + struct misc_function *fn1, *fn2; +{ + /* Return a signed result based on unsigned comparisons + so that we sort into unsigned numeric order. */ + if (fn1->address < fn2->address) + return -1; + if (fn1->address > fn2->address) + return 1; + return 0; +} + +static void +discard_misc_bunches () +{ + register struct misc_bunch *next; + + while (misc_bunch) + { + next = misc_bunch->next; + free (misc_bunch); + misc_bunch = next; + } +} + +static void +condense_misc_bunches () +{ + register int i, j; + register struct misc_bunch *bunch; +#ifdef NAMES_HAVE_UNDERSCORE + int offset = 1; +#else + int offset = 0; +#endif + + misc_function_vector + = (struct misc_function *) + xmalloc (misc_count * sizeof (struct misc_function)); + + j = 0; + bunch = misc_bunch; + while (bunch) + { + for (i = 0; i < misc_bunch_index; i++) + { + register char *tmp; + + misc_function_vector[j] = bunch->contents[i]; + tmp = misc_function_vector[j].name; + misc_function_vector[j].name = (tmp[0] == '_' ? tmp + offset : tmp); + j++; + } + bunch = bunch->next; + misc_bunch_index = MISC_BUNCH_SIZE; + } + + misc_function_count = j; + + /* Sort the misc functions by address. */ + + qsort (misc_function_vector, j, sizeof (struct misc_function), + compare_misc_functions); +} + +/* Call sort_syms to sort alphabetically + the symbols of each block of each symtab. */ + +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 +sort_syms () +{ + register struct symtab *s; + register int i, nbl; + register struct blockvector *bv; + register struct block *b; + + for (s = symtab_list; s; s = s->next) + { + bv = BLOCKVECTOR (s); + nbl = BLOCKVECTOR_NBLOCKS (bv); + for (i = 0; i < nbl; i++) + { + b = BLOCKVECTOR_BLOCK (bv, i); + qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b), + sizeof (struct symbol *), compare_symbols); + } + } +} + +/* This is the symbol-file command. Read the file, analyze its symbols, + and add a struct symtab to symtab_list. */ + +void +symbol_file_command (name) + char *name; +{ + int desc; + int num_symbols; + int num_sections; + int symtab_offset; + extern void close (); + register int val; + struct cleanup *old_chain; + + dont_repeat (); + + if (name == 0) + { + if (symtab_list && !query ("Discard symbol table? ", 0)) + error ("Not confirmed."); + free_all_symtabs (); + return; + } + + if (symtab_list && !query ("Load new symbol table from \"%s\"? ", name)) + error ("Not confirmed."); + + if (symfile) + free (symfile); + symfile = 0; + + { + char *absolute_name; + + desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name); + if (desc < 0) + perror_with_name (name); + else + name = absolute_name; + } + + old_chain = make_cleanup (close, desc); + make_cleanup (free_current_contents, &name); + + if ((num_symbols = read_file_hdr (desc, &file_hdr)) < 0) + error ("File \"%s\" not in executable format.", name); + + if (num_symbols == 0) + { + free_all_symtabs (); + printf ("%s does not have a symbol-table.\n", name); + fflush (stdout); + return; + } + + printf ("Reading symbol data from %s...", name); + fflush (stdout); + + /* Throw away the old symbol table. */ + + free_all_symtabs (); + + num_sections = file_hdr.f_nscns; + symtab_offset = file_hdr.f_symptr; + + if (read_section_hdr (desc, _TEXT, &text_hdr, num_sections) < 0) + error ("\"%s\": can't read text section header", name); + + /* Read the line number table, all at once. */ + + val = init_lineno (desc, text_hdr.s_lnnoptr, text_hdr.s_nlnno); + if (val < 0) + error ("\"%s\": error reading line numbers\n", name); + + /* Now read the string table, all at once. */ + + val = init_stringtab (desc, symtab_offset + num_symbols * SYMESZ); + if (val < 0) + { + free_all_symtabs (); + printf ("\"%s\": can't get string table", name); + fflush (stdout); + return; + } + make_cleanup (free_stringtab, 0); + + /* Position to read the symbol table. Do not read it all at once. */ + val = lseek (desc, (long)symtab_offset, 0); + if (val < 0) + perror_with_name (name); + + init_misc_functions (); + make_cleanup (discard_misc_bunches, 0); + + /* Now that the executable file is positioned at symbol table, + process it and define symbols accordingly. */ + + read_coff_symtab (desc, num_symbols); + + patch_opaque_types (); + + /* Sort symbols alphabetically within each block. */ + + sort_syms (); + + /* Go over the misc functions and install them in vector. */ + + condense_misc_bunches (); + + /* Don't allow char * to have a typename (else would get caddr_t.) */ + + TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0; + + /* Make a default for file to list. */ + + select_source_symtab (symtab_list); + + symfile = savestring (name, strlen (name)); + + do_cleanups (old_chain); + + printf ("done.\n"); + fflush (stdout); +} + +/* Return name of file symbols were loaded from, or 0 if none.. */ + +char * +get_sym_file () +{ + return symfile; +} + +/* Simplified internal version of coff symbol table information */ + +struct coff_symbol { + char *c_name; + int c_symnum; /* symbol number of this entry */ + int c_nsyms; /* 1 if syment only, 2 if syment + auxent */ + long c_value; + int c_sclass; + int c_secnum; + unsigned int c_type; +}; + +/* Given pointers to a symbol table in coff style exec file, + analyze them and create struct symtab's describing the symbols. + NSYMS is the number of symbols in the symbol table. + We read them one at a time using read_one_sym (). */ + +static void +read_coff_symtab (desc, nsyms) + int desc; + int nsyms; +{ + FILE *stream = fdopen (desc, "r"); + register struct context_stack *new; + struct coff_symbol coff_symbol; + register struct coff_symbol *cs = &coff_symbol; + static SYMENT main_sym; + static AUXENT main_aux; + + int num_object_files = 0; + int next_file_symnum; + char *filestring; + int depth; + int fcn_first_line; + int fcn_last_line; + long fcn_line_ptr; + struct cleanup *old_chain; + + old_chain = make_cleanup (free_all_symtabs, 0); + nlist_stream_global = stream; + nlist_nsyms_global = nsyms; + last_source_file = 0; + bzero (opaque_type_chain, sizeof opaque_type_chain); + + type_vector_length = 160; + type_vector = (struct typevector *) + xmalloc (sizeof (struct typevector) + + type_vector_length * sizeof (struct type *)); + bzero (type_vector->type, type_vector_length * sizeof (struct type *)); + + start_symtab (); + + symnum = 0; + while (symnum < nsyms) + { + QUIT; /* Make this command interruptable. */ + read_one_sym (cs, &main_sym, &main_aux); + + if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE) + { + CORE_ADDR last_file_end = cur_src_end_addr; + + if (last_source_file) + end_symtab (); + + start_symtab (); + complete_symtab ("_globals_", 0, first_object_file_end); + /* done with all files, everything from here on out is globals */ + } + + /* Special case for file with type declarations only, no text. */ + if (!last_source_file && cs->c_type != T_NULL && cs->c_secnum == N_DEBUG) + complete_symtab (filestring, 0, 0); + + if (ISFCN (cs->c_type)) + { + /* + * gdb expects all functions to also be in misc_function + * list -- why not... + */ + record_misc_function (cs->c_name, cs->c_value); + + fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr; + within_function = 1; + + new = (struct context_stack *) + xmalloc (sizeof (struct context_stack)); + new->depth = depth = 0; + new->next = 0; + context_stack = new; + new->locals = 0; + new->old_blocks = pending_blocks; + new->start_addr = cs->c_value; + new->name = process_coff_symbol (cs, &main_aux); + continue; + } + + switch (cs->c_sclass) + { + case C_EFCN: + case C_EXTDEF: + case C_ULABEL: + case C_USTATIC: + case C_LINE: + case C_ALIAS: + case C_HIDDEN: + printf ("Bad n_sclass = %d\n", cs->c_sclass); + break; + + case C_FILE: + /* + * c_value field contains symnum of next .file entry in table + * or symnum of first global after last .file. + */ + next_file_symnum = cs->c_value; + filestring = getfilename (&main_aux); + /* + * Complete symbol table for last object file + * containing debugging information. + */ + if (last_source_file) + { + end_symtab (); + start_symtab (); + } + num_object_files++; + break; + + case C_EXT: + if (cs->c_secnum == N_ABS && strcmp (cs->c_name, _ETEXT) == 0) + { + end_of_text_addr = cs->c_value; + } + if (cs->c_type == T_NULL) + { + if (cs->c_secnum <= 1) /* text or abs */ + { + record_misc_function (cs->c_name, cs->c_value); + break; + } + else + cs->c_type = T_INT; + } + (void) process_coff_symbol (cs, &main_aux); + break; + + case C_STAT: + if (cs->c_type == T_NULL && cs->c_secnum > N_UNDEF) + { + if (strcmp (cs->c_name, _TEXT) == 0) + { + if (num_object_files == 1) + { + /* Record end address of first file, crt0.s */ + first_object_file_end = + cs->c_value + main_aux.x_scn.x_scnlen; + } + /* + * Fill in missing information for debugged + * object file only if we have line number info. + */ + if (main_aux.x_scn.x_nlinno > 0) + { + complete_symtab (filestring, cs->c_value, + main_aux.x_scn.x_scnlen); + } + break; + } + else if (strcmp (cs->c_name, _DATA) == 0) + break; + else if (strcmp (cs->c_name, _BSS) == 0) + break; + + /* get rid of assembly labels here */ + /* record_misc_function (cs->c_name, cs->c_value); */ + break; + } + (void) process_coff_symbol (cs, &main_aux); + break; + + case C_FCN: + if (strcmp (cs->c_name, ".bf") == 0) + { + /* value contains address of first non-init type code */ + /* main_aux.x_sym.x_misc.x_lnsz.x_lnno + contains line number of '{' } */ + fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; + } + else if (strcmp (cs->c_name, ".ef") == 0) + { + /* value contains address of exit/return from function */ + /* round it up to next multiple of 16 */ + cs->c_value = (cs->c_value + 15) & -16; + /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno + contains number of lines to '}' */ + fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; + enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line); + + new = context_stack; + finish_block (new->name, &local_symbols, new->old_blocks, + new->start_addr, cs->c_value); + context_stack = 0; + within_function = 0; + free (new); + } + break; + + case C_BLOCK: + if (strcmp (cs->c_name, ".bb") == 0) + { + new = (struct context_stack *) + xmalloc (sizeof (struct context_stack)); + depth++; + new->depth = depth; + new->next = context_stack; + context_stack = new; + new->locals = local_symbols; + new->old_blocks = pending_blocks; + new->start_addr = cs->c_value; + new->name = 0; + local_symbols = 0; + } + else if (strcmp (cs->c_name, ".eb") == 0) + { + new = context_stack; + if (new == 0 || depth != new->depth) + error ("Invalid symbol data: .bb/.eb symbol mismatch."); + if (local_symbols && context_stack->next) + { + /* Make a block for the local symbols within. */ + finish_block (0, &local_symbols, new->old_blocks, + new->start_addr, cs->c_value); + } + depth--; + local_symbols = new->locals; + context_stack = new->next; + free (new); + } + break; + + default: + (void) process_coff_symbol (cs, &main_aux); + break; + } + } + + if (last_source_file) + end_symtab (); + fclose (stream); + discard_cleanups (old_chain); +} + +/* Routines for reading headers and symbols from executable. */ + +/* Read COFF file header, check magic number, + and return number of symbols. */ +read_file_hdr (chan, file_hdr) + int chan; + FILHDR *file_hdr; +{ + lseek (chan, 0L, 0); + if (myread (chan, (char *)file_hdr, FILHSZ) < 0) + return -1; + + switch (file_hdr->f_magic) + { + case NS32GMAGIC: + case NS32SMAGIC: + return file_hdr->f_nsyms; + + default: + return -1; + } +} + +read_aout_hdr (chan, aout_hdr, size) + int chan; + AOUTHDR *aout_hdr; + int size; +{ + lseek (chan, (long)FILHSZ, 0); + if (size != sizeof (AOUTHDR)) + return -1; + if (myread (chan, (char *)aout_hdr, size) != size) + return -1; + return 0; +} + +read_section_hdr (chan, section_name, section_hdr, nsects) + register int chan; + register char *section_name; + SCNHDR *section_hdr; + register int nsects; +{ + register int i; + + if (lseek (chan, FILHSZ + sizeof (AOUTHDR), 0) < 0) + return -1; + + for (i = 0; i < nsects; i++) + { + if (myread (chan, (char *)section_hdr, SCNHSZ) < 0) + return -1; + if (strncmp (section_hdr->s_name, section_name, 8) == 0) + return 0; + } + return -1; +} + +read_one_sym (cs, sym, aux) + register struct coff_symbol *cs; + register SYMENT *sym; + register AUXENT *aux; +{ + cs->c_symnum = symnum; + fread ((char *)sym, SYMESZ, 1, nlist_stream_global); + cs->c_nsyms = (sym->n_numaux & 0xff) + 1; + if (cs->c_nsyms == 2) + { + /* doc for coff says there is either no aux entry or just one */ + fread ((char *)aux, AUXESZ, 1, nlist_stream_global); + } + else if (cs->c_nsyms > 2) + error ("more than one aux symbol table entry at symnum=%d\n", symnum); + + cs->c_name = getsymname (sym); + cs->c_value = sym->n_value; + cs->c_sclass = (sym->n_sclass & 0xff); + cs->c_secnum = sym->n_scnum; + cs->c_type = (unsigned) sym->n_type; + + symnum += cs->c_nsyms; +} + +/* Support for string table handling */ + +static char *stringtab = NULL; + +static int +init_stringtab (chan, offset) + int chan; + long offset; +{ + long buffer; + int val; + + if (lseek (chan, offset, 0) < 0) + return -1; + + val = myread (chan, (char *)&buffer, sizeof buffer); + if (val != sizeof buffer) + return -1; + + if (stringtab) + free (stringtab); + stringtab = (char *) xmalloc (buffer); + if (stringtab == NULL) + return -1; + + bcopy (&buffer, stringtab, sizeof buffer); + + val = myread (chan, stringtab + sizeof buffer, buffer - sizeof buffer); + if (val != buffer - sizeof buffer || stringtab[buffer - 1] != '\0') + return -1; + + return 0; +} + +static void +free_stringtab () +{ + if (stringtab) + free (stringtab); + stringtab = NULL; +} + +static char * +getsymname (symbol_entry) + SYMENT *symbol_entry; +{ + static char buffer[SYMNMLEN+1]; + char *result; + + if (symbol_entry->n_zeroes == 0) + { + result = stringtab + symbol_entry->n_offset; + } + else + { + strncpy (buffer, symbol_entry->n_name, SYMNMLEN); + buffer[SYMNMLEN] = '\0'; + result = buffer; + } + return result; +} + +static char * +getfilename (aux_entry) + AUXENT *aux_entry; +{ + static char buffer[BUFSIZ]; + register char *temp; + char *result; + extern char *rindex (); + + if (aux_entry->x_file.x_foff != 0) + strcpy (buffer, stringtab + aux_entry->x_file.x_foff); + else + { + strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN); + buffer[FILNMLEN] = '\0'; + } + result = buffer; + if ((temp = rindex (result, '/')) != NULL) + result = temp + 1; + return (result); +} + +/* Support for line number handling */ +static char *linetab = NULL; +static long linetab_offset; +static int linetab_count; + +static int +init_lineno (chan, offset, count) + int chan; + long offset; + int count; +{ + int val; + + if (lseek (chan, offset, 0) < 0) + return -1; + + if (linetab) + free (linetab); + linetab = (char *) xmalloc (count * LINESZ); + + val = myread (chan, linetab, count * LINESZ); + if (val != count * LINESZ) + return -1; + + linetab_offset = offset; + linetab_count = count; + return 0; +} + +static void +enter_linenos (file_offset, first_line, last_line) + long file_offset; + register int first_line; + register int last_line; +{ + register char *rawptr = &linetab[file_offset - linetab_offset]; + register struct lineno *lptr; + + /* skip first line entry for each function */ + rawptr += LINESZ; + /* line numbers start at one for the first line of the function */ + first_line--; + + for (lptr = (struct lineno *)rawptr; + lptr->l_lnno && lptr->l_lnno <= last_line; + rawptr += LINESZ, lptr = (struct lineno *)rawptr) + { + record_line (first_line + lptr->l_lnno, lptr->l_addr.l_paddr); + } +} + +static int +hashname (name) + char *name; +{ + register char *p = name; + register int total = p[0]; + register int c; + + c = p[1]; + total += c << 2; + if (c) + { + c = p[2]; + total += c << 4; + if (c) + total += p[3] << 6; + } + + return total % HASHSIZE; +} + +static void +patch_type (type, real_type) + struct type *type; + struct type *real_type; +{ + register struct type *target = TYPE_TARGET_TYPE (type); + register struct type *real_target = TYPE_TARGET_TYPE (real_type); + int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field); + + TYPE_LENGTH (target) = TYPE_LENGTH (real_target); + TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target); + TYPE_FIELDS (target) = (struct field *) + obstack_alloc (symbol_obstack, field_size); + + bcopy (TYPE_FIELDS (real_target), TYPE_FIELDS (target), field_size); + + if (TYPE_NAME (real_target)) + { + if (TYPE_NAME (target)) + free (TYPE_NAME (target)); + TYPE_NAME (target) = concat (TYPE_NAME (real_target), "", ""); + } +} + +/* Patch up all appropriate typdef symbols in the opaque_type_chains + so that they can be used to print out opaque data structures properly */ + +static void +patch_opaque_types () +{ + struct symtab *s; + + /* Look at each symbol in the per-file block of each symtab. */ + for (s = symtab_list; s; s = s->next) + { + register struct block *b; + register int i; + + /* Go through the per-file symbols only */ + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1); + for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--) + { + register struct symbol *real_sym; + + /* Find completed typedefs to use to fix opaque ones. + Remove syms from the chain when their types are stored, + but search the whole chain, as there may be several syms + from different files with the same name. */ + real_sym = BLOCK_SYM (b, i); + if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF && + SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE && + TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR && + TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0) + { + register char *name = SYMBOL_NAME (real_sym); + register int hash = hashname (name); + register struct symbol *sym, *prev; + + prev = 0; + for (sym = opaque_type_chain[hash]; sym;) + { + if (name[0] == SYMBOL_NAME (sym)[0] && + !strcmp (name + 1, SYMBOL_NAME (sym) + 1)) + { + if (prev) + SYMBOL_VALUE (prev) = SYMBOL_VALUE (sym); + else + opaque_type_chain[hash] + = (struct symbol *) SYMBOL_VALUE (sym); + + patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym)); + + if (prev) + sym = (struct symbol *) SYMBOL_VALUE (prev); + else + sym = opaque_type_chain[hash]; + } + else + { + prev = sym; + sym = (struct symbol *) SYMBOL_VALUE (sym); + } + } + } + } + } +} + +static struct symbol * +process_coff_symbol (cs, aux) + register struct coff_symbol *cs; + register AUXENT *aux; +{ + register struct symbol *sym + = (struct symbol *) obstack_alloc (symbol_obstack, sizeof (struct symbol)); + char *name; + char *dot; +#ifdef NAMES_HAVE_UNDERSCORE + int offset = 1; +#else + int offset = 0; +#endif + + bzero (sym, sizeof (struct symbol)); + name = cs->c_name; + name = (name[0] == '_' ? name + offset : name); + SYMBOL_NAME (sym) = obstack_copy0 (symbol_obstack, name, strlen (name)); + + /* default assumptions */ + SYMBOL_VALUE (sym) = cs->c_value; + SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + + if (ISFCN (cs->c_type)) + { + SYMBOL_TYPE (sym) + = lookup_function_type (decode_function_type (cs, cs->c_type, aux)); + SYMBOL_CLASS (sym) = LOC_BLOCK; + if (cs->c_sclass == C_STAT) + add_symbol_to_list (sym, &file_symbols); + else if (cs->c_sclass == C_EXT) + add_symbol_to_list (sym, &global_symbols); + } + else + { + SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux); + switch (cs->c_sclass) + { + case C_NULL: + break; + + case C_AUTO: + SYMBOL_CLASS (sym) = LOC_LOCAL; + add_symbol_to_list (sym, &local_symbols); + break; + + case C_EXT: + SYMBOL_CLASS (sym) = LOC_STATIC; + add_symbol_to_list (sym, &global_symbols); + break; + + case C_STAT: + SYMBOL_CLASS (sym) = LOC_STATIC; + if (within_function) { + /* Static symbol of local scope */ + add_symbol_to_list (sym, &local_symbols); + } + else { + /* Static symbol at top level of file */ + add_symbol_to_list (sym, &file_symbols); + } + break; + + case C_REG: + case C_REGPARM: + SYMBOL_CLASS (sym) = LOC_REGISTER; + add_symbol_to_list (sym, &local_symbols); + break; + + case C_LABEL: + break; + + case C_ARG: + SYMBOL_CLASS (sym) = LOC_ARG; + add_symbol_to_list (sym, &local_symbols); + /* If PCC says a parameter is a short or a char, + it is really an int. */ + if (SYMBOL_TYPE (sym) == builtin_type_char + || SYMBOL_TYPE (sym) == builtin_type_short) + SYMBOL_TYPE (sym) = builtin_type_int; + else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char + || SYMBOL_TYPE (sym) == builtin_type_unsigned_short) + SYMBOL_TYPE (sym) = builtin_type_unsigned_int; + break; + + case C_TPDEF: + SYMBOL_CLASS (sym) = LOC_TYPEDEF; + SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + + /* If type has no name, give it one */ + if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0 + && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0) + TYPE_NAME (SYMBOL_TYPE (sym)) + = concat (SYMBOL_NAME (sym), "", ""); + + /* Keep track of any type which points to empty structured type, + so it can be filled from a definition from another file */ + if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR && + TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0) + { + register int i = hashname (SYMBOL_NAME (sym)); + + SYMBOL_VALUE (sym) = (int) opaque_type_chain[i]; + opaque_type_chain[i] = sym; + } + add_symbol_to_list (sym, &file_symbols); + break; + + case C_STRTAG: + case C_UNTAG: + case C_ENTAG: + SYMBOL_CLASS (sym) = LOC_TYPEDEF; + SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; + if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0 + && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0) + TYPE_NAME (SYMBOL_TYPE (sym)) + = concat ("", + (cs->c_sclass == C_ENTAG + ? "enum " + : (cs->c_sclass == C_STRTAG + ? "struct " : "union ")), + SYMBOL_NAME (sym)); + add_symbol_to_list (sym, &file_symbols); + break; + + default: + break; + } + } + return sym; +} + +/* Decode a coff type specifier; + return the type that is meant. */ + +static +struct type * +decode_type (cs, c_type, aux) + register struct coff_symbol *cs; + unsigned int c_type; + register AUXENT *aux; +{ + register struct type *type = 0; + register int n; + unsigned int new_c_type; + + if (c_type & ~N_BTMASK) + { + new_c_type = DECREF (c_type); + if (ISPTR (c_type)) + { + type = decode_type (cs, new_c_type, aux); + type = lookup_pointer_type (type); + } + else if (ISFCN (c_type)) + { + type = decode_type (cs, new_c_type, aux); + type = lookup_function_type (type); + } + else if (ISARY (c_type)) + { + int i, n; + register unsigned short *dim; + struct type *base_type; + + /* Define an array type. */ + /* auxent refers to array, not base type */ + if (aux->x_sym.x_tagndx == 0) + cs->c_nsyms = 1; + + /* shift the indices down */ + dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0]; + i = 1; + n = dim[0]; + for (i = 0; *dim && i < DIMNUM - 1; i++, dim++) + *dim = *(dim + 1); + *dim = 0; + + type = (struct type *) + obstack_alloc (symbol_obstack, sizeof (struct type)); + bzero (type, sizeof (struct type)); + + base_type = decode_type (cs, new_c_type, aux); + + TYPE_CODE (type) = TYPE_CODE_ARRAY; + TYPE_TARGET_TYPE (type) = base_type; + TYPE_LENGTH (type) = n * TYPE_LENGTH (base_type); + } + return type; + } + + /* Reference to existing type */ + if (cs->c_nsyms > 1 && aux->x_sym.x_tagndx != 0) + { + type = coff_alloc_type (aux->x_sym.x_tagndx); + return type; + } + + return decode_base_type (cs, BTYPE (c_type), aux); +} + +/* Decode a coff type specifier for function definition; + return the type that the function returns. */ + +static +struct type * +decode_function_type (cs, c_type, aux) + register struct coff_symbol *cs; + unsigned int c_type; + register AUXENT *aux; +{ + if (aux->x_sym.x_tagndx == 0) + cs->c_nsyms = 1; /* auxent refers to function, not base type */ + + return decode_type (cs, DECREF (cs->c_type), aux); +} + +/* basic C types */ + +static +struct type * +decode_base_type (cs, c_type, aux) + register struct coff_symbol *cs; + unsigned int c_type; + register AUXENT *aux; +{ + struct type *type; + + switch (c_type) + { + case T_NULL: + /* shouldn't show up here */ + break; + + case T_ARG: + /* shouldn't show up here */ + break; + + case T_CHAR: + return builtin_type_char; + + case T_SHORT: + return builtin_type_short; + + case T_INT: + return builtin_type_int; + + case T_LONG: + return builtin_type_long; + + case T_FLOAT: + return builtin_type_float; + + case T_DOUBLE: + return builtin_type_double; + + case T_STRUCT: + if (cs->c_nsyms != 2) + { + /* anonymous structure type */ + type = coff_alloc_type (cs->c_symnum); + TYPE_CODE (type) = TYPE_CODE_STRUCT; + TYPE_NAME (type) = concat ("struct ", "<opaque>", ""); + TYPE_LENGTH (type) = 0; + TYPE_FIELDS (type) = 0; + TYPE_NFIELDS (type) = 0; + } + else + { + type = read_struct_type (cs->c_symnum, + aux->x_sym.x_misc.x_lnsz.x_size, + aux->x_sym.x_fcnary.x_fcn.x_endndx); + } + return type; + + case T_UNION: + if (cs->c_nsyms != 2) + { + /* anonymous union type */ + type = coff_alloc_type (cs->c_symnum); + TYPE_NAME (type) = concat ("union ", "<opaque>", ""); + TYPE_LENGTH (type) = 0; + TYPE_FIELDS (type) = 0; + TYPE_NFIELDS (type) = 0; + } + else + { + type = read_struct_type (cs->c_symnum, + aux->x_sym.x_misc.x_lnsz.x_size, + aux->x_sym.x_fcnary.x_fcn.x_endndx); + } + TYPE_CODE (type) = TYPE_CODE_UNION; + return type; + + case T_ENUM: + return read_enum_type (cs->c_symnum, + aux->x_sym.x_misc.x_lnsz.x_size, + aux->x_sym.x_fcnary.x_fcn.x_endndx); + + case T_MOE: + /* shouldn't show up here */ + break; + + case T_UCHAR: + return builtin_type_unsigned_char; + + case T_USHORT: + return builtin_type_unsigned_short; + + case T_UINT: + return builtin_type_unsigned_int; + + case T_ULONG: + return builtin_type_unsigned_long; + } + printf ("unexpected type %d at symnum %d\n", c_type, cs->c_symnum); + return builtin_type_void; +} + +/* This page contains subroutines of read_type. */ + +/* Read the description of a structure (or union type) + and return an object describing the type. */ + +static struct type * +read_struct_type (index, length, lastsym) + int index; + int length; + int lastsym; +{ + struct nextfield + { + struct nextfield *next; + struct field field; + }; + + register struct type *type; + register struct nextfield *list = 0; + struct nextfield *new; + int nfields = 0; + register int n; + char *name; +#ifdef NAMES_HAVE_UNDERSCORE + int offset = 1; +#else + int offset = 0; +#endif + struct coff_symbol member_sym; + register struct coff_symbol *ms = &member_sym; + SYMENT sub_sym; + AUXENT sub_aux; + + type = coff_alloc_type (index); + TYPE_CODE (type) = TYPE_CODE_STRUCT; + TYPE_LENGTH (type) = length; + + while (symnum < lastsym && symnum < nlist_nsyms_global) + { + read_one_sym (ms, &sub_sym, &sub_aux); + name = ms->c_name; + name = (name[0] == '_' ? name + offset : name); + + switch (ms->c_sclass) + { + case C_MOS: + case C_MOU: + + /* Get space to record the next field's data. */ + new = (struct nextfield *) alloca (sizeof (struct nextfield)); + new->next = list; + list = new; + + /* Save the data. */ + list->field.name = savestring (name, strlen (name)); + list->field.type = decode_type (ms, ms->c_type, &sub_aux); + list->field.bitpos = 8 * ms->c_value; + list->field.bitsize = 0; + nfields++; + break; + + case C_FIELD: + + /* Get space to record the next field's data. */ + new = (struct nextfield *) alloca (sizeof (struct nextfield)); + new->next = list; + list = new; + + /* Save the data. */ + list->field.name = savestring (name, strlen (name)); + list->field.type = decode_type (ms, ms->c_type, &sub_aux); + list->field.bitpos = ms->c_value; + list->field.bitsize = sub_aux.x_sym.x_misc.x_lnsz.x_size; + nfields++; + break; + + case C_EOS: + break; + } + } + /* Now create the vector of fields, and record how big it is. */ + + TYPE_NFIELDS (type) = nfields; + TYPE_FIELDS (type) = (struct field *) + obstack_alloc (symbol_obstack, sizeof (struct field) * nfields); + + /* Copy the saved-up fields into the field vector. */ + + for (n = nfields; list; list = list->next) + TYPE_FIELD (type, --n) = list->field; + + return type; +} + +/* Read a definition of an enumeration type, + and create and return a suitable type object. + Also defines the symbols that represent the values of the type. */ + +static struct type * +read_enum_type (index, length, lastsym) + int index; + int length; + int lastsym; +{ + register struct symbol *sym; + register struct type *type; + int nsyms = 0; + struct pending **symlist; + struct coff_symbol member_sym; + register struct coff_symbol *ms = &member_sym; + SYMENT sub_sym; + AUXENT sub_aux; + struct pending *osyms, *syms; + register int n; + char *name; +#ifdef NAMES_HAVE_UNDERSCORE + int offset = 1; +#else + int offset = 0; +#endif + + type = coff_alloc_type (index); + if (within_function) + symlist = &local_symbols; + else + symlist = &file_symbols; + osyms = *symlist; + + while (symnum < lastsym && symnum < nlist_nsyms_global) + { + read_one_sym (ms, &sub_sym, &sub_aux); + name = ms->c_name; + name = (name[0] == '_' ? name + offset : name); + + switch (ms->c_sclass) + { + case C_MOE: + sym = (struct symbol *) xmalloc (sizeof (struct symbol)); + bzero (sym, sizeof (struct symbol)); + + SYMBOL_NAME (sym) = savestring (name, strlen (name)); + SYMBOL_CLASS (sym) = LOC_CONST; + SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_VALUE (sym) = ms->c_value; + add_symbol_to_list (sym, symlist); + nsyms++; + break; + + case C_EOS: + break; + } + } + + /* Now fill in the fields of the type-structure. */ + + TYPE_LENGTH (type) = sizeof (int); + TYPE_CODE (type) = TYPE_CODE_ENUM; + TYPE_NFIELDS (type) = nsyms; + TYPE_FIELDS (type) = (struct field *) + obstack_alloc (symbol_obstack, sizeof (struct field) * nsyms); + + /* Find the symbols for the values and put them into the type. + The symbols can be found in the symlist that we put them on + to cause them to be defined. osyms contains the old value + of that symlist; everything up to there was defined by us. */ + + for (syms = *symlist, n = nsyms; syms != osyms; syms = syms->next) + { + SYMBOL_TYPE (syms->symbol) = type; + TYPE_FIELD_NAME (type, --n) = SYMBOL_NAME (syms->symbol); + TYPE_FIELD_VALUE (type, n) = SYMBOL_VALUE (syms->symbol); + TYPE_FIELD_BITPOS (type, n) = 0; + TYPE_FIELD_BITSIZE (type, n) = 0; + } + return type; +} + +static +initialize () +{ + symfile = 0; + + add_com ("symbol-file", class_files, symbol_file_command, + "Load symbol table (in coff format) from executable file FILE."); +} + +END_FILE + +#endif /* COFF_FORMAT */ + diff --git a/gdb/command.c b/gdb/command.c index ec5bfc0..6643ad8 100644 --- a/gdb/command.c +++ b/gdb/command.c @@ -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'; diff --git a/gdb/config.gdb b/gdb/config.gdb new file mode 100644 index 0000000..6a8cbff --- /dev/null +++ b/gdb/config.gdb @@ -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 + @@ -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 () diff --git a/gdb/dbxread.c b/gdb/dbxread.c index 084135f..0ac4ff8 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -1,6 +1,5 @@ /* Read dbx symbol tables and convert to internal format, for GDB. Copyright (C) 1986, 1987, 1988 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 @@ -29,6 +28,7 @@ anyone else from sharing it farther. Help stamp out software hoarding! #include <obstack.h> #include <sys/param.h> #include <sys/file.h> +#include <sys/stat.h> #include "defs.h" #include "initialize.h" #include "symtab.h" @@ -51,9 +51,44 @@ static void hash_symsegs (); extern struct symtab *read_symsegs (); extern void free_all_symtabs (); -/* C++ */ -static struct type **read_args (); +/* Macro for number of symbol table entries (in usual a.out format). + Some machines override this definition. */ +#ifndef NUMBER_OF_SYMBOLS +#define NUMBER_OF_SYMBOLS (hdr.a_syms / sizeof (struct nlist)) +#endif + +/* Macro for file-offset of symbol table (in usual a.out format). */ +#ifndef SYMBOL_TABLE_OFFSET +#define SYMBOL_TABLE_OFFSET N_SYMOFF (hdr) +#endif + +/* Macro for file-offset of string table (in usual a.out format). */ +#ifndef STRING_TABLE_OFFSET +#define STRING_TABLE_OFFSET (N_SYMOFF (hdr) + hdr.a_syms) +#endif + +/* Macro to store the length of the string table data in INTO. */ +#ifndef READ_STRING_TABLE_SIZE +#define READ_STRING_TABLE_SIZE(INTO) \ +{ val = myread (desc, &INTO, sizeof INTO); \ + if (val < 0) perror_with_name (name); } +#endif +/* Macro to declare variables to hold the file's header data. */ +#ifndef DECLARE_FILE_HEADERS +#define DECLARE_FILE_HEADERS struct exec hdr +#endif + +/* Macro to read the header data from descriptor DESC and validate it. + NAME is the file name, for error messages. */ +#ifndef READ_FILE_HEADERS +#define READ_FILE_HEADERS(DESC, NAME) \ +{ val = myread (DESC, &hdr, sizeof hdr); \ + if (val < 0) perror_with_name (NAME); \ + if (N_BADMAG (hdr)) \ + error ("File \"%s\" not in executable format.", NAME); } +#endif + START_FILE /* Chain of symtabs made from reading the file's symsegs. @@ -102,14 +137,7 @@ static struct subfile *subfiles; static struct subfile *current_subfile; -/* The addresses of the symbol table stream and the string table - of the object file we are reading (as copied into core). */ - -static FILE *nlist_stream_global; -static int nlist_size_global; -static char *stringtab_global; - -/* The index in nlist_global of the last dbx symbol to be processed. */ +/* Count symbols as they are processed, for error messages. */ static int symnum; @@ -141,7 +169,7 @@ static int prev_line_number; static int line_vector_length; -/* Chain of global symbols whose values are not known yet. +/* Hash table of global symbols whose values are not known yet. They are chained thru the SYMBOL_VALUE, since we don't have the correct data for that slot yet. */ @@ -152,12 +180,18 @@ static struct symbol *global_sym_chain[HASHSIZE]; We don't create a struct block for the context until we know how long to make it. */ +#define PENDINGSIZE 100 + struct pending { struct pending *next; - struct symbol *symbol; + int nsyms; + struct symbol *symbol[PENDINGSIZE]; }; +/* List of free `struct pending' structures for reuse. */ +struct pending *free_pendings; + /* Here are the three lists that symbols are put on. */ struct pending *file_symbols; /* static at top level, and types */ @@ -166,12 +200,11 @@ struct pending *global_symbols; /* global functions and variables */ struct pending *local_symbols; /* everything local to lexical context */ -/* List of unclosed lexical contexts +/* Stack representing unclosed lexical contexts (that will become blocks, eventually). */ struct context_stack { - struct context_stack *next; struct pending *locals; struct pending_block *old_blocks; struct symbol *name; @@ -181,6 +214,13 @@ struct context_stack struct context_stack *context_stack; +/* Index of first unused entry in context stack. */ +int context_stack_depth; + +/* Currently allocated size of context stack. */ + +int context_stack_size; + /* Nonzero if within a function (so symbols should be local, if nothing says specifically). */ @@ -202,6 +242,53 @@ extern CORE_ADDR first_object_file_end; /* From blockframe.c */ /* File name symbols were loaded from. */ static char *symfile; + +static int +xxmalloc (n) +{ + int v = malloc (n); + if (v == 0) + abort (); + return v; +} + +/* Make a copy of the string at PTR with SIZE characters in the symbol obstack + (and add a null character at the end in the copy). + Returns the address of the copy. */ + +static char * +obsavestring (ptr, size) + char *ptr; + int size; +{ + register char *p = (char *) obstack_alloc (symbol_obstack, size + 1); + /* Open-coded bcopy--saves function call time. + These strings are usually short. */ + { + register char *p1 = ptr; + register char *p2 = p; + char *end = ptr + size; + while (p1 != end) + *p2++ = *p1++; + } + p[size] = 0; + return p; +} + +/* Concatenate strings S1, S2 and S3; return the new string. + Space is found in the symbol_obstack. */ + +static char * +obconcat (s1, s2, s3) + char *s1, *s2, *s3; +{ + register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1; + register char *val = (char *) obstack_alloc (symbol_obstack, len); + strcpy (val, s1); + strcat (val, s2); + strcat (val, s3); + return val; +} /* Support for Sun changes to dbx symbol format */ @@ -269,11 +356,11 @@ static void init_header_files () { n_allocated_header_files = 10; - header_files = (struct header_file *) xmalloc (10 * sizeof (struct header_file)); + header_files = (struct header_file *) xxmalloc (10 * sizeof (struct header_file)); n_header_files = 0; n_allocated_this_object_header_files = 10; - this_object_header_files = (int *) xmalloc (10 * sizeof (int)); + this_object_header_files = (int *) xxmalloc (10 * sizeof (int)); } /* At the end of reading dbx symbols, free our tables. */ @@ -396,7 +483,7 @@ add_new_header_file (name, instance) header_files[i].instance = instance; header_files[i].length = 10; header_files[i].vector - = (struct type **) xmalloc (10 * sizeof (struct type *)); + = (struct type **) xxmalloc (10 * sizeof (struct type *)); bzero (header_files[i].vector, 10 * sizeof (struct type *)); add_this_object_header_file (i); @@ -474,7 +561,6 @@ dbx_alloc_type (typenums) type = (struct type *) obstack_alloc (symbol_obstack, sizeof (struct type)); bzero (type, sizeof (struct type)); - TYPE_VPTR_FIELDNO (type) = -1; *type_addr = type; } return type; @@ -507,15 +593,64 @@ add_symbol_to_list (symbol, listhead) struct symbol *symbol; struct pending **listhead; { - register struct pending *link - = (struct pending *) xmalloc (sizeof (struct pending)); + /* We keep PENDINGSIZE symbols in each link of the list. + If we don't have a link with room in it, add a new link. */ + if (*listhead == 0 || (*listhead)->nsyms == PENDINGSIZE) + { + register struct pending *link; + if (free_pendings) + { + link = free_pendings; + free_pendings = link->next; + } + else + link = (struct pending *) xxmalloc (sizeof (struct pending)); - link->next = *listhead; - link->symbol = symbol; - *listhead = link; + link->next = *listhead; + *listhead = link; + link->nsyms = 0; + } + + (*listhead)->symbol[(*listhead)->nsyms++] = symbol; +} + +/* At end of reading syms, or in case of quit, + really free as many `struct pending's as we can easily find. */ + +static void +really_free_pendings () +{ + struct pending *next, *next1; + struct pending_block *bnext, *bnext1; + + for (next = free_pendings; next; next = next1) + { + next1 = next->next; + free (next); + } + free_pendings = 0; + + for (bnext = pending_blocks; bnext; bnext = bnext1) + { + bnext1 = bnext->next; + free (bnext); + } + pending_blocks = 0; + + for (next = file_symbols; next; next = next1) + { + next1 = next->next; + free (next); + } + for (next = global_symbols; next; next = next1) + { + next1 = next->next; + free (next); + } } /* Take one of the lists of symbols and make a block from it. + Keep the order the symbols have in the list (reversed from the input file). Put the block on the list of pending blocks. */ static void @@ -533,7 +668,7 @@ finish_block (symbol, listhead, old_blocks, start, end) /* Count the length of the list of symbols. */ - for (next = *listhead, i = 0; next; next = next->next, i++); + for (next = *listhead, i = 0; next; i += next->nsyms, next = next->next); block = (struct block *) obstack_alloc (symbol_obstack, sizeof (struct block) + (i - 1) * sizeof (struct symbol *)); @@ -542,7 +677,11 @@ finish_block (symbol, listhead, old_blocks, start, end) BLOCK_NSYMS (block) = i; for (next = *listhead; next; next = next->next) - BLOCK_SYM (block, --i) = next->symbol; + { + register int j; + for (j = next->nsyms - 1; j >= 0; j--) + BLOCK_SYM (block, --i) = next->symbol[j]; + } BLOCK_START (block) = start; BLOCK_END (block) = end; @@ -558,12 +697,13 @@ finish_block (symbol, listhead, old_blocks, start, end) else BLOCK_FUNCTION (block) = 0; - /* Now free the links of the list, and empty the list. */ + /* Now "free" the links of the list, and empty the list. */ for (next = *listhead; next; next = next1) { next1 = next->next; - free (next); + next->next = free_pendings; + free_pendings = next; } *listhead = 0; @@ -583,7 +723,10 @@ finish_block (symbol, listhead, old_blocks, start, end) Put it after opblock, or at the beginning if opblock is 0. This puts the block in the list after all its subblocks. */ - pblock = (struct pending_block *) xmalloc (sizeof (struct pending_block)); + /* Allocate in the symbol_obstack to save time. + It wastes a little space. */ + pblock = (struct pending_block *) obstack_alloc (symbol_obstack, + sizeof (struct pending_block)); pblock->block = block; if (opblock) { @@ -620,6 +763,7 @@ make_blockvector () for (next = pending_blocks; next; next = next->next) BLOCKVECTOR_BLOCK (blockvector, --i) = next->block; +#if 0 /* Now we make the links in the obstack, so don't free them. */ /* Now free the links of the list, and empty the list. */ for (next = pending_blocks; next; next = next1) @@ -627,6 +771,7 @@ make_blockvector () next1 = next->next; free (next); } +#endif pending_blocks = 0; return blockvector; @@ -680,9 +825,14 @@ start_symtab (name, start_addr) last_source_start_addr = start_addr; file_symbols = 0; global_symbols = 0; - context_stack = 0; within_function = 0; + /* Context stack is initially empty, with room for 10 levels. */ + context_stack + = (struct context_stack *) xxmalloc (10 * sizeof (struct context_stack)); + context_stack_size = 10; + context_stack_depth = 0; + new_object_header_files (); for (s = symseg_chain; s; s = s->next) @@ -693,7 +843,7 @@ start_symtab (name, start_addr) return; type_vector_length = 160; - type_vector = (struct typevector *) xmalloc (sizeof (struct typevector) + type_vector_length * sizeof (struct type *)); + type_vector = (struct typevector *) xxmalloc (sizeof (struct typevector) + type_vector_length * sizeof (struct type *)); bzero (type_vector->type, type_vector_length * sizeof (struct type *)); /* Initialize the list of sub source files with one entry @@ -745,12 +895,12 @@ start_subfile (name) line_vector_length = 1000; prev_line_number = -2; /* Force first line number to be explicit */ line_vector = (struct linetable *) - xmalloc (sizeof (struct linetable) + line_vector_length * sizeof (int)); + xxmalloc (sizeof (struct linetable) + line_vector_length * sizeof (int)); /* Make an entry for this subfile in the list of all subfiles of the current main source file. */ - subfile = (struct subfile *) xmalloc (sizeof (struct subfile)); + subfile = (struct subfile *) xxmalloc (sizeof (struct subfile)); subfile->next = subfiles; subfile->name = savestring (name, strlen (name)); subfile->line_vector = line_vector; @@ -770,7 +920,6 @@ end_symtab (end_addr) CORE_ADDR end_addr; { register struct symtab *symtab; - register struct context_stack *cstk; register struct blockvector *blockvector; register struct subfile *subfile; register struct linetable *lv; @@ -783,15 +932,17 @@ end_symtab (end_addr) return; } - /* Finish the lexical context of the last function in the file. */ + /* Finish the lexical context of the last function in the file; + pop the context stack. */ - if (context_stack) + if (context_stack_depth > 0) { - cstk = context_stack; + register struct context_stack *cstk; + context_stack_depth--; + cstk = &context_stack[context_stack_depth]; /* Make a block for the local symbols within. */ finish_block (cstk->name, &local_symbols, cstk->old_blocks, cstk->start_addr, end_addr); - free (cstk); } /* Finish defining all the blocks of this symtab. */ @@ -806,7 +957,7 @@ end_symtab (end_addr) for (subfile = subfiles; subfile; subfile = nextsub) { - symtab = (struct symtab *) xmalloc (sizeof (struct symtab)); + symtab = (struct symtab *) xxmalloc (sizeof (struct symtab)); symtab->free_ptr = 0; /* Fill in its components. */ @@ -860,7 +1011,7 @@ static void push_subfile () { register struct subfile_stack *tem - = (struct subfile_stack *) xmalloc (sizeof (struct subfile_stack)); + = (struct subfile_stack *) xxmalloc (sizeof (struct subfile_stack)); tem->next = subfile_stack; subfile_stack = tem; @@ -929,7 +1080,7 @@ record_misc_function (name, address) if (misc_bunch_index == MISC_BUNCH_SIZE) { - new = (struct misc_bunch *) xmalloc (sizeof (struct misc_bunch)); + new = (struct misc_bunch *) xxmalloc (sizeof (struct misc_bunch)); misc_bunch_index = 0; new->next = misc_bunch; misc_bunch = new; @@ -979,7 +1130,7 @@ condense_misc_bunches () misc_function_vector = (struct misc_function *) - xmalloc (misc_count * sizeof (struct misc_function)); + xxmalloc (misc_count * sizeof (struct misc_function)); j = 0; bunch = misc_bunch; @@ -989,9 +1140,9 @@ condense_misc_bunches () { misc_function_vector[j] = bunch->contents[i]; misc_function_vector[j].name - = concat (misc_function_vector[j].name - + (misc_function_vector[j].name[0] == '_' ? offset : 0), - "", ""); + = obconcat (misc_function_vector[j].name + + (misc_function_vector[j].name[0] == '_' ? offset : 0), + "", ""); j++; } bunch = bunch->next; @@ -1013,9 +1164,16 @@ 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)); + register int namediff; + + /* Compare the initial characters. */ + namediff = SYMBOL_NAME (*s1)[0] - SYMBOL_NAME (*s2)[0]; + if (namediff != 0) return namediff; + + /* If they match, compare the rest of the names. */ + 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)); @@ -1025,7 +1183,7 @@ static void sort_syms () { register struct symtab *s; - register int i, nbl; + int i, nbl; register struct blockvector *bv; register struct block *b; @@ -1036,8 +1194,21 @@ sort_syms () for (i = 0; i < nbl; i++) { b = BLOCKVECTOR_BLOCK (bv, i); - qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b), - sizeof (struct symbol *), compare_symbols); + if (BLOCK_SHOULD_SORT (b)) + qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b), + sizeof (struct symbol *), compare_symbols); + else + { + int lastindex = BLOCK_NSYMS (b) - 1; + register int j; + for (j = (lastindex - 1) / 2; j >= 0; j--) + { + register struct symbol *sym; + sym = BLOCK_SYM (b, j); + BLOCK_SYM (b, j) = BLOCK_SYM (b, lastindex - j); + BLOCK_SYM (b, lastindex - j) = sym; + } + } } } } @@ -1050,7 +1221,7 @@ symbol_file_command (name) char *name; { register int desc; - struct exec hdr; + DECLARE_FILE_HEADERS; struct nlist *nlist; char *stringtab; long buffer; @@ -1058,6 +1229,7 @@ symbol_file_command (name) extern void close (); struct cleanup *old_chain; struct symtab *symseg; + struct stat statbuf; dont_repeat (); @@ -1072,10 +1244,6 @@ symbol_file_command (name) if (symtab_list && !query ("Load new symbol table from \"%s\"? ", name)) error ("Not confirmed."); - if (symfile) - free (symfile); - symfile = 0; - { char *absolute_name; desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name); @@ -1088,17 +1256,15 @@ symbol_file_command (name) old_chain = make_cleanup (close, desc); make_cleanup (free_current_contents, &name); - val = myread (desc, &hdr, sizeof hdr); - if (val < 0) - perror_with_name (name); + READ_FILE_HEADERS (desc, name); - if (N_BADMAG (hdr)) - error ("File \"%s\" not in executable format.", name); - - if (hdr.a_syms == 0) + if (NUMBER_OF_SYMBOLS == 0) { + if (symfile) + free (symfile); + symfile = 0; free_all_symtabs (); - printf ("%s does not have a symbol-table.\n", name); + printf ("%s has no symbol-table; symbols discarded.\n", name); fflush (stdout); return; } @@ -1107,21 +1273,18 @@ symbol_file_command (name) fflush (stdout); /* Now read the string table, all at once. */ - val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0); - if (val < 0) - perror_with_name (name); - val = myread (desc, &buffer, sizeof buffer); + val = lseek (desc, STRING_TABLE_OFFSET, 0); if (val < 0) perror_with_name (name); - stringtab = (char *) alloca (buffer); + stat (name, &statbuf); + READ_STRING_TABLE_SIZE (buffer); + if (buffer >= 0 && buffer < statbuf.st_size) + stringtab = (char *) alloca (buffer); + else + stringtab = NULL; if (stringtab == NULL) - { - free_all_symtabs (); - printf("%s: symbol table too large for alloca: %d bytes.\n", name, - buffer); - fflush (stdout); - return; - } + error ("ridiculous string table size: %d bytes", name, buffer); + bcopy (&buffer, stringtab, sizeof buffer); val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer); if (val < 0) @@ -1129,8 +1292,14 @@ symbol_file_command (name) /* Throw away the old symbol table. */ + if (symfile) + free (symfile); + symfile = 0; free_all_symtabs (); + /* Empty the hash table of global syms looking for values. */ + bzero (global_sym_chain, sizeof global_sym_chain); + #ifdef READ_GDB_SYMSEGS /* That puts us at the symsegs. Read them. */ symseg_chain = read_symsegs (desc, name); @@ -1148,7 +1317,7 @@ symbol_file_command (name) int j; struct source *source = sv->source[i]; struct symtab *sp1 - = (struct symtab *) xmalloc (sizeof (struct symtab)); + = (struct symtab *) xxmalloc (sizeof (struct symtab)); bcopy (symseg, sp1, sizeof (struct symtab)); sp1->filename = savestring (source->name, strlen (source->name)); @@ -1168,7 +1337,7 @@ symbol_file_command (name) #endif /* Position to read the symbol table. Do not read it all at once. */ - val = lseek (desc, N_SYMOFF (hdr), 0); + val = lseek (desc, SYMBOL_TABLE_OFFSET, 0); if (val < 0) perror_with_name (name); @@ -1176,11 +1345,17 @@ symbol_file_command (name) make_cleanup (discard_misc_bunches, 0); init_header_files (); make_cleanup (free_header_files, 0); + free_pendings = 0; + pending_blocks = 0; + file_symbols = 0; + global_symbols = 0; + make_cleanup (really_free_pendings, 0); /* Now that the symbol table data of the executable file are all in core, process them and define symbols accordingly. Closes desc. */ - read_dbx_symtab (desc, stringtab, hdr.a_syms / sizeof (struct nlist)); + read_dbx_symtab (desc, stringtab, NUMBER_OF_SYMBOLS); + close (desc); /* Sort symbols alphabetically within each block. */ @@ -1223,6 +1398,49 @@ get_sym_file () return symfile; } +/* Buffer for reading the symbol table entries. */ +static struct nlist symbuf[2048]; +static int symbuf_idx; +static int symbuf_end; + +/* I/O descriptor for reading the symbol table. */ +static int symtab_input_desc; + +/* The address of the string table + of the object file we are reading (as copied into core). */ +static char *stringtab_global; + +/* Refill the symbol table input buffer + and set the variables that control fetching entries from it. + Reports an error if no data available. + This function can read past the end of the symbol table + (into the string table) but this does no harm. */ + +static int +fill_symbuf () +{ + int nbytes = myread (symtab_input_desc, symbuf, sizeof (symbuf)); + if (nbytes <= 0) + error ("error or end of file reading symbol table"); + symbuf_end = nbytes / sizeof (struct nlist); + symbuf_idx = 0; + return 1; +} + +/* dbx allows the text of a symbol name to be continued into the + next symbol name! When such a continuation is encountered + (a \ at the end of the text of a name) + call this function to get the continuation. */ + +static char * +next_symbol_text () +{ + if (symbuf_idx == symbuf_end) + fill_symbuf (); + symnum++; + return symbuf[symbuf_idx++].n_un.n_strx + stringtab_global; +} + /* Given pointers to a a.out symbol table in core containing dbx style data, analyze them and create struct symtab's describing the symbols. NLISTLEN is the number of symbols in the symbol table. @@ -1235,8 +1453,6 @@ read_dbx_symtab (desc, stringtab, nlistlen) register char *stringtab; register int nlistlen; { - FILE *stream = fdopen (desc, "r"); - struct nlist buf; register char *namestring; register struct symbol *sym, *prev; int hash; @@ -1248,49 +1464,70 @@ read_dbx_symtab (desc, stringtab, nlistlen) #endif old_chain = make_cleanup (free_all_symtabs, 0); - nlist_stream_global = stream; - nlist_size_global = nlistlen; stringtab_global = stringtab; last_source_file = 0; - bzero (global_sym_chain, sizeof global_sym_chain); + +#ifdef END_OF_TEXT_DEFAULT + end_of_text_addr = END_OF_TEXT_DEFAULT; +#endif + + symtab_input_desc = desc; + symbuf_end = symbuf_idx = 0; for (symnum = 0; symnum < nlistlen; symnum++) { + struct nlist *bufp; + int type; + QUIT; /* allow this to be interruptable */ - fread (&buf, sizeof buf, 1, stream); - namestring = buf.n_un.n_strx ? buf.n_un.n_strx + stringtab : ""; - if (buf.n_type & N_STAB) - process_one_symbol (buf.n_type, buf.n_desc, - buf.n_value, namestring); + if (symbuf_idx == symbuf_end) + fill_symbuf (); + bufp = &symbuf[symbuf_idx++]; + type = bufp->n_type; + namestring = bufp->n_un.n_strx ? bufp->n_un.n_strx + stringtab : ""; + + if (type & N_STAB) + process_one_symbol (type, bufp->n_desc, + bufp->n_value, namestring); /* A static text symbol whose name ends in ".o" - can only mean the start of another object file. + or begins with "-l" means the start of another object file. So end the symtab of the source file we have been processing. This is how we avoid counting the libraries as part or the last source file. Also this way we find end of first object file (crt0). */ - else if (buf.n_type == N_TEXT - && !strcmp (namestring + strlen (namestring) - 2, ".o")) + else if ( +#ifdef N_NBTEXT + (type == N_NBTEXT) +#else + (type == N_TEXT) +#endif + && (!strcmp (namestring + strlen (namestring) - 2, ".o") + || !strncmp (namestring, "-l", 2))) { if (num_object_files++ == 1) - first_object_file_end = buf.n_value; + first_object_file_end = bufp->n_value; if (last_source_file) - end_symtab (buf.n_value); + end_symtab (bufp->n_value); } - else if (buf.n_type & N_EXT || buf.n_type == N_TEXT) + else if (type & N_EXT || type == N_TEXT +#ifdef N_NBTEXT + || type == N_NBTEXT +#endif + ) { int used_up = 0; /* Record the location of _etext. */ - if (buf.n_type == (N_TEXT | N_EXT) + if (type == (N_TEXT | N_EXT) && !strcmp (namestring, "_etext")) - end_of_text_addr = buf.n_value; + end_of_text_addr = bufp->n_value; /* Global symbol: see if we came across a dbx definition for a corresponding symbol. If so, store the value. Remove syms from the chain when their values are stored, but search the whole chain, as there may be several syms from different files with the same name. */ - if (buf.n_type & N_EXT) + if (type & N_EXT) { prev = 0; #ifdef NAMES_HAVE_UNDERSCORE @@ -1319,7 +1556,7 @@ read_dbx_symtab (desc, stringtab, nlistlen) else global_sym_chain[hash] = (struct symbol *) SYMBOL_VALUE (sym); - SYMBOL_VALUE (sym) = buf.n_value; + SYMBOL_VALUE (sym) = bufp->n_value; if (prev) sym = (struct symbol *) SYMBOL_VALUE (prev); else @@ -1337,34 +1574,19 @@ read_dbx_symtab (desc, stringtab, nlistlen) /* Defined global or text symbol: record as a misc function if it didn't give its address to a debugger symbol above. */ - if (buf.n_type <= (N_TYPE | N_EXT) - && buf.n_type != N_EXT + if (type <= (N_TYPE | N_EXT) + && type != N_EXT && ! used_up) - record_misc_function (namestring, buf.n_value); + record_misc_function (namestring, bufp->n_value); } } if (last_source_file) end_symtab (end_of_text_addr); - fclose (stream); discard_cleanups (old_chain); } -/* dbx allows the text of a symbol name to be continued into the - next symbol name! When such a continuation is encountered - (a \ at the end of the text of a name) - call this function to get the continuation. */ - -static char * -next_symbol_text () -{ - struct nlist buf; - fread (&buf, sizeof buf, 1, nlist_stream_global); - symnum++; - return buf.n_un.n_strx + stringtab_global; -} - static int hashname (name) char *name; @@ -1382,7 +1604,9 @@ hashname (name) if (c) total += p[3] << 6; } - + + /* Ensure result is positive. */ + if (total < 0) total += (1000 << 6); return total % HASHSIZE; } @@ -1428,16 +1652,23 @@ process_one_symbol (type, desc, value, name) char *name; { register struct context_stack *new; - + /* Something is wrong if we see real data before seeing a source file name. */ - + + if (last_source_file == 0 && type != N_SO) + { #ifdef N_NSYMS - if (type == N_NSYMS) return; + /* This code is used on Ultrix; ignore this sym. */ + if (type == N_NSYMS) + return; #endif - if (type != N_SO && last_source_file == 0) - error ("Invalid symbol data: does not start by identifying a source file."); + if (type == N_ENTRY) + /* This code appears in libraries on Gould machines. */ + return; + error ("Invalid symbol data: does not start by identifying a source file."); + } switch (type) { @@ -1447,22 +1678,21 @@ process_one_symbol (type, desc, value, name) a new function. We must process its "name" normally for dbx, but also record the start of a new lexical context, and possibly also the end of the lexical context for the previous function. */ - new = context_stack; + within_function = 1; - if (new) + if (context_stack_depth > 0) { + new = &context_stack[--context_stack_depth]; /* Make a block for the local symbols within. */ finish_block (new->name, &local_symbols, new->old_blocks, new->start_addr, value); } - else - { - new = (struct context_stack *) xmalloc (sizeof (struct context_stack)); - new->next = 0; - new->depth = -1; - context_stack = new; - } - new->locals = 0; + /* Stack must be empty now. */ + if (context_stack_depth != 0) + error ("Invalid symbol data: unmatched N_LBRAC before symtab pos %d.", + symnum); + + new = &context_stack[context_stack_depth++]; new->old_blocks = pending_blocks; new->start_addr = value; new->name = define_symbol (value, name, desc); @@ -1472,10 +1702,18 @@ process_one_symbol (type, desc, value, name) case N_LBRAC: /* This "symbol" just indicates the start of an inner lexical context within a function. */ - new = (struct context_stack *) xmalloc (sizeof (struct context_stack)); + + if (context_stack_depth == context_stack_size) + { + context_stack_size *= 2; + context_stack + = (struct context_stack *) xrealloc (context_stack, + context_stack_size + * sizeof (struct context_stack)); + } + + new = &context_stack[context_stack_depth++]; new->depth = desc; - new->next = context_stack; - context_stack = new; new->locals = local_symbols; new->old_blocks = pending_blocks; new->start_addr = value; @@ -1486,11 +1724,11 @@ process_one_symbol (type, desc, value, name) case N_RBRAC: /* This "symbol" just indicates the end of an inner lexical context that was started with N_RBRAC. */ - new = context_stack; - if (new == 0 || desc != new->depth) + new = &context_stack[--context_stack_depth]; + if (desc != new->depth) error ("Invalid symbol data: N_LBRAC/N_RBRAC symbol mismatch, symtab pos %d.", symnum); local_symbols = new->locals; - context_stack = new->next; + /* If this is not the outermost LBRAC...RBRAC pair in the function, its local symbols preceded it, and are the ones just recovered from the context stack. Defined the block for them. @@ -1498,7 +1736,7 @@ process_one_symbol (type, desc, value, name) If this is the outermost LBRAC...RBRAC pair, there is no need to do anything; leave the symbols that preceded it to be attached to the function's own block. */ - if (local_symbols && context_stack->next) + if (local_symbols && context_stack_depth > 1) { /* Muzzle a compiler bug that makes end > start. */ if (new->start_addr > value) @@ -1508,7 +1746,6 @@ process_one_symbol (type, desc, value, name) new->start_addr + last_source_start_addr, value + last_source_start_addr); } - free (new); break; case N_FN: @@ -1557,313 +1794,18 @@ process_one_symbol (type, desc, value, name) record_line (desc, value); break; + case N_BCOMM: + case N_ECOMM: + case N_ECOML: + case N_LENG: + break; + default: if (name) define_symbol (value, name, desc); } } -/************************ READ_ADDL_SYM() ***********************************/ - -static void -read_addl_syms (desc, stringtab, nlistlen, text_addr, text_size) - int desc; - register char *stringtab; - register int nlistlen; - unsigned text_addr; - int text_size; -{ - FILE *stream = fdopen (desc, "r"); - struct nlist buf; - register char *namestring; - register struct symbol *sym, *prev; - int hash; - int num_object_files = 0; - -#ifdef N_BINCL - subfile_stack = 0; -#endif - - nlist_stream_global = stream; - nlist_size_global = nlistlen; - stringtab_global = stringtab; - last_source_file = 0; - bzero (global_sym_chain, sizeof global_sym_chain); - - for (symnum = 0; symnum < nlistlen; symnum++) - { - unsigned type; - - fread (&buf, sizeof buf, 1, stream); - - type = buf.n_type & N_TYPE; - if( (type == N_TEXT) || (type == N_DATA) || (type == N_BSS) ) - { - buf.n_value += text_addr; - } /* Right?? ###### */ - - - namestring = buf.n_un.n_strx ? buf.n_un.n_strx + stringtab : ""; - if (buf.n_type & N_STAB) - process_one_symbol (buf.n_type, buf.n_desc, - buf.n_value, namestring); - /* A static text symbol whose name ends in ".o" - can only mean the start of another object file. - So end the symtab of the source file we have been processing. - This is how we avoid counting the libraries as part - or the last source file. - Also this way we find end of first object file (crt0). */ - else if (buf.n_type == N_TEXT - && !strcmp (namestring + strlen (namestring) - 2, ".o")) - { - if (num_object_files++ == 1) - first_object_file_end = buf.n_value; - if (last_source_file) - { - end_symtab (buf.n_value); /* All this not used##### */ - } - } - else if (buf.n_type & N_EXT || buf.n_type == N_TEXT) - { - int used_up = 0; - - /* Record the location of _etext. */ - if (buf.n_type == (N_TEXT | N_EXT) - && !strcmp (namestring, "_etext")) - { - end_of_text_addr = buf.n_value; - } - - /* Global symbol: see if we came across a dbx definition - for a corresponding symbol. If so, store the value. - Remove syms from the chain when their values are stored, - but search the whole chain, as there may be several syms - from different files with the same name. */ - if (buf.n_type & N_EXT) - { - prev = 0; -#ifdef NAMES_HAVE_UNDERSCORE - hash = hashname (namestring + 1); -#else /* not NAMES_HAVE_UNDERSCORE */ - hash = hashname (namestring); -#endif /* not NAMES_HAVE_UNDERSCORE */ - for (sym = global_sym_chain[hash]; - sym;) - { - if ( -#ifdef NAMES_HAVE_UNDERSCORE - *namestring == '_' - && namestring[1] == SYMBOL_NAME (sym)[0] - && - !strcmp (namestring + 2, SYMBOL_NAME (sym) + 1) -#else /* NAMES_HAVE_UNDERSCORE */ - namestring[0] == SYMBOL_NAME (sym)[0] - && - !strcmp (namestring + 1, SYMBOL_NAME (sym) + 1) -#endif /* NAMES_HAVE_UNDERSCORE */ - ) - { - if (prev) - SYMBOL_VALUE (prev) = SYMBOL_VALUE (sym); - else - global_sym_chain[hash] - = (struct symbol *) SYMBOL_VALUE (sym); - SYMBOL_VALUE (sym) = buf.n_value; - if (prev) - sym = (struct symbol *) SYMBOL_VALUE (prev); - else - sym = global_sym_chain[hash]; - - used_up = 1; - } - else - { - prev = sym; - sym = (struct symbol *) SYMBOL_VALUE (sym); - } - } - } - - /* Defined global or text symbol: record as a misc function - if it didn't give its address to a debugger symbol above. */ - if (buf.n_type <= (N_TYPE | N_EXT) - && buf.n_type != N_EXT - && ! used_up) - record_misc_function (namestring, buf.n_value); - } - } - - if (last_source_file) - { - end_symtab (text_addr + text_size); - } - - fclose (stream); -} - -/***************************** CONDENSE_ADDL_MISC_BUNCHES *******************/ - -static void -condense_addl_misc_bunches () -{ - register int i, j; - register struct misc_bunch *bunch; -#ifdef NAMES_HAVE_UNDERSCORE - int offset = 1; -#else - int offset = 0; -#endif - - misc_function_vector - = (struct misc_function *) xrealloc (misc_function_vector, - (misc_count + misc_function_count) * sizeof (struct misc_function)); - - j = misc_function_count; - bunch = misc_bunch; - while (bunch) - { - for (i = 0; i < misc_bunch_index; i++) - { - misc_function_vector[j] = bunch->contents[i]; - misc_function_vector[j].name - = concat (misc_function_vector[j].name - + (misc_function_vector[j].name[0] == '_' ? offset : 0), - "", ""); - j++; - } - bunch = bunch->next; - misc_bunch_index = MISC_BUNCH_SIZE; - } - - misc_function_count += misc_count; - - /* Sort the misc functions by address. */ - - qsort (misc_function_vector, misc_function_count, - sizeof (struct misc_function), compare_misc_functions); -} - -/**************************** ADD_FILE_COMMAND() ****************************/ -/* This function allows the addition of incrementally linked object files. */ - -void -add_file_command (arg_string) - char* arg_string; -{ - register int desc; - struct exec hdr; - struct nlist *nlist; - char *stringtab; - long buffer; - register int val; - extern void close (); - struct cleanup *old_chain; - char* name; - unsigned text_addr; - - if (arg_string == 0) - error ("add-file takes a file name and an address"); - - for( ; *arg_string == ' '; arg_string++ ); - name = arg_string; - for( ; *arg_string && *arg_string != ' ' ; arg_string++ ); - *arg_string++ = (char) 0; - - if (name[0] == 0) - error ("add-file takes a file name and an address"); - - text_addr = parse_and_eval_address (arg_string); - - dont_repeat (); - - if (query ("add symbol table from filename \"%s\" at text_addr = 0x%x\n", name, text_addr)) - { - desc = open (name, O_RDONLY); - if (desc < 0) - perror_with_name (name); - - old_chain = make_cleanup (close, desc); - make_cleanup (free_current_contents, &name); - - val = myread (desc, &hdr, sizeof hdr); - if (val < 0) - perror_with_name (name); - - if (N_BADMAG (hdr)) - error ("File \"%s\" has a bad header.", name); - - if (hdr.a_syms == 0) - { - printf ("%s does not have a symbol-table.\n", name); - fflush (stdout); - return; - } - - /* Now read the string table, all at once. */ - val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0); - if (val < 0) - perror_with_name (name); - val = myread (desc, &buffer, sizeof buffer); - if (val < 0) - perror_with_name (name); - stringtab = (char *) alloca (buffer); - bcopy (&buffer, stringtab, sizeof buffer); - val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer); - if (val < 0) - perror_with_name (name); - - /* That puts us at the symsegs. Read them. ########## Also need other - changes if they exist. */ - - /* Position to read the symbol table. Do not read it all at once. */ - val = lseek (desc, N_SYMOFF (hdr), 0); - if (val < 0) - perror_with_name (name); - - printf ("Reading symbol data from %s...", name); - fflush (stdout); - - init_misc_functions (); - make_cleanup (discard_misc_bunches, 0); - init_header_files (); - make_cleanup (free_header_files, 0); - - read_addl_syms (desc, stringtab, hdr.a_syms / sizeof(struct nlist), - text_addr, hdr.a_text) ; - - /* Sort symbols alphabetically within each block. */ - - sort_syms (); - - /* Go over the all misc functions and install them in vector. */ - - condense_addl_misc_bunches (); - - /* Don't allow char * to have a typename (else would get caddr_t.) */ - - TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0; - - /* Make a default for file to list. */ - - select_source_symtab (symtab_list); - - do_cleanups (old_chain); - - /* Free the symtabs made by read_symsegs, but not their contents, - which have been copied into symtabs on symtab_list. */ - while (symseg_chain) - { - register struct symtab *s = symseg_chain->next; - free (symseg_chain); - symseg_chain = s; - } - - printf ("done.\n"); - fflush (stdout); - } - else error ("Not confirmed."); -} - static struct symbol * define_symbol (value, string, desc) int value; @@ -1876,8 +1818,20 @@ define_symbol (value, string, desc) int deftype; register int i; - bzero (sym, sizeof (struct symbol)); - SYMBOL_NAME (sym) = obstack_copy0 (symbol_obstack, string, p - string); + /* Ignore syms with empty names. */ + if (string[0] == 0) + return 0; + + SYMBOL_NAME (sym) + = (char *) obstack_alloc (symbol_obstack, ((p - string) + 1)); + /* Open-coded bcopy--saves function call time. */ + { + register char *p1 = string; + register char *p2 = SYMBOL_NAME (sym); + while (p1 != p) + *p2++ = *p1++; + *p2++ = '\0'; + } p++; /* Determine the type of name being defined. */ if ((*p >= '0' && *p <= '9') || *p == '(') @@ -1935,7 +1889,15 @@ define_symbol (value, string, desc) = lookup_pointer_type (lookup_function_type (read_type (&p))); } else - SYMBOL_TYPE (sym) = read_type (&p); + { + struct type *type = read_type (&p); + + if ((deftype == 'F' || deftype == 'f') + && TYPE_CODE (type) != TYPE_CODE_FUNC) + SYMBOL_TYPE (sym) = lookup_function_type (type); + else + SYMBOL_TYPE (sym) = type; + } switch (deftype) { @@ -2014,17 +1976,9 @@ define_symbol (value, string, desc) SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0 && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0) - TYPE_NAME (SYMBOL_TYPE (sym)) = concat (SYMBOL_NAME (sym), "", ""); - /* C++ vagaries: we may have a type which is derived from - a base type which did not have its name defined when the - derived class was output. We fill in the derived class's - base part member's name here in that case. */ - else if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT - || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION) - && TYPE_BASECLASS (SYMBOL_TYPE (sym)) - && TYPE_FIELD_NAME (SYMBOL_TYPE (sym), 0) == 0) - TYPE_FIELD_NAME (SYMBOL_TYPE (sym), 0) = TYPE_NAME (TYPE_BASECLASS (SYMBOL_TYPE (sym))); - + TYPE_NAME (SYMBOL_TYPE (sym)) = + obsavestring (SYMBOL_NAME (sym), + strlen (SYMBOL_NAME (sym))); add_symbol_to_list (sym, &file_symbols); break; @@ -2035,12 +1989,12 @@ define_symbol (value, string, desc) if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0 && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0) TYPE_NAME (SYMBOL_TYPE (sym)) - = concat ("", - (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM - ? "enum " - : (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT - ? "struct " : "union ")), - SYMBOL_NAME (sym)); + = obconcat ("", + (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM + ? "enum " + : (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT + ? "struct " : "union ")), + SYMBOL_NAME (sym)); add_symbol_to_list (sym, &file_symbols); break; @@ -2128,10 +2082,6 @@ read_type (pp) break; } /* Skip the name the cross-ref points to. */ - /* Note: for C++, the cross reference may be to a base type which - has not yet been seen. In this case, we skip to the comma, - which will mark the end of the base class name. (The ':' - at the end of the base class name will be skipped as well.) */ *pp = (char *) index (*pp, ','); /* Just allocate the type and leave it zero if nothing known */ return dbx_alloc_type (typenums); @@ -2160,27 +2110,6 @@ read_type (pp) smash_to_pointer_type (type, read_type (pp)); break; - case '@': - { - struct type *domain = read_type (pp); - char c; - struct type *memtype; - - if (*(*pp)++ != ',') - error ("invalid member type data format, at symtab pos %d.", - symnum); - - memtype = read_type (pp); - type = dbx_alloc_type (typenums); - smash_to_member_type (type, domain, memtype); - } - break; - - case '&': - type = dbx_alloc_type (typenums); - smash_to_reference_type (type, read_type (pp)); - break; - case 'f': type = dbx_alloc_type (typenums); smash_to_function_type (type, read_type (pp)); @@ -2274,23 +2203,9 @@ read_struct_type (pp, type) struct nextfield { struct nextfield *next; - int visibility; struct field field; }; - struct next_fnfield - { - struct next_fnfield *next; - int visibility; - struct fn_field fn_field; - }; - - struct next_fnfieldlist - { - struct next_fnfieldlist *next; - struct fn_fieldlist fn_fieldlist; - }; - register struct nextfield *list = 0; struct nextfield *new; int totalsize; @@ -2299,72 +2214,20 @@ read_struct_type (pp, type) int nfields = 0; register int n; - register struct next_fnfieldlist *mainlist = 0; - int nfn_fields = 0; - struct type *baseclass = NULL; - int read_possible_virtual_info = 0; - TYPE_CODE (type) = TYPE_CODE_STRUCT; /* First comes the total size in bytes. */ TYPE_LENGTH (type) = read_number (pp, 0); - /* C++: Now, if the class is a derived class, then the next character - will be a '!', followed by the type of the base class. Allocate - pretend that that base class is a sub-structure of this one, - with its field name being the type name of the derived class. This - cannot cause a naming conflict, since field names cannot be - type names. This will magically recurse itself to gound terms - when all is read and done. */ - if (**pp == '!') - { - *pp += 1; - - switch (*(*pp)++) - { - case '0': - break; - case '1': - TYPE_VIA_PROTECTED (type) = 1; - break; - case '2': - TYPE_VIA_PUBLIC (type) = 1; - break; - default: - error ("Invalid symbol data: bad visibility format at symtab pos %d.", - symnum); - } - - if (**pp == '\\') *pp = next_symbol_text (); - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - baseclass = read_type (pp); - list->field.type = baseclass; - list->field.name = TYPE_NAME (baseclass); - *pp += 1; /* skip ',' */ - list->field.bitpos = 0; - list->field.bitsize = 0; /* this should be an unpacked field! */ - nfields++; - } - - /* Now come the fields, as NAME:?TYPENUM,BITPOS,BITSIZE; for each one. - At the end, we see a semicolon instead of a field. - - In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for - a static field. - - The `?' is a placeholder for one of '+' (public visibility), - '0' (protected visibility), and '-' (private visibility). */ + /* Now come the fields, as NAME:TYPENUM,BITPOS,BITSIZE; for each one. + At the end, we see a semicolon instead of a field. */ while (**pp != ';') { - int visibility; - /* Check for and handle cretinous dbx symbol name continuation! */ - if (**pp == '\\') *pp = next_symbol_text (); + if (**pp == '\\') + *pp = next_symbol_text (); /* Get space to record the next field's data. */ new = (struct nextfield *) alloca (sizeof (struct nextfield)); @@ -2374,49 +2237,10 @@ read_struct_type (pp, type) /* Read the data. */ p = *pp; while (*p != ':') p++; - list->field.name = savestring (*pp, p - *pp); - - /* Check to see if we have hit the methods yet. */ - if (p[1] == ':') - break; - + list->field.name = obsavestring (*pp, p - *pp); *pp = p + 1; - - /* This means we have a visibility for a field coming. */ - if (**pp == '/') - { - switch (*++*pp) - { - case '0': - visibility = 0; - *pp += 1; - break; - - case '1': - visibility = 1; - *pp += 1; - break; - - case '2': - visibility = 2; - *pp += 1; - break; - } - } - /* else normal dbx-style format. */ - list->field.type = read_type (pp); - if (**pp == ':') - { - list->field.bitpos = (long)-1; - p = ++(*pp); - while (*p != ';') p++; - list->field.bitsize = (long) savestring (*pp, p - *pp); - *pp = p + 1; - nfields++; - continue; - } - else if (**pp != ',') + if (**pp != ',') error ("Invalid symbol data: bad structure-type format at symtab pos %d.", symnum); (*pp)++; /* Skip the comma. */ @@ -2424,11 +2248,12 @@ read_struct_type (pp, type) list->field.bitsize = read_number (pp, ';'); /* Detect an unpacked field and mark it as such. dbx gives a bit size for all fields. - Also detect forward refs to structures and unions, + Note that forward refs cannot be packed, and treat enums as if they had the width of ints. */ + if (TYPE_CODE (list->field.type) != TYPE_CODE_INT + && TYPE_CODE (list->field.type) != TYPE_CODE_ENUM) + list->field.bitsize = 0; if ((list->field.bitsize == 8 * TYPE_LENGTH (list->field.type) - || TYPE_CODE (list->field.type) == TYPE_CODE_STRUCT - || TYPE_CODE (list->field.type) == TYPE_CODE_UNION || (TYPE_CODE (list->field.type) == TYPE_CODE_ENUM && list->field.bitsize == 8 * TYPE_LENGTH (builtin_type_int))) && @@ -2437,218 +2262,18 @@ read_struct_type (pp, type) nfields++; } - /* Now come the method fields, as NAME::methods - where each method is of the form TYPENUM,ARGS,...:PHYSNAME; - At the end, we see a semicolon instead of a field. - - For the case of overloaded operators, the format is - OPERATOR::*.methods, where OPERATOR is the string "operator", - `*' holds the place for an operator name (such as `+=') - and `.' marks the end of the operator name. */ - if (p[1] == ':') - { - /* Now, read in the methods. To simplify matters, we - "unread" the name that has been read, so that we can - start from the top. */ - - p = *pp; - - /* chill the list of fields: the last entry (at the head) - is a partially constructed entry which we now scrub. */ - list = list->next; - - /* For each list of method lists... */ - do - { - int i; - struct next_fnfield *sublist = 0; - struct fn_field *fn_fields = 0; - int length = 0; - struct next_fnfieldlist *new_mainlist = - (struct next_fnfieldlist *)alloca (sizeof (struct next_fnfieldlist)); - - /* read in the name. */ - while (*p != ':') p++; - if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && (*pp)[2] == '$') - { - static char opname[32] = "operator "; - char *o = opname + 9; - - /* Skip past '::'. */ - p += 2; - while (*p != '.') - *o++ = *p++; - new_mainlist->fn_fieldlist.name = savestring (opname, o - opname); - /* Skip past '.' */ - *pp = p + 1; - } - else - { - i = 0; - new_mainlist->fn_fieldlist.name = savestring (*pp, p - *pp); - /* Skip past '::'. */ - *pp = p + 2; - } - - do - { - struct next_fnfield *new_sublist = - (struct next_fnfield *)alloca (sizeof (struct next_fnfield)); - - /* Check for and handle cretinous dbx symbol name continuation! */ - if (**pp == '\\') *pp = next_symbol_text (); - - new_sublist->fn_field.type = read_type (pp); - new_sublist->fn_field.args = read_args (pp, ':'); - p = *pp; - while (*p != ';') p++; - new_sublist->fn_field.physname = savestring (*pp, p - *pp); - *pp = p + 1; - new_sublist->visibility = *(*pp)++ - '0'; - if (**pp == '\\') *pp = next_symbol_text (); - - if (*(*pp)++ == '*') - new_sublist->fn_field.voffset = read_number (pp, ';') + 1; - else - new_sublist->fn_field.voffset = 0; - - new_sublist->next = sublist; - sublist = new_sublist; - length++; - } - while (**pp != ';'); - - *pp += 1; - - new_mainlist->fn_fieldlist.fn_fields = - (struct fn_field *) obstack_alloc (symbol_obstack, - sizeof (struct fn_field) * length); - TYPE_FN_PRIVATE_BITS (new_mainlist->fn_fieldlist) = - (int *) obstack_alloc (symbol_obstack, - sizeof (int) * (1 + (length >> 5))); - - TYPE_FN_PROTECTED_BITS (new_mainlist->fn_fieldlist) = - (int *) obstack_alloc (symbol_obstack, - sizeof (int) * (1 + (length >> 5))); - - for (i = length; sublist; sublist = sublist->next) - { - new_mainlist->fn_fieldlist.fn_fields[--i] = sublist->fn_field; - if (sublist->visibility == 0) - B_SET (new_mainlist->fn_fieldlist.private_fn_field_bits, i); - else if (sublist->visibility == 1) - B_SET (new_mainlist->fn_fieldlist.protected_fn_field_bits, i); - } - - new_mainlist->fn_fieldlist.length = length; - new_mainlist->next = mainlist; - mainlist = new_mainlist; - nfn_fields++; - } - while (**pp != ';'); - - *pp += 2; - - if (**pp == '~') - { - read_possible_virtual_info = 1; - *pp += 1; - } - if (**pp == '-') - { - TYPE_HAS_DESTRUCTOR (type) = 1; - TYPE_HAS_CONSTRUCTOR (type) = 1; - *pp += 1; - } - else if (**pp == '+') - { - TYPE_HAS_CONSTRUCTOR (type) = 1; - *pp += 1; - } - } - else *pp += 1; + (*pp)++; /* Skip the terminating ';'. */ /* Now create the vector of fields, and record how big it is. */ TYPE_NFIELDS (type) = nfields; TYPE_FIELDS (type) = (struct field *) obstack_alloc (symbol_obstack, sizeof (struct field) * nfields); - TYPE_FIELD_PRIVATE_BITS (type) = - (int *) obstack_alloc (symbol_obstack, - sizeof (int) * (1 + (nfields >> 5))); - TYPE_FIELD_PROTECTED_BITS (type) = - (int *) obstack_alloc (symbol_obstack, - sizeof (int) * (1 + (nfields >> 5))); - - TYPE_NFN_FIELDS (type) = nfn_fields; - TYPE_NFN_FIELDS_TOTAL (type) = nfn_fields; - if (baseclass) - TYPE_NFN_FIELDS_TOTAL (type) += TYPE_NFN_FIELDS_TOTAL (baseclass); - - TYPE_FN_FIELDLISTS (type) = - (struct fn_fieldlist *) obstack_alloc (symbol_obstack, - sizeof (struct fn_fieldlist) * nfn_fields); /* Copy the saved-up fields into the field vector. */ for (n = nfields; list; list = list->next) - { - TYPE_FIELD (type, --n) = list->field; - if (list->visibility == 0) - SET_TYPE_FIELD_PRIVATE (type, n); - else if (list->visibility == 1) - SET_TYPE_FIELD_PROTECTED (type, n); - } - - for (n = nfn_fields; mainlist; mainlist = mainlist->next) - TYPE_FN_FIELDLISTS (type)[--n] = mainlist->fn_fieldlist; - - TYPE_BASECLASS (type) = baseclass; - - if (read_possible_virtual_info) - { - /* Read either a '%' or the final ';'. */ - if (*(*pp)++ == '%') - { - /* Now we must record the virtual function table pointer's - field information. */ - - struct type *t; - int i; - - t = read_type (pp); - p = (*pp)++; - while (*p != ';') p++; - TYPE_VPTR_BASETYPE (type) = t; - if (type == t) - { - if (TYPE_FIELD_NAME (t, 0) == 0) - TYPE_VPTR_FIELDNO (type) = i = 0; - else for (i = TYPE_NFIELDS (t) - 1; i >= 0; --i) - if (! strncmp (TYPE_FIELD_NAME (t, i), *pp, - strlen (TYPE_FIELD_NAME (t, i)))) - { - TYPE_VPTR_FIELDNO (type) = i; - break; - } - if (i < 0) - error ("virtual function table field not found"); - } - else - TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type)); - *pp = p; - } - else - { - TYPE_VPTR_BASETYPE (type) = 0; - TYPE_VPTR_FIELDNO (type) = -1; - } - } - else - { - TYPE_VPTR_BASETYPE (type) = 0; - TYPE_VPTR_FIELDNO (type) = -1; - } + TYPE_FIELD (type, --n) = list->field; return type; } @@ -2669,12 +2294,14 @@ read_enum_type (pp, type) int nsyms = 0; struct pending **symlist; struct pending *osyms, *syms; + int o_nsyms; if (within_function) symlist = &local_symbols; else symlist = &file_symbols; osyms = *symlist; + o_nsyms = osyms ? osyms->nsyms : 0; /* Read the value-names and their values. The input syntax is NAME:VALUE,NAME:VALUE, and so on. @@ -2682,15 +2309,16 @@ read_enum_type (pp, type) while (**pp && **pp != ';') { /* Check for and handle cretinous dbx symbol name continuation! */ - if (**pp == '\\') *pp = next_symbol_text (); + if (**pp == '\\') + *pp = next_symbol_text (); p = *pp; while (*p != ':') p++; - name = savestring (*pp, p - *pp); + name = obsavestring (*pp, p - *pp); *pp = p + 1; n = read_number (pp, ','); - sym = (struct symbol *) xmalloc (sizeof (struct symbol)); + sym = (struct symbol *) obstack_alloc (symbol_obstack, sizeof (struct symbol)); bzero (sym, sizeof (struct symbol)); SYMBOL_NAME (sym) = name; SYMBOL_CLASS (sym) = LOC_CONST; @@ -2714,13 +2342,22 @@ read_enum_type (pp, type) to cause them to be defined. osyms contains the old value of that symlist; everything up to there was defined by us. */ - for (syms = *symlist, n = nsyms; syms != osyms; syms = syms->next) + for (syms = *symlist, n = nsyms; syms; syms = syms->next) { - SYMBOL_TYPE (syms->symbol) = type; - TYPE_FIELD_NAME (type, --n) = SYMBOL_NAME (syms->symbol); - TYPE_FIELD_VALUE (type, n) = SYMBOL_VALUE (syms->symbol); - TYPE_FIELD_BITPOS (type, n) = 0; - TYPE_FIELD_BITSIZE (type, n) = 0; + int j = 0; + if (syms == osyms) + j = o_nsyms; + for (; j < syms->nsyms; j++) + { + struct symbol *sym = syms->symbol[j]; + SYMBOL_TYPE (sym) = type; + TYPE_FIELD_NAME (type, --n) = SYMBOL_NAME (sym); + TYPE_FIELD_VALUE (type, n) = SYMBOL_VALUE (sym); + TYPE_FIELD_BITPOS (type, n) = 0; + TYPE_FIELD_BITSIZE (type, n) = 0; + } + if (syms == osyms) + break; } return type; @@ -2855,53 +2492,6 @@ read_number (pp, end) return n * sign; } -/* Read in an argument list. This is a list of types. It is terminated with - a ':', FYI. Return the list of types read in. */ -static struct type ** -read_args (pp, end) - char **pp; - int end; -{ - struct type *types[1024], **rval; /* allow for fns of 1023 parameters */ - int n = 0; - - while (**pp != end) - { - if (**pp != ',') - error ("Invalid argument list: no ',', at symtab pos %d", symnum); - *pp += 1; - types[n++] = read_type (pp); - } - *pp += 1; /* get past `end' (the ':' character) */ - - if (n == 1) - { - rval = (struct type **) xmalloc (2 * sizeof (struct type *)); - } - else if (TYPE_CODE (types[n-1]) != TYPE_CODE_VOID) - { - rval = (struct type **) xmalloc ((n + 1) * sizeof (struct type *)); - bzero (rval + n, sizeof (struct type *)); - } - else - { - rval = (struct type **) xmalloc (n * sizeof (struct type *)); - } - bcopy (types, rval, n * sizeof (struct type *)); - return rval; -} - -/* This function is really horrible, but to avoid it, there would need - to be more filling in of forward references. */ -int -fill_in_vptr_fieldno (type) - struct type *type; -{ - if (TYPE_VPTR_FIELDNO (type) < 0) - TYPE_VPTR_FIELDNO (type) = fill_in_vptr_fieldno (TYPE_BASECLASS (type)); - return TYPE_VPTR_FIELDNO (type); -} - static initialize () { @@ -2909,9 +2499,6 @@ initialize () add_com ("symbol-file", class_files, symbol_file_command, "Load symbol table (in dbx format) from executable file FILE."); - - add_com ("add-file", class_files, add_file_command, - "Load the symbols from FILE, assuming its codes is at TEXT_START.") ; } END_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[]; @@ -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: diff --git a/gdb/expprint.c b/gdb/expprint.c index 02a1ed3..b7adc29 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -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; diff --git a/gdb/expread.tab.c b/gdb/expread.tab.c deleted file mode 100644 index 8974bd5..0000000 --- a/gdb/expread.tab.c +++ /dev/null @@ -1,2152 +0,0 @@ - -/* A Bison parser, made from expread.y */ - -#define INT 258 -#define CHAR 259 -#define FLOAT 260 -#define NAME 261 -#define TYPENAME 262 -#define STRING 263 -#define STRUCT 264 -#define UNION 265 -#define ENUM 266 -#define SIZEOF 267 -#define UNSIGNED 268 -#define COLONCOLON 269 -#define LAST 270 -#define REGNAME 271 -#define VARIABLE 272 -#define ASSIGN_MODIFY 273 -#define THIS 274 -#define ABOVE_COMMA 275 -#define OR 276 -#define AND 277 -#define EQUAL 278 -#define NOTEQUAL 279 -#define LEQ 280 -#define GEQ 281 -#define LSH 282 -#define RSH 283 -#define UNARY 284 -#define INCREMENT 285 -#define DECREMENT 286 -#define ARROW 287 - -#line 30 "expread.y" - -#include "defs.h" -#include "param.h" -#include "symtab.h" -#include "frame.h" -#include "expression.h" - -#include <stdio.h> - -static struct expression *expout; -static int expout_size; -static int expout_ptr; - -static int yylex (); -static yyerror (); -static void write_exp_elt (); -static void write_exp_string (); -static void start_arglist (); -static int end_arglist (); -static void free_funcalls (); -static char *copy_name (); - -/* If this is nonzero, this block is used as the lexical context - for symbol names. */ - -static struct block *expression_context_block; - -/* Number of arguments seen so far in innermost function call. */ -static int arglist_len; - -/* Data structure for saving values of arglist_len - for function calls whose arguments contain other function calls. */ - -struct funcall - { - struct funcall *next; - int arglist_len; - }; - -struct funcall *funcall_chain; - -/* This kind of datum is used to represent the name - of a symbol token. */ - -struct stoken - { - char *ptr; - int length; - }; - -#line 85 "expread.y" -typedef union - { - long lval; - double dval; - struct symbol *sym; - struct type *tval; - struct stoken sval; - int voidval; - struct block *bval; - enum exp_opcode opcode; - struct internalvar *ivar; - - struct type **tvec; - int *ivec; - } YYSTYPE; - -#ifndef YYLTYPE -typedef - struct yyltype - { - int timestamp; - int first_line; - int first_column; - int last_line; - int last_column; - char *text; - } - yyltype; - -#define YYLTYPE yyltype -#endif - -#define YYACCEPT return(0) -#define YYABORT return(1) -#define YYERROR return(1) -#include <stdio.h> - -#ifndef __STDC__ -#define const -#endif - - - -#define YYFINAL 152 -#define YYFLAG -32768 -#define YYNTBASE 57 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 287 ? yytranslate[x] : 68) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 48, 2, 2, 2, 40, 27, 2, 51, - 52, 38, 36, 20, 37, 46, 39, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 56, 2, 30, - 22, 31, 55, 41, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 47, 2, 50, 26, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 53, 25, 54, 49, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 21, 23, 24, 28, 29, 32, - 33, 34, 35, 42, 43, 44, 45 -}; - -static const short yyrline[] = { 0, - 152, 156, 157, 162, 165, 168, 172, 176, 180, 184, - 188, 192, 196, 200, 206, 210, 216, 220, 224, 228, - 234, 237, 241, 245, 251, 257, 263, 267, 271, 275, - 279, 283, 287, 291, 295, 299, 303, 307, 311, 315, - 319, 323, 327, 331, 335, 339, 343, 347, 353, 360, - 367, 374, 377, 383, 389, 395, 402, 409, 416, 437, - 448, 461, 474, 510, 575, 576, 578, 580, 582, 584, - 586, 592, 595, 598, 601, 604, 609, 614, 621, 622 -}; - -static const char * const yytname[] = { 0, -"error","$illegal.","INT","CHAR","FLOAT","NAME","TYPENAME","STRING","STRUCT","UNION", -"ENUM","SIZEOF","UNSIGNED","COLONCOLON","LAST","REGNAME","VARIABLE","ASSIGN_MODIFY","THIS","','", -"ABOVE_COMMA","'='","OR","AND","'|'","'^'","'&'","EQUAL","NOTEQUAL","'<'", -"'>'","LEQ","GEQ","LSH","RSH","'+'","'-'","'*'","'/'","'%'", -"'@'","UNARY","INCREMENT","DECREMENT","ARROW","'.'","'['","'!'","'~'","']'", -"'('","')'","'{'","'}'","'?'","':'","start" -}; - -static const short yyr1[] = { 0, - 57, 58, 58, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 60, 59, - 61, 61, 61, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 62, 62, - 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, - 64, 65, 65, 65, 65, 65, 66, 66, 67, 67 -}; - -static const short yyr2[] = { 0, - 1, 1, 3, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 4, 3, 4, 4, 0, 5, - 0, 1, 3, 4, 4, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 5, 3, 3, 1, 1, - 1, 1, 1, 1, 1, 4, 1, 1, 1, 3, - 3, 3, 2, 1, 1, 2, 2, 3, 6, 8, - 9, 1, 2, 2, 2, 2, 1, 3, 1, 1 -}; - -static const short yydefact[] = { 0, - 49, 50, 51, 64, 72, 57, 0, 0, 0, 0, - 0, 0, 53, 54, 55, 58, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 2, 0, 52, 0, - 59, 79, 80, 73, 74, 75, 0, 13, 76, 63, - 5, 6, 4, 9, 10, 7, 8, 0, 0, 65, - 72, 0, 65, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 11, 12, 0, 0, 0, - 19, 0, 0, 0, 0, 26, 67, 66, 0, 0, - 0, 0, 0, 3, 48, 47, 45, 44, 43, 42, - 41, 35, 36, 39, 40, 37, 38, 33, 34, 31, - 32, 28, 29, 30, 27, 0, 14, 0, 16, 0, - 21, 0, 61, 62, 56, 0, 25, 68, 24, 15, - 17, 18, 22, 0, 0, 0, 0, 20, 46, 0, - 23, 69, 0, 70, 77, 0, 0, 71, 78, 0, - 0, 0 -}; - -static const short yydefgoto[] = { 150, - 48, 27, 121, 134, 28, 29, 49, 30, 146, 31 -}; - -static const short yypact[] = { 125, --32768,-32768,-32768, 1,-32768,-32768, 24, 24, 24, 176, - 24, 24,-32768,-32768,-32768,-32768, 125, 125, 125, 125, - 125, 125, 125, 125, 515, 0, 243, 14,-32768, 18, --32768,-32768,-32768,-32768,-32768,-32768, 125, 472,-32768,-32768, - 472, 472, 472, 472, 472, 472, 472, 21, 52, 19, --32768, 58, 20, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125,-32768,-32768, -1, 29, 125, --32768, 125, 24, 24, 119,-32768,-32768,-32768, 515, 125, - 32, 125, -14, 243, 243, 243, 275, 306, 336, 365, - 393, 419, 419, 441, 441, 441, 441, 161, 161, 459, - 459, 104, 104, 104, 472, 125,-32768, 125,-32768, 49, - 125, 208, 26,-32768, 125, 57, 472,-32768, 472, 104, - 104,-32768, 243, 22, 125, 38, 125,-32768, 243, 25, - 243, 27, 16,-32768, 54, 23, 515,-32768, 54, 84, - 86,-32768 -}; - -static const short yypgoto[] = {-32768, - 3, -10,-32768,-32768,-32768,-32768, -21, -23,-32768, 10 -}; - - -#define YYLAST 528 - - -static const short yytable[] = { 38, - 50, 53, 26, 52, 32, 33, 41, 42, 43, 44, - 45, 46, 47, 50, -79, 85, 34, 35, 36, 54, - 39, 40, 51, 128, 7, 8, 9, 83, 11, 32, - 33, 84, 91, 93, 32, 33, 116, 32, 33, -60, - 54, 137, 147, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 126, 118, 144, 54, 128, - 136, 122, 86, 138, 148, 140, 142, 143, 87, 127, - 87, 129, 120, 151, 87, 152, 0, 117, 119, 88, - 0, 88, 123, 124, 0, 88, 0, 0, 132, 0, - 124, 0, 89, 90, 89, 130, 0, 131, 89, 0, - 133, 92, 0, 0, 127, 0, 0, 0, 0, 53, - 0, 145, 0, 53, 139, 149, 141, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 0, 16, 75, 87, 76, 77, 78, 79, - 80, 17, 0, 0, 81, 0, 88, 0, 82, 0, - 0, 18, 19, 0, 0, 0, 0, 20, 21, 89, - 125, 0, 22, 23, 0, 24, 0, 25, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 0, 16, 0, 70, 71, 72, 73, - 74, 75, 17, 76, 77, 78, 79, 80, 0, 0, - 0, 81, 18, 19, 0, 82, 0, 0, 20, 21, - 0, 0, 0, 22, 23, 55, 37, 0, 25, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 0, - 76, 77, 78, 79, 80, 0, 0, 0, 81, 0, - 55, 0, 82, 135, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 0, 76, 77, 78, 79, 80, - 0, 0, 0, 81, 0, 0, 0, 82, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 0, 76, 77, 78, - 79, 80, 0, 0, 0, 81, 0, 0, 0, 82, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 0, 76, 77, - 78, 79, 80, 0, 0, 0, 81, 0, 0, 0, - 82, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 0, 76, 77, - 78, 79, 80, 0, 0, 0, 81, 0, 0, 0, - 82, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 0, 76, 77, 78, - 79, 80, 0, 0, 0, 81, 0, 0, 0, 82, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 0, 76, 77, 78, 79, 80, - 0, 0, 0, 81, 0, 0, 0, 82, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 0, 76, 77, 78, 79, 80, 0, 0, 0, 81, - 0, 0, 0, 82, 68, 69, 70, 71, 72, 73, - 74, 75, 0, 76, 77, 78, 79, 80, 0, 0, - 0, 81, 0, 0, 0, 82, 72, 73, 74, 75, - 0, 76, 77, 78, 79, 80, 0, 0, 0, 81, - 0, 0, 0, 82, 76, 77, 78, 79, 80, 0, - 0, 51, 81, 7, 8, 9, 82, 11 -}; - -static const short yycheck[] = { 10, - 24, 25, 0, 25, 6, 7, 17, 18, 19, 20, - 21, 22, 23, 37, 14, 37, 7, 8, 9, 20, - 11, 12, 7, 38, 9, 10, 11, 14, 13, 6, - 7, 14, 14, 14, 6, 7, 38, 6, 7, 14, - 20, 20, 20, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 89, 38, 52, 20, 38, - 14, 82, 52, 52, 52, 38, 52, 51, 27, 90, - 27, 92, 80, 0, 27, 0, -1, 78, 79, 38, - -1, 38, 83, 84, -1, 38, -1, -1, 50, -1, - 91, -1, 51, 52, 51, 116, -1, 118, 51, -1, - 121, 54, -1, -1, 125, -1, -1, -1, -1, 143, - -1, 143, -1, 147, 135, 147, 137, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, -1, 19, 41, 27, 43, 44, 45, 46, - 47, 27, -1, -1, 51, -1, 38, -1, 55, -1, - -1, 37, 38, -1, -1, -1, -1, 43, 44, 51, - 52, -1, 48, 49, -1, 51, -1, 53, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, -1, 19, -1, 36, 37, 38, 39, - 40, 41, 27, 43, 44, 45, 46, 47, -1, -1, - -1, 51, 37, 38, -1, 55, -1, -1, 43, 44, - -1, -1, -1, 48, 49, 18, 51, -1, 53, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, -1, - 43, 44, 45, 46, 47, -1, -1, -1, 51, -1, - 18, -1, 55, 56, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, -1, 43, 44, 45, 46, 47, - -1, -1, -1, 51, -1, -1, -1, 55, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, - 46, 47, -1, -1, -1, 51, -1, -1, -1, 55, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, -1, 43, 44, - 45, 46, 47, -1, -1, -1, 51, -1, -1, -1, - 55, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, -1, 43, 44, - 45, 46, 47, -1, -1, -1, 51, -1, -1, -1, - 55, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, - 46, 47, -1, -1, -1, 51, -1, -1, -1, 55, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, -1, 43, 44, 45, 46, 47, - -1, -1, -1, 51, -1, -1, -1, 55, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - -1, 43, 44, 45, 46, 47, -1, -1, -1, 51, - -1, -1, -1, 55, 34, 35, 36, 37, 38, 39, - 40, 41, -1, 43, 44, 45, 46, 47, -1, -1, - -1, 51, -1, -1, -1, 55, 38, 39, 40, 41, - -1, 43, 44, 45, 46, 47, -1, -1, -1, 51, - -1, -1, -1, 55, 43, 44, 45, 46, 47, -1, - -1, 7, 51, 9, 10, 11, 55, 13 -}; -#define YYPURE 1 - -#line 2 "bison.simple" - -/* Skeleton output parser for bison, - copyright (C) 1984 Bob Corbett and Richard Stallman - - NO WARRANTY - - BECAUSE THIS PROGRAM 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 THIS PROGRAM "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 THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM 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 THIS PROGRAM AS PERMITTED BELOW, 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) THIS -PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. - - GENERAL PUBLIC LICENSE TO COPY - - 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) 1985 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. - - 2. You may modify your copy or copies of this source file 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 this - program 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 some or all third parties, at your option). - - c) 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 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: - - 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 this program -except as expressly provided under this License Agreement. Any attempt -otherwise to copy, sublicense, distribute or transfer this program 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 this program 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, you are welcome to use, share and improve this program. -You are forbidden to forbid anyone else to use, share and improve -what you give them. Help stamp out software-hoarding! */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYFAIL goto yyerrlab; - -#define YYTERROR 1 - -#ifndef YYIMPURE -#define YYLEX yylex() -#endif - -#ifndef YYPURE -#define YYLEX yylex(&yylval, &yylloc) -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYIMPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ - -int yynerr; /* number of parse errors so far */ - -#ifdef YYDEBUG -int yydebug = 0; /* nonzero means print parse trace */ -#endif - -#endif /* YYIMPURE */ - - -/* YYMAXDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 200 -#endif - -/* YYMAXLIMIT is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#ifndef YYMAXLIMIT -#define YYMAXLIMIT 10000 -#endif - - -#line 165 "bison.simple" -int -yyparse() -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYMAXDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYMAXDEPTH]; /* the semantic value stack */ - YYLTYPE yylsa[YYMAXDEPTH]; /* the location stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - YYLTYPE *yyls = yylsa; - - int yymaxdepth = YYMAXDEPTH; - -#ifndef YYPURE - - int yychar; - YYSTYPE yylval; - YYLTYPE yylloc; - -#ifdef YYDEBUG - extern int yydebug; -#endif - -#endif - - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#ifdef YYDEBUG - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerr = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. */ - - yyssp = yyss - 1; - yyvsp = yyvs; - yylsp = yyls; - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yymaxdepth - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - YYLTYPE *yyls1 = yyls; - short *yyss1 = yyss; - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yymaxdepth); - - yyss = yyss1; yyvs = yyvs1; yyls = yyls1; -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yymaxdepth >= YYMAXLIMIT) - yyerror("parser stack overflow"); - yymaxdepth *= 2; - if (yymaxdepth > YYMAXLIMIT) - yymaxdepth = YYMAXLIMIT; - yyss = (short *) alloca (yymaxdepth * sizeof (*yyssp)); - bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); - yyls = (YYLTYPE *) alloca (yymaxdepth * sizeof (*yylsp)); - bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); - yyvs = (YYSTYPE *) alloca (yymaxdepth * sizeof (*yyvsp)); - bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yylsp = yyls + size - 1; - yyvsp = yyvs + size - 1; - -#ifdef YYDEBUG - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yymaxdepth); -#endif - - if (yyssp >= yyss + yymaxdepth - 1) - YYERROR; - } - -#ifdef YYDEBUG - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -yyresume: - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#ifdef YYDEBUG - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#ifdef YYDEBUG - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#ifdef YYDEBUG - if (yydebug) - fprintf(stderr, "Next token is %d (%s)\n", yychar, yytname[yychar1]); -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#ifdef YYDEBUG - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; - *++yylsp = yylloc; - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#ifdef YYDEBUG - if (yydebug) - { - if (yylen == 1) - fprintf (stderr, "Reducing 1 value via line %d, ", - yyrline[yyn]); - else - fprintf (stderr, "Reducing %d values via line %d, ", - yylen, yyrline[yyn]); - } -#endif - - - switch (yyn) { - -case 3: -#line 158 "expread.y" -{ write_exp_elt (BINOP_COMMA); ; - break;} -case 4: -#line 163 "expread.y" -{ write_exp_elt (UNOP_IND); ; - break;} -case 5: -#line 166 "expread.y" -{ write_exp_elt (UNOP_ADDR); ; - break;} -case 6: -#line 169 "expread.y" -{ write_exp_elt (UNOP_NEG); ; - break;} -case 7: -#line 173 "expread.y" -{ write_exp_elt (UNOP_ZEROP); ; - break;} -case 8: -#line 177 "expread.y" -{ write_exp_elt (UNOP_LOGNOT); ; - break;} -case 9: -#line 181 "expread.y" -{ write_exp_elt (UNOP_PREINCREMENT); ; - break;} -case 10: -#line 185 "expread.y" -{ write_exp_elt (UNOP_PREDECREMENT); ; - break;} -case 11: -#line 189 "expread.y" -{ write_exp_elt (UNOP_POSTINCREMENT); ; - break;} -case 12: -#line 193 "expread.y" -{ write_exp_elt (UNOP_POSTDECREMENT); ; - break;} -case 13: -#line 197 "expread.y" -{ write_exp_elt (UNOP_SIZEOF); ; - break;} -case 14: -#line 201 "expread.y" -{ write_exp_elt (STRUCTOP_PTR); - write_exp_string (yyvsp[0].sval); - write_exp_elt (STRUCTOP_PTR); ; - break;} -case 15: -#line 207 "expread.y" -{ write_exp_elt (STRUCTOP_MPTR); ; - break;} -case 16: -#line 211 "expread.y" -{ write_exp_elt (STRUCTOP_STRUCT); - write_exp_string (yyvsp[0].sval); - write_exp_elt (STRUCTOP_STRUCT); ; - break;} -case 17: -#line 217 "expread.y" -{ write_exp_elt (STRUCTOP_MEMBER); ; - break;} -case 18: -#line 221 "expread.y" -{ write_exp_elt (BINOP_SUBSCRIPT); ; - break;} -case 19: -#line 227 "expread.y" -{ start_arglist (); ; - break;} -case 20: -#line 229 "expread.y" -{ write_exp_elt (OP_FUNCALL); - write_exp_elt (end_arglist ()); - write_exp_elt (OP_FUNCALL); ; - break;} -case 22: -#line 238 "expread.y" -{ arglist_len = 1; ; - break;} -case 23: -#line 242 "expread.y" -{ arglist_len++; ; - break;} -case 24: -#line 246 "expread.y" -{ write_exp_elt (UNOP_MEMVAL); - write_exp_elt (yyvsp[-2].tval); - write_exp_elt (UNOP_MEMVAL); ; - break;} -case 25: -#line 252 "expread.y" -{ write_exp_elt (UNOP_CAST); - write_exp_elt (yyvsp[-2].tval); - write_exp_elt (UNOP_CAST); ; - break;} -case 26: -#line 258 "expread.y" -{ ; - break;} -case 27: -#line 264 "expread.y" -{ write_exp_elt (BINOP_REPEAT); ; - break;} -case 28: -#line 268 "expread.y" -{ write_exp_elt (BINOP_MUL); ; - break;} -case 29: -#line 272 "expread.y" -{ write_exp_elt (BINOP_DIV); ; - break;} -case 30: -#line 276 "expread.y" -{ write_exp_elt (BINOP_REM); ; - break;} -case 31: -#line 280 "expread.y" -{ write_exp_elt (BINOP_ADD); ; - break;} -case 32: -#line 284 "expread.y" -{ write_exp_elt (BINOP_SUB); ; - break;} -case 33: -#line 288 "expread.y" -{ write_exp_elt (BINOP_LSH); ; - break;} -case 34: -#line 292 "expread.y" -{ write_exp_elt (BINOP_RSH); ; - break;} -case 35: -#line 296 "expread.y" -{ write_exp_elt (BINOP_EQUAL); ; - break;} -case 36: -#line 300 "expread.y" -{ write_exp_elt (BINOP_NOTEQUAL); ; - break;} -case 37: -#line 304 "expread.y" -{ write_exp_elt (BINOP_LEQ); ; - break;} -case 38: -#line 308 "expread.y" -{ write_exp_elt (BINOP_GEQ); ; - break;} -case 39: -#line 312 "expread.y" -{ write_exp_elt (BINOP_LESS); ; - break;} -case 40: -#line 316 "expread.y" -{ write_exp_elt (BINOP_GTR); ; - break;} -case 41: -#line 320 "expread.y" -{ write_exp_elt (BINOP_LOGAND); ; - break;} -case 42: -#line 324 "expread.y" -{ write_exp_elt (BINOP_LOGXOR); ; - break;} -case 43: -#line 328 "expread.y" -{ write_exp_elt (BINOP_LOGIOR); ; - break;} -case 44: -#line 332 "expread.y" -{ write_exp_elt (BINOP_AND); ; - break;} -case 45: -#line 336 "expread.y" -{ write_exp_elt (BINOP_OR); ; - break;} -case 46: -#line 340 "expread.y" -{ write_exp_elt (TERNOP_COND); ; - break;} -case 47: -#line 344 "expread.y" -{ write_exp_elt (BINOP_ASSIGN); ; - break;} -case 48: -#line 348 "expread.y" -{ write_exp_elt (BINOP_ASSIGN_MODIFY); - write_exp_elt (yyvsp[-1].opcode); - write_exp_elt (BINOP_ASSIGN_MODIFY); ; - break;} -case 49: -#line 354 "expread.y" -{ write_exp_elt (OP_LONG); - write_exp_elt (builtin_type_long); - write_exp_elt (yyvsp[0].lval); - write_exp_elt (OP_LONG); ; - break;} -case 50: -#line 361 "expread.y" -{ write_exp_elt (OP_LONG); - write_exp_elt (builtin_type_char); - write_exp_elt (yyvsp[0].lval); - write_exp_elt (OP_LONG); ; - break;} -case 51: -#line 368 "expread.y" -{ write_exp_elt (OP_DOUBLE); - write_exp_elt (builtin_type_double); - write_exp_elt (yyvsp[0].dval); - write_exp_elt (OP_DOUBLE); ; - break;} -case 53: -#line 378 "expread.y" -{ write_exp_elt (OP_LAST); - write_exp_elt (yyvsp[0].lval); - write_exp_elt (OP_LAST); ; - break;} -case 54: -#line 384 "expread.y" -{ write_exp_elt (OP_REGISTER); - write_exp_elt (yyvsp[0].lval); - write_exp_elt (OP_REGISTER); ; - break;} -case 55: -#line 390 "expread.y" -{ write_exp_elt (OP_INTERNALVAR); - write_exp_elt (yyvsp[0].ivar); - write_exp_elt (OP_INTERNALVAR); ; - break;} -case 56: -#line 396 "expread.y" -{ write_exp_elt (OP_LONG); - write_exp_elt (builtin_type_int); - write_exp_elt ((long) TYPE_LENGTH (yyvsp[-1].tval)); - write_exp_elt (OP_LONG); ; - break;} -case 57: -#line 403 "expread.y" -{ write_exp_elt (OP_STRING); - write_exp_string (yyvsp[0].sval); - write_exp_elt (OP_STRING); ; - break;} -case 58: -#line 410 "expread.y" -{ write_exp_elt (OP_THIS); - write_exp_elt (OP_THIS); ; - break;} -case 59: -#line 417 "expread.y" -{ - struct symtab *tem = lookup_symtab (copy_name (yyvsp[0].sval)); - struct symbol *sym; - - if (tem) - yyval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), 1); - else - { - sym = lookup_symbol (copy_name (yyvsp[0].sval), - expression_context_block, - VAR_NAMESPACE); - if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) - yyval.bval = SYMBOL_BLOCK_VALUE (sym); - else - error ("No file or function \"%s\".", - copy_name (yyvsp[0].sval)); - } - ; - break;} -case 60: -#line 438 "expread.y" -{ - struct symbol *tem - = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, VAR_NAMESPACE); - if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) - error ("No function \"%s\" in specified context.", - copy_name (yyvsp[-2].bval)); - yyval.bval = SYMBOL_BLOCK_VALUE (tem); - ; - break;} -case 61: -#line 449 "expread.y" -{ - struct symbol *sym; - sym = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, VAR_NAMESPACE); - if (sym == 0) - error ("No symbol \"%s\" in specified context.", - copy_name (yyvsp[0].sval)); - write_exp_elt (OP_VAR_VALUE); - write_exp_elt (sym); - write_exp_elt (OP_VAR_VALUE); - ; - break;} -case 62: -#line 462 "expread.y" -{ - struct type *type = yyvsp[-2].tval; - 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 (yyvsp[0].sval); - write_exp_elt (OP_SCOPE); - ; - break;} -case 63: -#line 475 "expread.y" -{ - char *name = copy_name (yyvsp[0].sval); - 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); - ; - break;} -case 64: -#line 511 "expread.y" -{ struct symbol *sym; - sym = lookup_symbol_1 (copy_name (yyvsp[0].sval), - expression_context_block, - VAR_NAMESPACE); - if (sym) - { - write_exp_elt (OP_VAR_VALUE); - write_exp_elt (sym); - write_exp_elt (OP_VAR_VALUE); - } - else - { - register char *arg = copy_name (yyvsp[0].sval); - 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 (yyvsp[0].sval); - 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; - - 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.", - copy_name (yyvsp[0].sval)); - } - ; - break;} -case 66: -#line 577 "expread.y" -{ yyval.tval = lookup_pointer_type (yyvsp[-1].tval); ; - break;} -case 67: -#line 579 "expread.y" -{ yyval.tval = lookup_reference_type (yyvsp[-1].tval); ; - break;} -case 68: -#line 581 "expread.y" -{ yyval.tval = lookup_member_type (builtin_type_int, yyvsp[-2].tval); ; - break;} -case 69: -#line 583 "expread.y" -{ yyval.tval = lookup_member_type (yyvsp[-5].tval, yyvsp[-3].tval); ; - break;} -case 70: -#line 585 "expread.y" -{ yyval.tval = lookup_member_type (lookup_function_type (yyvsp[-7].tval, 0), yyvsp[-5].tval); ; - break;} -case 71: -#line 587 "expread.y" -{ yyval.tval = lookup_member_type (lookup_function_type (yyvsp[-8].tval, yyvsp[-1].tvec), yyvsp[-6].tval); - free (yyvsp[-1].tvec); ; - break;} -case 72: -#line 593 "expread.y" -{ yyval.tval = lookup_typename (copy_name (yyvsp[0].sval), - expression_context_block, 0); ; - break;} -case 73: -#line 596 "expread.y" -{ yyval.tval = lookup_struct (copy_name (yyvsp[0].sval), - expression_context_block); ; - break;} -case 74: -#line 599 "expread.y" -{ yyval.tval = lookup_union (copy_name (yyvsp[0].sval), - expression_context_block); ; - break;} -case 75: -#line 602 "expread.y" -{ yyval.tval = lookup_enum (copy_name (yyvsp[0].sval), - expression_context_block); ; - break;} -case 76: -#line 605 "expread.y" -{ yyval.tval = lookup_unsigned_typename (copy_name (yyvsp[0].sval)); ; - break;} -case 77: -#line 610 "expread.y" -{ yyval.tvec = (struct type **)xmalloc (sizeof (struct type *) * 2); - yyval.tvec[0] = (struct type *)0; - yyval.tvec[1] = yyvsp[0].tval; - ; - break;} -case 78: -#line 615 "expread.y" -{ int len = sizeof (struct type *) * ++(yyvsp[-2].ivec[0]); - yyval.tvec = (struct type **)xrealloc (yyvsp[-2].tvec, len); - yyval.tvec[yyval.ivec[0]] = yyvsp[0].tval; - ; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 303 "bison.simple" - - yyvsp -= yylen; - yylsp -= yylen; - yyssp -= yylen; - -#ifdef YYDEBUG - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now", yyssp-yyss); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerr; - yyerror("parse error"); - } - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYERROR; - -#ifdef YYDEBUG - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYERROR; - yyvsp--; - yylsp--; - yystate = *--yyssp; - -#ifdef YYDEBUG - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now", yyssp-yyss); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#ifdef YYDEBUG - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; - *++yylsp = yylloc; - - yystate = yyn; - goto yynewstate; -} -#line 624 "expread.y" - - -/* Begin counting arguments for a function call, - saving the data about any containing call. */ - -static void -start_arglist () -{ - register struct funcall *new = (struct funcall *) xmalloc (sizeof (struct funcall)); - - new->next = funcall_chain; - new->arglist_len = arglist_len; - arglist_len = 0; - funcall_chain = new; -} - -/* Return the number of arguments in a function call just terminated, - and restore the data for the containing function call. */ - -static int -end_arglist () -{ - register int val = arglist_len; - register struct funcall *call = funcall_chain; - funcall_chain = call->next; - arglist_len = call->arglist_len; - free (call); - return val; -} - -/* Free everything in the funcall chain. - Used when there is an error inside parsing. */ - -static void -free_funcalls () -{ - register struct funcall *call, *next; - - for (call = funcall_chain; call; call = next) - { - next = call->next; - free (call); - } -} - -/* This page contains the functions for adding data to the struct expression - being constructed. */ - -/* Add one element to the end of the expression. */ - -static void -write_exp_elt (expelt) - union exp_element expelt; -{ - if (expout_ptr >= expout_size) - { - expout_size *= 2; - expout = (struct expression *) xrealloc (expout, - sizeof (struct expression) - + expout_size * sizeof (union exp_element)); - } - expout->elts[expout_ptr++] = expelt; -} - -/* Add a string constant to the end of the expression. - Follow it by its length in bytes, as a separate exp_element. */ - -static void -write_exp_string (str) - struct stoken str; -{ - register int len = str.length; - register int lenelt - = (len + sizeof (union exp_element)) / sizeof (union exp_element); - - expout_ptr += lenelt; - - if (expout_ptr >= expout_size) - { - expout_size = max (expout_size * 2, expout_ptr + 10); - expout = (struct expression *) xrealloc (expout, - sizeof (struct expression) - + expout_size * sizeof (union exp_element)); - } - bcopy (str.ptr, (char *) &expout->elts[expout_ptr - lenelt], len); - ((char *) &expout->elts[expout_ptr - lenelt])[len] = 0; - write_exp_elt (len); -} - -/* During parsing of a C expression, the pointer to the next character - is in this variable. */ - -static char *lexptr; - -/* Tokens that refer to names do so with explicit pointer and length, - so they can share the storage that lexptr is parsing. - - When it is necessary to pass a name to a function that expects - a null-terminated string, the substring is copied out - into a block of storage that namecopy points to. - - namecopy is allocated once, guaranteed big enough, for each parsing. */ - -static char *namecopy; - -/* Current depth in parentheses within the expression. */ - -static int paren_depth; - -/* Nonzero means stop parsing on first comma (if not within parentheses). */ - -static int comma_terminates; - -/* Take care of parsing a number (anything that starts with a digit). - Set yylval and return the token type; update lexptr. - LEN is the number of characters in it. */ - -/*** Needs some error checking for the float case ***/ - -static int -parse_number (olen) - int olen; -{ - register char *p = lexptr; - register long n = 0; - register int c; - register int base = 10; - register int len = olen; - char *err_copy; - - extern double atof (); - - for (c = 0; c < len; c++) - if (p[c] == '.') - { - /* It's a float since it contains a point. */ - yylval.dval = atof (p); - lexptr += len; - return FLOAT; - } - - if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) - { - p += 2; - base = 16; - len -= 2; - } - else if (*p == '0') - base = 8; - - while (len-- > 0) - { - c = *p++; - n *= base; - if (c >= '0' && c <= '9') - n += c - '0'; - else - { - if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; - if (base == 16 && c >= 'a' && c <= 'f') - n += c - 'a' + 10; - else if (len == 0 && c == 'l') - ; - else - { - err_copy = (char *) alloca (olen + 1); - bcopy (lexptr, err_copy, olen); - err_copy[olen] = 0; - error ("Invalid number \"%s\".", err_copy); - } - } - } - - lexptr = p; - yylval.lval = n; - return INT; -} - -struct token -{ - char *operator; - int token; - enum exp_opcode opcode; -}; - -static struct token tokentab3[] = - { - {">>=", ASSIGN_MODIFY, BINOP_RSH}, - {"<<=", ASSIGN_MODIFY, BINOP_LSH} - }; - -static struct token tokentab2[] = - { - {"+=", ASSIGN_MODIFY, BINOP_ADD}, - {"-=", ASSIGN_MODIFY, BINOP_SUB}, - {"*=", ASSIGN_MODIFY, BINOP_MUL}, - {"/=", ASSIGN_MODIFY, BINOP_DIV}, - {"%=", ASSIGN_MODIFY, BINOP_REM}, - {"|=", ASSIGN_MODIFY, BINOP_LOGIOR}, - {"&=", ASSIGN_MODIFY, BINOP_LOGAND}, - {"^=", ASSIGN_MODIFY, BINOP_LOGXOR}, - {"++", INCREMENT, BINOP_END}, - {"--", DECREMENT, BINOP_END}, - {"->", ARROW, BINOP_END}, - {"&&", AND, BINOP_END}, - {"||", OR, BINOP_END}, - {"::", COLONCOLON, BINOP_END}, - {"<<", LSH, BINOP_END}, - {">>", RSH, BINOP_END}, - {"==", EQUAL, BINOP_END}, - {"!=", NOTEQUAL, BINOP_END}, - {"<=", LEQ, BINOP_END}, - {">=", GEQ, BINOP_END} - }; - -/* Read one token, getting characters through lexptr. */ - -static int -yylex () -{ - register int c; - register int namelen; - register int i; - register char *tokstart; - - retry: - - tokstart = lexptr; - /* See if it is a special token of length 3. */ - for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) - if (!strncmp (tokstart, tokentab3[i].operator, 3)) - { - lexptr += 3; - yylval.opcode = tokentab3[i].opcode; - return tokentab3[i].token; - } - - /* See if it is a special token of length 2. */ - for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) - if (!strncmp (tokstart, tokentab2[i].operator, 2)) - { - lexptr += 2; - yylval.opcode = tokentab2[i].opcode; - return tokentab2[i].token; - } - - switch (c = *tokstart) - { - case 0: - return 0; - - case ' ': - case '\t': - case '\n': - lexptr++; - goto retry; - - case '\'': - lexptr++; - c = *lexptr++; - if (c == '\\') - c = parse_escape (&lexptr); - yylval.lval = c; - c = *lexptr++; - if (c != '\'') - error ("Invalid character constant."); - return CHAR; - - case '(': - paren_depth++; - lexptr++; - return c; - - case ')': - if (paren_depth == 0) - return 0; - paren_depth--; - lexptr++; - return c; - - case ',': - if (comma_terminates && paren_depth == 0) - return 0; - lexptr++; - return c; - - case '+': - case '-': - case '*': - case '/': - case '%': - case '|': - case '&': - case '^': - case '~': - case '!': - case '@': - case '<': - case '>': - case '[': - case ']': - case '.': - case '?': - case ':': - case '=': - case '{': - case '}': - lexptr++; - return c; - - case '"': - for (namelen = 1; (c = tokstart[namelen]) != '"'; namelen++) - if (c == '\\') - { - c = tokstart[++namelen]; - if (c >= '0' && c <= '9') - { - c = tokstart[++namelen]; - if (c >= '0' && c <= '9') - c = tokstart[++namelen]; - } - } - yylval.sval.ptr = tokstart + 1; - yylval.sval.length = namelen - 1; - lexptr += namelen + 1; - return STRING; - } - if (c >= '0' && c <= '9') - { - /* It's a number */ - for (namelen = 0; - c = tokstart[namelen], - (c == '_' || c == '$' || c == '.' || (c >= '0' && c <= '9') - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); - namelen++) - ; - return parse_number (namelen); - } - - if (!(c == '_' || c == '$' - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) - error ("Invalid token in expression."); - - /* It is a name. See how long it is. */ - - for (namelen = 0; - c = tokstart[namelen], - (c == '_' || c == '$' || (c >= '0' && c <= '9') - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); - namelen++) - ; - - /* The token "if" terminates the expression and is NOT - removed from the input stream. */ - if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') - { - return 0; - } - - lexptr += namelen; - - /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1) - and $$digits (equivalent to $<-digits> if you could type that). - Make token type LAST, and put the number (the digits) in yylval. */ - - if (*tokstart == '$') - { - register int negate = 0; - c = 1; - /* Double dollar means negate the number and add -1 as well. - Thus $$ alone means -1. */ - if (namelen >= 2 && tokstart[1] == '$') - { - negate = 1; - c = 2; - } - if (c == namelen) - { - /* Just dollars (one or two) */ - yylval.lval = - negate; - return LAST; - } - /* Is the rest of the token digits? */ - for (; c < namelen; c++) - if (!(tokstart[c] >= '0' && tokstart[c] <= '9')) - break; - if (c == namelen) - { - yylval.lval = atoi (tokstart + 1 + negate); - if (negate) - yylval.lval = - yylval.lval; - return LAST; - } - } - - /* Handle tokens that refer to machine registers: - $ followed by a register name. */ - - if (*tokstart == '$') - for (c = 0; c < NUM_REGS; c++) - if (namelen - 1 == strlen (reg_names[c]) - && !strncmp (tokstart + 1, reg_names[c], namelen - 1)) - { - yylval.lval = c; - return REGNAME; - } - - if (namelen == 6 && !strncmp (tokstart, "struct", 6)) - { - return STRUCT; - } - if (namelen == 5) - { - if (!strncmp (tokstart, "union", 5)) - { - return UNION; - } - } - if (namelen == 4) - { - if (!strncmp (tokstart, "enum", 4)) - { - return ENUM; - } - if (!strncmp (tokstart, "this", 4)) - { - return THIS; - } - } - if (namelen == 6 && !strncmp (tokstart, "sizeof", 6)) - { - return SIZEOF; - } - if (namelen == 8 && !strncmp (tokstart, "unsigned", 6)) - { - return UNSIGNED; - } - yylval.sval.ptr = tokstart; - yylval.sval.length = namelen; - - /* Any other names starting in $ are debugger internal variables. */ - - if (*tokstart == '$') - { - yylval.ivar = (struct internalvar *) lookup_internalvar (copy_name (yylval.sval) + 1); - return VARIABLE; - } - - /* Use token-type TYPENAME for symbols that happen to be defined - currently as names of types; NAME for other symbols. - The caller is not constrained to care about the distinction. */ - if (lookup_typename (copy_name (yylval.sval), expression_context_block, 1)) - return TYPENAME; - return NAME; -} - -static -yyerror () -{ - error ("Invalid syntax in expression."); -} - -/* Return a null-terminated temporary copy of the name - of a string token. */ - -static char * -copy_name (token) - struct stoken token; -{ - bcopy (token.ptr, namecopy, token.length); - namecopy[token.length] = 0; - return namecopy; -} - -/* Reverse an expression from suffix form (in which it is constructed) - to prefix form (in which we can conveniently print or execute it). */ - -static void prefixify_subexp (); - -static void -prefixify_expression (expr) - register struct expression *expr; -{ - register int len = sizeof (struct expression) + - expr->nelts * sizeof (union exp_element); - register struct expression *temp; - register int inpos = expr->nelts, outpos = 0; - - temp = (struct expression *) alloca (len); - - /* Copy the original expression into temp. */ - bcopy (expr, temp, len); - - prefixify_subexp (temp, expr, inpos, outpos); -} - -/* Return the number of exp_elements in the subexpression of EXPR - whose last exp_element is at index ENDPOS - 1 in EXPR. */ - -static int -length_of_subexp (expr, endpos) - register struct expression *expr; - register int endpos; -{ - register int oplen = 1; - 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; - break; - - case OP_VAR_VALUE: - case OP_LAST: - case OP_REGISTER: - case OP_INTERNALVAR: - oplen = 3; - break; - - case OP_FUNCALL: - oplen = 3; - args = 1 + expr->elts[endpos - 2].longconst; - break; - - case UNOP_CAST: - case UNOP_MEMVAL: - oplen = 3; - args = 1; - break; - - case STRUCTOP_STRUCT: - case STRUCTOP_PTR: - args = 1; - case OP_STRING: - oplen = 3 + ((expr->elts[endpos - 2].longconst - + sizeof (union exp_element)) - / sizeof (union exp_element)); - break; - - case TERNOP_COND: - args = 3; - break; - - case BINOP_ASSIGN_MODIFY: - oplen = 3; - args = 2; - break; - - /* C++ */ - case OP_THIS: - oplen = 2; - break; - - default: - args = 1 + (i < (int) BINOP_END); - } - - while (args > 0) - { - oplen += length_of_subexp (expr, endpos - oplen); - args--; - } - - return oplen; -} - -/* Copy the subexpression ending just before index INEND in INEXPR - into OUTEXPR, starting at index OUTBEG. - In the process, convert it from suffix to prefix form. */ - -static void -prefixify_subexp (inexpr, outexpr, inend, outbeg) - register struct expression *inexpr; - struct expression *outexpr; - register int inend; - int outbeg; -{ - register int oplen = 1; - register int args = 0; - register int i; - int *arglens; - enum exp_opcode opcode; - - /* Compute how long the last operation is (in OPLEN), - and also how many preceding subexpressions serve as - arguments for it (in ARGS). */ - - 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; - break; - - case OP_VAR_VALUE: - case OP_LAST: - case OP_REGISTER: - case OP_INTERNALVAR: - oplen = 3; - break; - - case OP_FUNCALL: - oplen = 3; - args = 1 + inexpr->elts[inend - 2].longconst; - break; - - case UNOP_CAST: - case UNOP_MEMVAL: - oplen = 3; - args = 1; - break; - - case STRUCTOP_STRUCT: - case STRUCTOP_PTR: - args = 1; - case OP_STRING: - oplen = 3 + ((inexpr->elts[inend - 2].longconst - + sizeof (union exp_element)) - / sizeof (union exp_element)); - - break; - - case TERNOP_COND: - args = 3; - break; - - case BINOP_ASSIGN_MODIFY: - oplen = 3; - args = 2; - break; - - /* C++ */ - case OP_THIS: - oplen = 2; - break; - - default: - args = 1 + ((int) opcode < (int) BINOP_END); - } - - /* Copy the final operator itself, from the end of the input - to the beginning of the output. */ - inend -= oplen; - bcopy (&inexpr->elts[inend], &outexpr->elts[outbeg], - oplen * sizeof (union exp_element)); - outbeg += oplen; - - /* Find the lengths of the arg subexpressions. */ - arglens = (int *) alloca (args * sizeof (int)); - for (i = args - 1; i >= 0; i--) - { - oplen = length_of_subexp (inexpr, inend); - arglens[i] = oplen; - inend -= oplen; - } - - /* Now copy each subexpression, preserving the order of - the subexpressions, but prefixifying each one. - In this loop, inend starts at the beginning of - the expression this level is working on - and marches forward over the arguments. - outbeg does similarly in the output. */ - for (i = 0; i < args; i++) - { - oplen = arglens[i]; - inend += oplen; - prefixify_subexp (inexpr, outexpr, inend, outbeg); - outbeg += oplen; - } -} - -/* This page contains the two entry points to this file. */ - -/* Read a C expression from the string *STRINGPTR points to, - parse it, and return a pointer to a struct expression that we malloc. - Use block BLOCK as the lexical context for variable names; - if BLOCK is zero, use the block of the selected stack frame. - Meanwhile, advance *STRINGPTR to point after the expression, - at the first nonwhite character that is not part of the expression - (possibly a null character). - - If COMMA is nonzero, stop if a comma is reached. */ - -struct expression * -parse_c_1 (stringptr, block, comma) - char **stringptr; - struct block *block; -{ - struct cleanup *old_chain; - - lexptr = *stringptr; - - comma_terminates = comma; - - if (lexptr == 0 || *lexptr == 0) - error_no_arg ("expression to compute"); - - old_chain = make_cleanup (free_funcalls, 0); - funcall_chain = 0; - - expression_context_block = block ? block : get_selected_block (); - - namecopy = (char *) alloca (strlen (lexptr) + 1); - expout_size = 10; - expout_ptr = 0; - expout = (struct expression *) xmalloc (sizeof (struct expression) - + expout_size * sizeof (union exp_element)); - make_cleanup (free_current_contents, &expout); - if (yyparse ()) - yyerror (); - discard_cleanups (old_chain); - expout->nelts = expout_ptr; - expout = (struct expression *) - xrealloc (expout, - sizeof (struct expression) - + expout_ptr * sizeof (union exp_element)); - prefixify_expression (expout); - *stringptr = lexptr; - return expout; -} - -/* Parse STRING as an expression, and complain if this fails - to use up all of the contents of STRING. */ - -struct expression * -parse_c_expression (string) - char *string; -{ - register struct expression *exp; - exp = parse_c_1 (&string, 0, 0); - if (*string) - error ("Junk after end of expression."); - return exp; -} diff --git a/gdb/expread.y b/gdb/expread.y index 996ca21..b112cbc 100644 --- a/gdb/expread.y +++ b/gdb/expread.y @@ -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); } diff --git a/gdb/expression.h b/gdb/expression.h index 0fac7be..7a7bd83 100644 --- a/gdb/expression.h +++ b/gdb/expression.h @@ -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 diff --git a/gdb/findvar.c b/gdb/findvar.c index 465e00a..e5f9b4a 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -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)); } diff --git a/gdb/gdb+.texinfo b/gdb/gdb+.texinfo deleted file mode 100644 index 0591073..0000000 --- a/gdb/gdb+.texinfo +++ /dev/null @@ -1,2795 +0,0 @@ -\input texinfo -@setfilename ../info/gdb -@settitle GDB+, The GNU Debugger for GNU C++ -@ifinfo -This file documents the GNU debugger GDB+. - -Copyright (C) 1988 Richard M. Stallman. -Modified by Michael Tiemann - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -@ignore -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -sections entitled ``Distribution'' and ``GDB General Public License'' are -included exactly as in the original, and provided that the entire resulting -derived work is distributed under the terms of a permission notice -identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that the sections entitled ``Distribution'' and ``GDB General Public -License'' may be included in a translation approved by the author instead -of in the original English. -@end ifinfo - -@setchapternewpage odd -@settitle GDB+ Manual -@titlepage -@sp 6 -@center @titlefont{GDB+ Manual} -@sp 1 -@center The GNU Source-Level Debugger for GNU C++ -@sp 4 -@center Second Edition, GDB+ version 2.5.0 -@sp 1 -@center February 1988 -@sp 5 -@center Richard M. Stallman -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 1988 Richard M. Stallman. -Modified by Michael Tiemann - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -sections entitled ``Distribution'' and ``GDB General Public License'' are -included exactly as in the original, and provided that the entire resulting -derived work is distributed under the terms of a permission notice -identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that the sections entitled ``Distribution'' and ``GDB General Public -License'' may be included in a translation approved by the author instead -of in the original English. -@end titlepage -@page - -@node Top, Commands,, (DIR) -@unnumbered Summary of GDB+ - -The purpose of a debugger such as GDB+ is to allow you to execute another -program while examining what is going on inside it. We call the other -program ``your program'' or ``the program being debugged''. - -GDB+ can do four kinds of things (plus other things in support of these): - -@enumerate -@item -Start the program, specifying anything that might affect its behavior. - -@item -Make the program stop on specified conditions. - -@item -Examine what has happened, when the program has stopped, so that you -can see bugs happen. - -@item -Change things in the program, so you can correct the effects of one bug -and go on to learn about another without having to recompile first. -@end enumerate - -@menu -* License:: The GDB General Public License gives you permission - to redistribute GDB+ on certain terms; and also - explains that there is no warranty. -* Input:: GDB+ command syntax and input conventions. -* Files:: Specifying files for GDB+ to operate on. -* Options:: GDB+ arguments and options. -* Compilation::Compiling your program so you can debug it. -* Running:: Running your program under GDB+. -* Stopping:: Making your program stop. Why it may stop. What to do then. -* Stack:: Examining your program's stack. -* Source:: Examining your program's source files. -* Data:: Examining data in your program. -* Symbols:: Examining the debugger's symbol table. -* Altering:: Altering things in your program. -* Sequences:: Canned command sequences for repeated use. -* Emacs:: Using GDB through GNU Emacs. -* Remote:: Remote kernel debugging across a serial line. -* Commands:: Index of GDB+ commands. -* Concepts:: Index of GDB+ concepts. -@end menu - -@node License, Input, Top, Top -@unnumbered GDB General Public License -@center (Clarified 11 Feb 1988) - - 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. - -@unnumberedsec Copying Policies - -@enumerate -@item -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 file a valid copyright notice ``Copyright -@copyright{} 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. - -@item -You may modify your copy or copies of GDB source code 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: - -@itemize @bullet -@item -cause the modified files to carry prominent notices stating -that you changed the files and the date of any change; and - -@item -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 some or all third parties, at your option). - -@item -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 -@copyright{} 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. - -@item -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. -@end itemize - -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. - -@item -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: - -@itemize @bullet -@item -accompany it with the complete corresponding machine-readable -source code, which must be distributed under the terms of -Paragraphs 1 and 2 above; or, - -@item -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, - -@item -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.) -@end itemize - -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. - -@item -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 GDB 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. - -@item -If you wish to incorporate parts of GDB into other free programs whose -distribution conditions are different, write to the Free Software -Foundation. 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 our free -software and of promoting the sharing and reuse of software. -@end enumerate - -@iftex -@vfil -@eject -@end iftex -@unnumberedsec 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, THE 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 THE PROGRAM IS WITH YOU. SHOULD THE GDB -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY -SERVICING, REPAIR OR CORRECTION. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL FREE SOFTWARE -FOUNDATION, INC., RICHARD M. STALLMAN, 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 PROGRAMS NOT DISTRIBUTED BY -FREE SOFTWARE FOUNDATION, INC.) THE PROGRAM, EVEN IF YOU HAVE BEEN -ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY -OTHER PARTY. - -@node Input, Files, License, Top -@chapter GDB+ Input Conventions - -GDB+ is invoked with the shell command @samp{gdb+}. Once started, it reads -commands from the terminal until you tell it to exit. - -A GDB+ command is a single line of input. There is no limit on how long -it can be. It starts with a command name, which is followed by arguments -whose meaning depends on the command name. Some command names do not -allow arguments. - -GDB+ command names may always be abbreviated if the abbreviation is -unambiguous. Sometimes even ambiguous abbreviations are allowed; for -example, @samp{s} is specially defined as equivalent to @samp{step} -even though there are other commands whose names start with @samp{s}. -Possible command abbreviations are often stated in the documentation -of the individual commands. - -A blank line as input to GDB+ means to repeat the previous command verbatim. -Certain commands do not allow themselves to be repeated this way; these are -commands for which unintentional repetition might cause trouble and which -you are unlikely to want to repeat. Certain others (@samp{list} and -@samp{x}) act differently when repeated because that is more useful. - -A line of input starting with @samp{#} is a comment; it does nothing. -This is useful mainly in command files (@xref{Command Files}). - -GDB+ @dfn{prompts} for commands with a string that is normally @samp{(gdb+)}. -When debugging GDB+ with GDB+, it is useful to change the prompt in one of -the GDB+s so that you can distinguish them. This can be done with the -@samp{set-prompt} command. - -@table @code -@item set-prompt @var{newprompt} -@kindex set-prompt -Directs GDB+ to use @var{newprompt} as its prompt string henceforth. -@end table - -@cindex exiting GDB+ -@kindex quit -To exit GDB+, use the @samp{quit} command (abbreviated @samp{q}). -@kbd{Ctrl-c} will not exit from GDB+, but rather will terminate the action -of any GDB+ command that is in progress and return to GDB+ command level. -It is safe to type @kbd{Ctrl-c} at any time because GDB+ does not allow -it to take effect until a time when it is safe. - -@node Files, Options, Input, Top -@chapter Specifying GDB+'s Files - -@cindex core dump file -@cindex executable file -@cindex symbol table -GDB+ needs to know the filename of the program to be debugged. To debug a -core dump of a previous run, GDB+ must be told the filename of the core -dump. - -@menu -* Arguments: File Arguments. Specifying files with arguments - (when you start GDB+). -* Commands: File Commands. Specifying files with GDB+ commands. -@end menu - -@node File Arguments, File Commands, Files, Files -@section Specifying Files with Arguments - -The usual way to specify the executable and core dump file names is with -two command arguments given when you start GDB+. The first argument is used -as the file for execution and symbols, and the second argument (if any) is -used as the core dump file name. Thus, - -@example -GDB+ progm core -@end example - -@noindent -specifies @file{progm} as the executable program and @file{core} as a core -dump file to examine. (You do not need to have a core dump file if what -you plan to do is debug the program interactively.) - -@xref{Options}, for full information on command options and arguments for -GDB+. - -@node File Commands,, File Arguments, Files -@section Specifying Files with Commands - -Usually you specify the files for GDB+ to work with by giving arguments when -you invoke GDB+. But occasionally it is necessary to change to a different -file during a GDB+ session. Or you may run GDB+ and forget to specify the -files you want to use. In these situations the GDB+ commands to specify new -files are useful. - -@table @code -@item exec-file @var{filename} -@kindex exec-file -Specify that the program to be run is found in @var{filename}. If you -do not specify a directory and the file is not found in GDB+'s working -directory, GDB+ will use the environment variable @samp{PATH} as a list -of directories to search, just as the shell does when looking for a -program to run. - -@item symbol-file @var{filename} -@kindex symbol-file -Read symbol table information from file @var{filename}. @samp{PATH} -is searched when necessary. Most of the time you will use both the -@samp{exec-file} and @samp{symbol-file} commands on the same file. - -@samp{symbol-file} with no argument clears out GDB+'s symbol table. - -@item core-file @var{filename} -@kindex core-file -Specify the whereabouts of a core dump file to be used as the -``contents of memory''. Note that the core dump contains only the -writable parts of memory; the read-only parts must come from the -executable file. - -@samp{core-file} with no argument specifies that no core file is -to be used. - -@item add-file @var{filename} @var{address} -When performing incremental linking, the symbol table of an incrementally -linked file may be included in the link step, but GDB+ needs to be told -where that symbol table is in the address space. By issuing this command, -it is possible to symbolically debug programs which make use of incremental -loading in a completely natural fashion. - -@item kill -@kindex kill -Cancel running the program under GDB+. This could be used if you wish -to debug a core dump instead. GDB+ ignores any core dump file if it is -actually running the program, so the @samp{kill} command is the only -sure way to go back to using the core dump file. - -@item info files -@kindex info files -Print the names of the executable and core dump files currently in -use by GDB+, and the file from which symbols were loaded. -@end table - -While all three file-specifying commands allow both absolute and relative -file names as arguments, GDB+ always converts the file name to an absolute -one and remembers it that way. - -The @samp{symbol-file} command causes GDB+ to forget the contents of its -convenience variables, the value history, and all breakpoints and -auto-display expressions. This is because they may contain pointers to the -internal data recording symbols and data types, which are part of the old -symbol table data being discarded inside GDB+. - -@node Options, Compilation, Files, Top -@chapter Options and Arguments for GDB+ - -When you invoke GDB+, you can pass commands telling it what files to -operate on and what other things to do. - -@menu -* Mode Options:: Options controlling modes of operation. -* File Options:: Options to specify files (executable, coredump, commands) -* Other Arguments:: Any other arguments without options - also specify files. -@end menu - -@node Mode Options, File Options, Options, Options -@section Mode Options - -@table @samp -@item -nx -Do not execute commands from the init files @file{.gdbinit}. -Normally, the commands in these files are executed after all the -command options and arguments have been processed. @xref{Command -Files}. - -@item -q -``Quiet''. Do not print the usual introductory messages. - -@item -batch -Run in batch mode. Exit with code 1 after processing all the command -files specified with @samp{-x} (and @file{./.gdbinit}, if not inhibited). -Exit also if, due to an error, GDB+ would otherwise attempt to read a -command from the terminal. - -@item -fullname -This option is used when Emacs runs GDB as a subprocess. It tells GDB -to output the full file name and line number in a standard, -recognizable fashion each time a stack frame is displayed (which -includes each time the program stops). This recognizable format looks -like two @samp{\032} characters, followed by the filename, line number -and character position separated by colons, and a newline. The -Emacs-to-GDB interface program uses the two @samp{\032} characters as -a signal to display the source code for the frame. -@end table - -@node File Options, Other Arguments, Mode Options, Options -@section File-specifying Options - -All the options and command line arguments given are processed -in sequential order. The order makes a difference when the -@samp{-x} command is used. - -@table @samp -@item -s @var{file} -Read symbol table from file @var{file}. - -@item -e @var{file} -Use file @var{file} as the executable file to execute when -appropriate, and for examining pure data in conjunction with a core -dump. - -@item -se @var{file} -Read symbol table from file @var{file} and use it as the executable -file. - -@item -c @var{file} -Use file @var{file} as a core dump to examine. - -@item -x @var{file} -Execute GDB+ commands from file @var{file}. - -@item -d @var{directory} -Add @var{directory} to the path to search for source files. -@end table - -@node Other Arguments,, File Options, Options -@section Other Arguments - -If there are arguments to GDB+ that are not options or associated with -options, the first one specifies the symbol table and executable file name -(as if it were preceded by @samp{-se}) and the second one specifies a core -dump file name (as if it were preceded by @samp{-c}). - -@node Compilation, Running, Options, Top -@chapter Compiling Your Program for Debugging - -In order to debug a program effectively, you need to ask for debugging -information when you compile it. This information in the object file -describes the data type of each variable or function and the correspondence -between source line numbers and addresses in the executable code. - -To request debugging information, specify the @samp{-g} option when you run -the compiler. - -The Unix C compiler is unable to handle the @samp{-g} and @samp{-O} options -together. This means that you cannot ask for optimization if you ask for -debugger information. - -The GNU C compiler supports @samp{-g} with or without @samp{-O}, making it -possible to debug optimized code. We recommend that you @emph{always} use -@samp{-g} whenever you compile a program. You may think the program is -correct, but there's no sense in pushing your luck. - -If you are using the GNU C compiler, the GNU assembler and the GNU linker, -you can choose between two formats of debugging information: the standard -Unix format, which is what you get with @samp{-g}, and GDB's own format, -which you request by using @samp{-gg} instead of @samp{-g}. This stores -debugging information in the executable file in a format much like that -which is used inside GDB. This has these advantages and disadvantages: - -@itemize @bullet -@item -GDB can read @samp{-gg} format more than twice as fast as Unix -@samp{-g} format. - -@item -The @samp{-gg} format uses much more disk space than Unix format. - -@item -The Unix debuggers can understand only Unix format, so you cannot use -Unix source-level debuggers if you compile with @samp{-gg}. (The -@code{adb} debugger works with either format; it does not use this -information in any case.) -@end itemize - -@node Running, Stopping, Compilation, Top -@chapter Running Your Program Under GDB+ - -@cindex running -@kindex run -To start your program under GDB+, use the @samp{run} command. The program -must already have been specified using the @samp{exec-file} command or with -an argument to GDB+ (@pxref{Files}); what @samp{run} does is create an -inferior process, load the program into it, and set it in motion. - -The execution of a program is affected by certain information it receives -from its superior. GDB+ provides ways to specify them, which you must do -@i{before} starting the program. (You can change them after starting the -program, but such changes do not affect the program unless you start it -over again.) - -@table @asis -@item The @i{arguments.} -You specify the arguments to give the program as the arguments of the -@samp{run} command. - -@item The @i{environment.} -The program normally inherits its environment from GDB+, but you can -use the GDB+ commands @samp{set-environment} and -@samp{unset-environment} to change parts of the environment that will -be given to the program.@refill - -@item The @i{working directory.} -The program inherits its working directory from GDB+. You can set GDB+'s -working directory with the @samp{cd} command in GDB+. -@end table - -After the @samp{run} command, the debugger does nothing but wait for your -program to stop. @xref{Stopping}. - -@menu -* Arguments:: Specifying the arguments for your program. -* Environment:: Specifying the environment for your program. -* Working Directory:: Specifying the working directory for giving - to your program when it is run. -* Input/Output:: Specifying the program's standard input and output. -* Attach:: Debugging a process started outside GDB. -@end menu - -@node Arguments, Environment, Running, Running -@section Your Program's Arguments - -@cindex arguments (to your program) -You specify the arguments to give the program as the arguments of the -@samp{run} command. They are passed to a shell, which expands wildcard -characters and performs redirection of I/O, and thence to the program. - -@samp{run} with no arguments uses the same arguments used by the previous -@samp{run}. - -@kindex set-args -The command @samp{set-args} can be used to specify the arguments to be used -the next time the program is run. If @samp{set-args} has no arguments, it -means to use no arguments the next time the program is run. If you have -run your program with arguments and want to run it again with no arguments, -this is the only way to do so. - -@node Environment, Working Directory, Arguments, Running -@section Your Program's Environment - -@cindex environment (of your program) -The @dfn{environment} consists of a set of @dfn{environment variables} and -their values. Environment variables conventionally record such things as -your user name, your home directory, your terminal type, and your search -path for programs to run. Usually you set up environment variables with -the shell and they are inherited by all the other programs you run. When -debugging, it can be useful to try running the program with different -environments without having to start the debugger over again. - -@table @code -@item info environment @var{varname} -@kindex info environment -Print the value of environment variable @var{varname} to be given to -your program when it is started. This command can be abbreviated -@samp{i env @var{varname}}. - -@item info environment -Print the names and values of all environment variables to be given to -your program when it is started. This command can be abbreviated -@samp{i env}. - -@item set-environment @var{varname} @var{value} -@kindex set-environment -Sets environment variable @var{varname} to @var{value}, for your -program only, not for GDB+ itself. @var{value} may be any string; the -values of environment variables are just strings, and any -interpretation is supplied by your program itself. This command -can be abbreviated as short as @samp{set-e}. - -@item unset-environment @var{varname} -@kindex unset-environment -Remove variable @var{varname} from the environment to be passed to -your program. This is different from @samp{set-env @var{varname} =} -because @samp{unset-environment} makes a variable not be defined at -all, which is distinguishable from an empty value. This command can -be abbreviated @samp{unset}. -@end table - -@node Working Directory, Input/Output, Environment, Running -@section Your Program's Working Directory - -@cindex working directory (of your program) -Each time you start your program with @samp{run}, it inherits its working -directory from the current working directory of GDB+. GDB+'s working -directory is initially whatever it inherited from its superior, but you can -specify the working directory for GDB+ with the @samp{cd} command. - -The GDB+ working directory also serves as a default for the commands -that specify files for GDB+ to operate on. @xref{Files}. - -@table @code -@item cd @var{directory} -@kindex cd -Set GDB+'s working directory to @var{directory}. - -@item pwd -@kindex pwd -Print GDB+'s working directory. -@end table - -@node Input/Output, Attach, Working Directory, Running -@section Your Program's Input and Output - -@cindex redirection -By default, the program you run under GDB does input and output to the same -terminal that GDB uses. - -You can redirect the program's input and/or output using @samp{sh}-style -redirection commands in the @samp{run} command. For example, - -@example -run > outfile -@end example - -@noindent -starts the program, diverting its output to the file @file{outfile}. - -@kindex tty -Another way to specify where the program should do input and output is with -the @samp{tty} command. This command accepts a file name as argument, and -causes this file to be the default for future @samp{run} commands. For -example, - -@example -tty /dev/ttyb -@end example - -@noindent -directs that processes started with subsequent @samp{run} commands default -to do input and output on the terminal @file{/dev/ttyb}. An explicit -redirection in @samp{run} overrides the @samp{tty} command. - -When you use the @samp{tty} command or redirect input in the @samp{run} -command, the @emph{input for your program} comes from the specified file, -but the input for GDB still comes from your terminal. The program's -controlling terminal is your (GDB's) terminal, not the terminal that the -program is reading from; so if you want to type @kbd{C-c} to stop the -program, you must type it on your (GDB's) terminal. A @kbd{C-c} typed on -the program's terminal is available to the program as ordinary input. - -@node Attach,, Input/Output, Running -@section Debugging an Already-Running Process -@kindex detach -@kindex attach -@cindex attach - -Some operating systems (in particular, Sun) allow GDB to begin debugging an -already-running process that was started outside of GDB. To do this you -must use the @samp{attach} command instead of the @samp{run} command. - -The @samp{attach} command requires one argument, which is the process-id of -the process you want to debug. (The usual way to find out the process-id -of the process is with the @samp{ps} utility.) - -The first thing GDB after arranging to debug the process is to stop it. -You can examine and modify an attached process with all the GDB commands -that ordinarily available when you start processes with @samp{run}. You -can insert breakpoints; you can step and continue; you can modify storage. -If you would rather the process continue running, use the @samp{continue} -command after attaching. - -When you are finished debugging the attached process, you can use the -@samp{detach} command to release it from GDB's control. Detaching -the process continues its execution. After the @samp{detach} command, -that process and GDB become completely independent once more, and you -are ready to @samp{attach} another process or start one with @samp{run}. - -If you exit GDB or use the @samp{run} command while you have an attached -process, you kill that process. You will be asked for confirmation if you -try to do either of these things. - -@node Stopping, Stack, Running, Top -@chapter Stopping and Continuing - -When you run a program normally, it runs until exiting. The purpose -of using a debugger is so that you can stop it before that point; -or so that if the program runs into trouble you can find out why. - -@menu -* Signals:: Fatal signals in your program just stop it; - then you can use GDB+ to see what is going on. -* Breakpoints:: Breakpoints let you stop your program when it - reaches a specified point in the code. -* Continuing:: Resuming execution until the next signal or breakpoint. -* Stepping:: Stepping runs the program a short distance and - then stops it wherever it has come to. -@end menu - -@node Signals, Breakpoints, Stopping, Stopping -@section Signals - -A signal is an asynchronous event that can happen in a program. The -operating system defines the possible kinds of signals, and gives each kind -a name and a number. For example, @code{SIGINT} is the signal a program -gets when you type @kbd{Ctrl-c}; @code{SIGSEGV} is the signal a program -gets from referencing a place in memory far away from all the areas in use; -@code{SIGALRM} occurs when the alarm clock timer goes off (which happens -only if the program has requested an alarm). - -Some signals, including @code{SIGALRM}, are a normal part of the -functioning of the program. Others, such as @code{SIGSEGV}, indicate -errors; these signals are @dfn{fatal} (kill the program immediately) if the -program has not specified in advance some other way to handle the signal. -@code{SIGINT} does not indicate an error in the program, but it is normally -fatal so it can carry out the purpose of @kbd{Ctrl-c}: to kill the program. - -GDB+ has the ability to detect any occurrence of a signal in the program -running under GDB+'s control. You can tell GDB+ in advance what to do for -each kind of signal. - -Normally, GDB+ is set up to ignore non-erroneous signals like @code{SIGALRM} -(so as not to interfere with their role in the functioning of the program) -but to stop the program immediately whenever an error signal happens. -You can change these settings with the @samp{handle} command. You must -specify which signal you are talking about with its number. - -@table @code -@item info signal -@kindex info signal -Print a table of all the kinds of signals and how GDB+ has been told to -handle each one. You can use this to see the signal numbers of all -the defined types of signals. - -@item handle @var{signalnum} @var{keywords}@dots{} -@kindex handle -Change the way GDB+ handles signal @var{signalnum}. The @var{keywords} -say what change to make. -@end table - -To use the @samp{handle} command you must know the code number of the -signal you are concerned with. To find the code number, type @samp{info -signal} which prints a table of signal names and numbers. - -The keywords allowed by the handle command can be abbreviated. Their full -names are - -@table @code -@item stop -GDB+ should stop the program when this signal happens. This implies -the @samp{print} keyword as well. - -@item print -GDB+ should print a message when this signal happens. - -@item nostop -GDB+ should not stop the program when this signal happens. It may -still print a message telling you that the signal has come in. - -@item noprint -GDB+ should not mention the occurrence of the signal at all. This -implies the @samp{nostop} keyword as well. - -@item pass -GDB+ should allow the program to see this signal; the program will be -able to handle the signal, or may be terminated if the signal is fatal -and not handled. - -@item nopass -GDB+ should not allow the program to see this signal. -@end table - -When a signal has been set to stop the program, the program cannot see the -signal until you continue. It will see the signal then, if @samp{pass} is -in effect for the signal in question @i{at that time}. In other words, -after GDB+ reports a signal, you can use the @samp{handle} command with -@samp{pass} or @samp{nopass} to control whether that signal will be seen by -the program when you later continue it. - -You can also use the @samp{signal} command to prevent the program from -seeing a signal, or cause it to see a signal it normally would not see, -or to give it any signal at any time. @xref{Signaling}. - -@node Breakpoints, Continuing, Signals, Stopping -@section Breakpoints - -@cindex breakpoints -A @dfn{breakpoint} makes your program stop whenever a certain point in the -program is reached. You set breakpoints explicitly with GDB+ commands, -specifying the place where the program should stop by line number, function -name or exact address in the program. You can add various other conditions -to control whether the program will stop. - -Each breakpoint is assigned a number when it is created; these numbers are -successive integers starting with 1. In many of the commands for controlling -various features of breakpoints you use the breakpoint number to say which -breakpoint you want to change. Each breakpoint may be @dfn{enabled} or -@dfn{disabled}; if disabled, it has no effect on the program until you -enable it again. - -@kindex info break -@kindex $_ -The command @samp{info break} prints a list of all breakpoints set and not -cleared, showing their numbers, where in the program they are, and any -special features in use for them. Disabled breakpoints are included in the -list, but marked as disabled. @samp{info break} with a breakpoint number -as argument lists only that breakpoint. The convenience variable @samp{$_} -and the default examining-address for the @samp{x} command are set to the -address of the last breakpoint listed (@pxref{Memory}). - -@menu -* Set Breaks:: How to establish breakpoints. -* Clear Breaks:: How to remove breakpoints no longer needed. -* Disabling:: How to disable breakpoints (turn them off temporarily). -* Conditions:: Making extra conditions on whether to stop. -* Break Commands:: Commands to be executed at a breakpoint. -* Error in Breakpoints:: "Cannot insert breakpoints" error--why, what to do. -@end menu - -@node Set Breaks, Clear Breaks, Breakpoints, Breakpoints -@subsection Setting Breakpoints - -@kindex break -Breakpoints are set with the @samp{break} command (abbreviated @samp{b}). -You have several ways to say where the breakpoint should go. - -@table @code -@item break @var{function} -Set a breakpoint at entry to function @var{function}. - -@item break @var{linenum} -Set a breakpoint at line @var{linenum} in the current source file. -That file is the last file whose source text was printed. This -breakpoint will stop the program just before it executes any of the -code on that line. - -@item break @var{filename}:@var{linenum} -Set a breakpoint at line @var{linenum} in source file @var{filename}. - -@item break @var{filename}:@var{function} -Set a breakpoint at entry to function @var{function} found in file -@var{filename}. Specifying a filename as well as a function name is -superfluous except when multiple files contain similarly named -functions. - -@item break *@var{address} -Set a breakpoint at address @var{address}. You can use this to set -breakpoints in parts of the program which do not have debugging -information or source files. - -@item break -Set a breakpoint at the next instruction to be executed in the -selected stack frame (@pxref{Stack}). This is a silly thing to do in -the innermost stack frame because the program would stop immediately -after being started, but it is very useful with another stack frame, -because it will cause the program to stop as soon as control returns -to that frame. - -@item break @dots{} if @var{cond} -Set a breakpoint with condition @var{cond}; evaluate the expression -@var{cond} each time the breakpoint is reached, and stop only if the -value is nonzero. @samp{@dots{}} stands for one of the possible -arguments described above (or no argument) specifying where to break. -@xref{Conditions}, for more information on breakpoint conditions. - -@item tbreak @var{args} -@kindex tbreak -Set a breakpoint enabled only for one stop. @var{args} are the -same as in the @samp{break} command, and the breakpoint is set in the same -way, but the breakpoint is automatically @dfn{disabled} the first time it -is hit. -@end table - -GDB allows you to set any number of breakpoints at the same place in the -program. There is nothing silly or meaningless about this. When the -breakpoints are conditional, this is even useful (@pxref{Conditions}). - -@node Clear Breaks, Disabling, Set Breaks, Breakpoints -@subsection Clearing Breakpoints - -@cindex clear breakpoint -@cindex delete breakpoints -It is often necessary to eliminate a breakpoint once it has done its job -and you no longer want the program to stop there. This is called -@dfn{clearing} or @samp{deleting} the breakpoint. A breakpoint that -has been cleared no longer exists in any sense. - -With the @samp{clear} command you can clear breakpoints according to where -they are in the program. With the @samp{delete} command you can clear -individual breakpoints by specifying their breakpoint numbers. - -@b{It is not necessary to clear a breakpoint to proceed past it.} GDB+ -automatically ignores breakpoints in the first instruction to be executed -when you continue execution at the same address where the program stopped. - -@table @code -@item clear -@kindex clear -Clear any breakpoints at the next instruction to be executed in the -selected stack frame (@pxref{Selection}). When the innermost frame -is selected, this is a good way to clear a breakpoint that the program -just stopped at. - -@item clear @var{function} -@itemx clear @var{filename}:@var{function} -Clear any breakpoints set at entry to the function @var{function}. - -@item clear @var{linenum} -@item clear @var{filename}:@var{linenum} -Clear any breakpoints set at or within the code of the specified line. - -@item delete @var{bnums}@dots{} -@kindex delete -Delete the breakpoints of the numbers specified as arguments. -A breakpoint deleted is forgotten completely. -@end table - -@node Disabling, Conditions, Clear Breaks, Breakpoints -@subsection Disabling Breakpoints - -@cindex disabled breakpoints -@cindex enabled breakpoints -Rather than clearing a breakpoint, you might prefer to @dfn{disable} it. -This makes the breakpoint inoperative as if it had been cleared, but -remembers the information on the breakpoint so that you can @dfn{enable} -it again later. - -You disable and enable breakpoints with the @samp{enable} and -@samp{disable} commands, specifying one or more breakpoint numbers as -arguments. Use @samp{info break} to print a list of breakpoints if you -don't know which breakpoint numbers to use. - -A breakpoint can have any of four different states of enablement: - -@itemize @bullet -@item -Enabled. The breakpoint will stop the program. A breakpoint made -with the @samp{break} command starts out in this state. -@item -Disabled. The breakpoint has no effect on the program. -@item -Enabled once. The breakpoint will stop the program, but -when it does so it will become disabled. A breakpoint made -with the @samp{tbreak} command starts out in this state. -@item -Enabled for deletion. The breakpoint will stop the program, but -immediately after it does so it will be deleted permanently. -@end itemize - -You change the state of enablement of a breakpoint with the following -commands: - -@table @code -@item disable @var{bnums}@dots{} -@kindex disable -Disable the specified breakpoints. A disabled breakpoint has no -effect but is not forgotten. All options such as ignore-counts, -conditions and commands are remembered in case the breakpoint is -enabled again later. - -@item enable @var{bnums}@dots{} -@kindex enable -Enable the specified breakpoints. They become effective once again in -stopping the program, until you specify otherwise. - -@item enable once @var{bnums}@dots{} -Enable the specified breakpoints temporarily. Each will be disabled -again the next time it stops the program (unless you have used one of -these commands to specify a different state before that time comes). - -@item enable delete @var{bnums}@dots{} -Enable the specified breakpoints to work once and then die. Each of -the breakpoints will be deleted the next time it stops the program -(unless you have used one of these commands to specify a different -state before that time comes). -@end table - -Aside from the automatic disablement or deletion of a breakpoint when it -stops the program, which happens only in certain states, the state of -enablement of a breakpoint changes only when one of the commands above -is used. - -@node Conditions, Break Commands, Disabling, Breakpoints -@subsection Break Conditions - -@cindex conditions -The simplest sort of breakpoint breaks every time the program reaches a -specified place. You can also specify a @dfn{condition} for a breakpoint. -A condition is just a boolean expression in your programming language. -A breakpoint with a condition evaluates the expression each time the -program reaches it, and the program stops only if the condition is true. - -Break conditions may have side effects, and may even call functions in your -program. These may sound like strange things to do, but their effects are -completely predictable unless there is another enabled breakpoint at the -same address. (In that case, GDB+ might see the other breakpoint first and -stop the program without checking the condition of this one.) Note that -breakpoint commands are usually more convenient and flexible for the -purpose of performing side effects when a breakpoint is reached -(@pxref{Break Commands}). - -Break conditions can be specified when a breakpoint is set, by using -@samp{if} in the arguments to the @samp{break} command. @xref{Set Breaks}. -They can also be changed at any time with the @samp{condition} command: - -@table @code -@item condition @var{bnum} @var{expression} -@kindex condition -Specify @var{expression} as the break condition for breakpoint number -@var{bnum}. From now on, this breakpoint will stop the program only if -the value of @var{expression} is true (nonzero, in C). @var{expression} -is not evaluated at the time the @samp{condition} command is given. - -@item condition @var{bnum} -Remove the condition from breakpoint number @var{bnum}. It becomes -an ordinary unconditional breakpoint. -@end table - -@cindex ignore count (of breakpoint) -A special feature is provided for one kind of condition: to prevent the -breakpoint from doing anything until it has been reached a certain number -of times. This is done with the @dfn{ignore count} of the breakpoint. -When the program reaches a breakpoint whose ignore count is positive, then -instead of stopping, it just decrements the ignore count by one and -continues. - -@table @code -@item ignore @var{bnum} @var{count} -@kindex ignore -Set the ignore count of breakpoint number @var{bnum} to @var{count}. -The next @var{count} times the breakpoint is reached, it will not stop. - -To make the breakpoint stop the next time it is reached, specify -a count of zero. - -@item cont @var{count} -Continue execution of the program, setting the ignore count of the -breakpoint that the program stopped at to @var{count} minus one. -Continuing through the breakpoint does not itself count as one of -@var{count}. Thus, the program will not stop at this breakpoint until the -@var{count}'th time it is hit. - -This command is allowed only when the program stopped due to a -breakpoint. At other times, the argument to @samp{cont} is ignored. -@end table - -If a breakpoint has a positive ignore count and a condition, the condition -is not checked. Once the ignore count reaches zero, the condition will -start to be checked. - -Note that you could achieve the effect of the ignore count with a condition -such as @samp{$foo-- <= 0} using a debugger convenience variable that is -decremented each time. That is why the ignore count is considered a -special case of a condition. @xref{Convenience Vars}. - -@node Break Commands, Error in Breakpoints, Conditions, Breakpoints -@subsection Commands Executed on Breaking - -@cindex breakpoint commands -You can give any breakpoint a series of commands to execute when the -program stops due to that breakpoint. For example, you might want to -print the values of certain expressions, or enable other breakpoints. - -@table @code -@item commands @var{bnum} -Specify commands for breakpoint number @var{bnum}. The commands -themselves appear on the following lines. Type a line containing just -@samp{end} to terminate the commands. - -To remove all commands from a breakpoint, use the command -@samp{commands} and follow it immediately by @samp{end}; that is, give -no commands. -@end table - -It is possible for breakpoint commands to start the program up again. -Simply use the @samp{cont} command, or @samp{step}, or any other command -to resume execution. However, any remaining breakpoint commands are -ignored. When the program stops again, GDB+ will act according to why -that stop took place. - -@kindex silent -If the first command specified is @samp{silent}, the usual message about -stopping at a breakpoint is not printed. This may be desirable for -breakpoints that are to print a specific message and then continue. -If the remaining commands too print nothing, you will see no sign that -the breakpoint was reached at all. @samp{silent} is not really a command; -it is meaningful only at the beginning of the commands for a breakpoint. - -The commands @samp{echo} and @samp{output} that allow you to print precisely -controlled output are often useful in silent breakpoints. @xref{Output}. - -For example, here is how you could use breakpoint commands to print the -value of @code{x} at entry to @code{foo} whenever it is positive. We -assume that the newly created breakpoint is number 4; @samp{break} will -print the number that is assigned. - -@example -break foo if x>0 -commands 4 -silent -echo x is\040 -output x -echo \n -cont -end -@end example - -One application for breakpoint commands is to correct one bug so you can -test another. Put a breakpoint just after the erroneous line of code, give -it a condition to detect the case in which something erroneous has been -done, and give it commands to assign correct values to any variables that -need them. End with the @samp{cont} command so that the program does not -stop, and start with the @samp{silent} command so that no output is -produced. Here is an example: - -@example -break 403 -commands 5 -silent -set x = y + 4 -cont -end -@end example - -One deficiency in the operation of automatically continuing breakpoints -under Unix appears when your program uses raw mode for the terminal. -GDB+ options back to its own terminal modes (not raw) before executing -commands, and then must switch back to raw mode when your program is -continued. This causes any pending terminal input to be lost. - -In the GNU system, this will be fixed by changing the behavior of -terminal modes. - -Under Unix, when you have this problem, you might be able to get around -it by putting your actions into the breakpoint condition instead of -commands. For example - -@example -condition 5 (x = y + 4), 0 -@end example - -@noindent -is a condition expression that will change @code{x} as needed, then always -have the value 0 so the program will not stop. Loss of input is avoided -here because break conditions are evaluated without changing the terminal -modes. When you want to have nontrivial conditions for performing the side -effects, the operators @samp{&&}, @samp{||} and @samp{?@: @dots{} :@:} may be useful. - -@node Error in Breakpoints,, Break Commands, Breakpoints -@subsection ``Cannot Insert Breakpoints'' Error - -Under Unix, breakpoints cannot be used in a program if any other process -is running that program. Attempting to run or continue the program with -a breakpoint in this case will cause GDB+ to stop it. - -When this happens, you have two ways to proceed: - -@enumerate -@item -Remove or disable the breakpoints, then continue. - -@item -Suspend GDB+, and copy the file containing the program to a new name. -Resume GDB+ and use the @samp{exec-file} command to specify that GDB+ -should run the program under that name. Then start the program again. -@end enumerate - -@node Continuing, Stepping, Breakpoints, Stopping -@section Continuing - -After your program stops, most likely you will want it to run some more if -the bug you are looking for has not happened yet. - -@table @code -@item cont -Continue running the program at the place where it stopped. -@end table - -If the program stopped at a breakpoint, the place to continue running -is the address of the breakpoint. You might expect that continuing would -just stop at the same breakpoint immediately. In fact, @samp{cont} -takes special care to prevent that from happening. You do not need -to clear the breakpoint to proceed through it after stopping at it. - -You can, however, specify an ignore-count for the breakpoint that the -program stopped at, by means of an argument to the @samp{cont} command. -@xref{Conditions}. - -If the program stopped because of a signal other than @code{SIGINT} or -@code{SIGTRAP}, continuing will cause the program to see that signal. -You may not want this to happen. For example, if the program stopped -due to some sort of memory reference error, you might store correct -values into the erroneous variables and continue, hoping to see more -execution; but the program would probably terminate immediately as -a result of the fatal signal once it sees the signal. To prevent this, -you can continue with @samp{signal 0}. @xref{Signaling}. You can -also act in advance to prevent the program from seeing certain kinds -of signals, using the @samp{handle} command (@pxref{Signals}). - -@node Stepping,, Continuing, Stopping -@section Stepping - -@cindex stepping -@dfn{Stepping} means setting your program in motion for a limited time, so -that control will return automatically to the debugger after one line of -code or one machine instruction. Breakpoints are active during stepping -and the program will stop for them even if it has not gone as far as the -stepping command specifies. - -@table @code -@item step -@kindex step -Proceed the program until control reaches a different line, then stop -it and return to the debugger. This command is abbreviated @samp{s}. - -@item step @var{count} -Proceed as in @samp{step}, but do so @var{count} times. If a breakpoint -or a signal not related to stepping is reached before @var{count} steps, -stepping stops right away. - -@item next -@kindex next -Similar to @samp{step}, but any function calls appearing within the line of -code are executed without stopping. Execution stops when control reaches a -different line of code at the stack level which was executing when the -@samp{next} command was given. This command is abbreviated @samp{n}. - -An argument is a repeat count, as in @samp{step}. - -@item finish -@kindex finish -Continue running until just after the selected stack frame returns -(or until there is some other reason to stop, such as a fatal signal -or a breakpoint). - -Contrast this with the @samp{return} command (@pxref{Returning}). - -@item stepi -@itemx si -@kindex stepi -@kindex si -Proceed one machine instruction, then stop and return to the debugger. - -It is often useful to do @samp{display/i $pc} when stepping by machine -instructions. This will cause the next instruction to be executed to -be displayed automatically at each stop. @xref{Auto Display}. - -An argument is a repeat count, as in @samp{step}. - -@item nexti -@itemx ni -@kindex nexti -@kindex ni -Proceed one machine instruction, but if it is a subroutine call, -proceed until the subroutine returns. - -An argument is a repeat count, as in @samp{next}. -@end table - -A typical technique for using stepping is to put a breakpoint -(@pxref{Breakpoints}) at the beginning of the function or the section of -the program in which a problem is believed to lie, and then step through -the suspect area, examining the variables that are interesting, until the -problem happens. - -The @samp{cont} command can be used after stepping to resume execution -until the next breakpoint or signal. - -@node Stack, Source, Stopping, Top -@chapter Examining the Stack - -When your program has stopped, the first thing you need to know is where it -stopped and how it got there. - -@cindex call stack -Each time your program performs a function call, the information about -where in the program the call was made from is saved in a block of data -called a @dfn{stack frame}. The frame also contains the arguments of the -call and the local variables of the function that was called. All the -stack frames are allocated in a region of memory called the @dfn{call -stack}. - -When your program stops, the GDB+ commands for examining the stack allow you -to see all of this information. - -One of the stack frames is @dfn{selected} by GDB+ and many GDB+ commands -refer implicitly to the selected frame. In particular, whenever you ask -GDB+ for the value of a variable in the program, the value is found in the -selected frame. There are special GDB+ commands to select whichever frame -you are interested in. - -When the program stops, GDB+ automatically selects the currently executing -frame and describes it briefly as the @samp{frame} command does -(@pxref{Frame Info, Info}). - -@menu -* Frames:: Explanation of stack frames and terminology. -* Backtrace:: Summarizing many frames at once. -* Selection:: How to select a stack frame. -* Info: Frame Info, Commands to print information on stack frames. -@end menu - -@node Frames, Backtrace, Stack, Stack -@section Stack Frames - -@cindex frame -The call stack is divided up into contiguous pieces called @dfn{frames}; -each frame is the data associated with one call to one function. The frame -contains the arguments given to the function, the function's local -variables, and the address at which the function is executing. - -@cindex initial frame -@cindex outermost frame -@cindex innermost frame -When your program is started, the stack has only one frame, that of the -function @code{main}. This is called the @dfn{initial} frame or the -@dfn{outermost} frame. Each time a function is called, a new frame is -made. Each time a function returns, the frame for that function invocation -is eliminated. If a function is recursive, there can be many frames for -the same function. The frame for the function in which execution is -actually occurring is called the @dfn{innermost} frame. This is the most -recently created of all the stack frames that still exist. - -@cindex frame pointer -Inside your program, stack frames are identified by their addresses. A -stack frame consists of many bytes, each of which has its own address; each -kind of computer has a convention for choosing one of those bytes whose -address serves as the address of the frame. Usually this address is kept -in a register called the @dfn{frame pointer register} while execution is -going on in that frame. - -@cindex frame number -GDB+ assigns numbers to all existing stack frames, starting with zero for -the innermost frame, one for the frame that called it, and so on upward. -These numbers do not really exist in your program; they are to give you a -way of talking about stack frames in GDB+ commands. - -@cindex selected frame -Many GDB+ commands refer implicitly to one stack frame. GDB+ records a stack -frame that is called the @dfn{selected} stack frame; you can select any -frame using one set of GDB+ commands, and then other commands will operate -on that frame. When your program stops, GDB+ automatically selects the -innermost frame. - -@node Backtrace, Selection, Frames, Stack -@section Backtraces - -A backtrace is a summary of how the program got where it is. It shows one -line per frame, for many frames, starting with the currently executing -frame (frame zero), followed by its caller (frame one), and on up the -stack. - -@table @code -@item backtrace -@itemx bt -Print a backtrace of the entire stack: one line per frame for all -frames in the stack. - -You can stop the backtrace at any time by typing the system interrupt -character, normally @kbd{Control-C}. - -@item backtrace @var{n} -@itemx bt @var{n} -Similar, but stop after @var{n} frames. -@end table - -Each line in a backtrace shows the frame number, the program counter, the -function and its arguments, and the source file name and line number (if -known). The program counter is is omitted if is the beginning of the code for -the source line. This is the same as the first of the two lines printed -when you select a frame. - -@node Selection, Frame Info, Backtrace, Stack -@section Selecting a Frame - -Most commands for examining the stack and other data in the program work on -whichever stack frame is selected at the moment. Here are the commands for -selecting a stack frame; all of them finish by printing a brief description -of the stack frame just selected. - -@table @code -@item frame @var{n} -@kindex frame -Select frame number @var{n}. Recall that frame zero is the innermost -(currently executing) frame, frame one is the frame that called the -innermost one, and so on. The highest-numbered frame is @code{main}'s -frame. - -@item frame @var{addr} -Select the frame at address @var{addr}. This is useful mainly if the -chaining of stack frames has been damaged by a bug, making it -impossible for GDB+ to assign numbers properly to all frames. In -addition, this can be useful when the program has multiple stacks and -options between them. - -@item up @var{n} -@kindex up -Select the frame @var{n} frames up from the frame previously selected. -For positive numbers @var{n}, this advances toward the outermost -frame, to higher frame numbers, to frames that have existed longer. -@var{n} defaults to one. - -@item down @var{n} -@kindex down -Select the frame @var{n} frames down from the frame previously -selected. For positive numbers @var{n}, this advances toward the -innermost frame, to lower frame numbers, to frames that were created -more recently. @var{n} defaults to one. -@end table - -All of these commands end by printing some information on the frame that -has been selected: the frame number, the function name, the arguments, the -source file and line number of execution in that frame, and the text of -that source line. For example: - -@example -#3 main (argc=3, argv=??, env=??) at main.c, line 67 -67 read_input_file (argv[i]); -@end example - -After such a printout, the @samp{list} command with no arguments will print -ten lines centered on the point of execution in the frame. @xref{List}. - -@node Frame Info,, Selection, Stack -@section Information on a Frame - -There are several other commands to print information about the selected -stack frame. - -@table @code -@item frame -This command prints a brief description of the selected stack frame. -It can be abbreviated @samp{f}. With an argument, this command is -used to select a stack frame; with no argument, it does not change -which frame is selected, but still prints the same information. - -@item info frame -@kindex info frame -This command prints a verbose description of the selected stack frame, -including the address of the frame, the addresses of the next frame in -(called by this frame) and the next frame out (caller of this frame), -the address of the frame's arguments, the program counter saved in it -(the address of execution in the caller frame), and which registers -were saved in the frame. The verbose description is useful when -something has gone wrong that has made the stack format fail to fit -the usual conventions. - -@item info frame @var{addr} -Print a verbose description of the frame at address @var{addr}, -without selecting that frame. The selected frame remains unchanged by -this command. - -@item info args -@kindex info args -Print the arguments of the selected frame, each on a separate line. - -@item info locals -@kindex info locals -Print the local variables of the selected frame, each on a separate -line. These are all variables declared static or automatic within all -program blocks that execution in this frame is currently inside of. -@end table - -@node Source, Data, Stack, Top -@chapter Examining Source Files - -GDB+ knows which source files your program was compiled from, and -can print parts of their text. When your program stops, GDB+ -spontaneously prints the line it stopped in. Likewise, when you -select a stack frame (@pxref{Selection}), GDB+ prints the line -which execution in that frame has stopped in. You can also -print parts of source files by explicit command. - -@menu -* List:: Using the @samp{list} command to print source files. -* Search:: Commands for searching source files. -* Source Path:: Specifying the directories to search for source files. -@end menu - -@node List, Search, Source, Source -@section Printing Source Lines - -@kindex list -To print lines from a source file, use the @samp{list} command -(abbreviated @samp{l}). There are several ways to specify what part -of the file you want to print. - -Here are the forms of @samp{list} command most commonly used: - -@table @code -@item list @var{linenum} -Print ten lines centered around line number @var{linenum} in the -current source file. - -@item list @var{function} -Print ten lines centered around the beginning of function -@var{function}. - -@item list -Print ten more lines. If the last lines printed were printed with a -@samp{list} command, this prints ten lines following the last lines -printed; however, if the last line printed was a solitary line printed -as part of displaying a stack frame (@pxref{Stack}), this prints ten -lines centered around that line. - -@item list @minus{} -Print ten lines just before the lines last printed. -@end table - -Repeating a @samp{list} command with @key{RET} discards the argument, -so it is equivalent to typing just @samp{list}. This is more useful -than listing the same lines again. An exception is made for an -argument of @samp{-}; that argument is preserved in repetition so that -each repetition moves up in the file. - -In general, the @samp{list} command expects you to supply zero, one or two -@dfn{linespecs}. Linespecs specify source lines; there are several ways -of writing them but the effect is always to specify some source line. -Here is a complete description of the possible arguments for @samp{list}: - -@table @code -@item list @var{linespec} -Print ten lines centered around the line specified by @var{linespec}. - -@item list @var{first},@var{last} -Print lines from @var{first} to @var{last}. Both arguments are -linespecs. - -@item list ,@var{last} -Print ten lines ending with @var{last}. - -@item list @var{first}, -Print ten lines starting with @var{first}. - -@item list + -Print ten lines just after the lines last printed. - -@item list @minus{} -Print ten lines just before the lines last printed. - -@item list -As described in the preceding table. -@end table - -Here are the ways of specifying a single source line---all the -kinds of linespec. - -@table @asis -@item @var{linenum} -Specifies line @var{linenum} of the current source file. -When a @samp{list} command has two linespecs, this refers to -the same source file as the first linespec. - -@item +@var{offset} -Specifies the line @var{offset} lines after the last line printed. -When used as the second linespec in a @samp{list} command that has -two, this specifies the line @var{offset} lines down from the -first linespec. - -@item @minus{}@var{offset} -Specifies the line @var{offset} lines before the last line printed. - -@item @var{filename}:@var{linenum} -Specifies line @var{linenum} in the source file @var{filename}. - -@item @var{function} -Specifies the line of the open-brace that begins the body of the -function @var{function}. - -@item @var{filename}:@var{function} -Specifies the line of the open-brace that begins the body of the -function @var{function} in the file @var{filename}. The file name is -needed with a function name only for disambiguation of identically -named functions in different source files. - -@item *@var{address} -Specifies the line containing the program address @var{address}. -@var{address} may be any expression. -@end table - -One other command is used to map source lines to program addresses. - -@table @code -@item info line @var{linenum} -@kindex info line -Print the starting and ending addresses of the compiled code for -source line @var{linenum}. - -@kindex $_ -The default examine address for the @samp{x} command is changed to the -starting address of the line, so that @samp{x/i} is sufficient to -begin examining the machine code (@pxref{Memory}). Also, this address -is saved as the value of the convenience variable @samp{$_} -(@pxref{Convenience Vars}). -@end table - -@node Search, Source Path, List, Source -@section Searching Source Files -@cindex searching -@kindex forward-search -@kindex reverse-search - -There are two commands for searching through the current source file for a -regular expression. - -The command @samp{forward-search @var{regexp}} checks each line, starting -with the one following the last line listed, for a match for @var{regexp}. -It lists the line that is found. You can abbreviate the command name -as @samp{fo}. - -The command @samp{reverse-search @var{regexp}} checks each line, starting -with the one before the last line listed and going backward, for a match -for @var{regexp}. It lists the line that is found. You can abbreviate -this command with as little as @samp{rev}. - -@node Source Path,, Search, Source -@section Specifying Source Directories - -@cindex source path -@cindex directories for source files -Executable programs do not record the directories of the source files they -were compiled from, just the names. GDB+ remembers a list of directories to -search for source files; this is called the @dfn{source path}. Each time -GDB+ wants a source file, it tries all the directories in the list, in the -order they are present in the list, until it finds a file with the desired -name. - -@kindex directory -When you start GDB+, its source path contains just the current working -directory. To add other directories, use the @samp{directory} command. -@b{Note that the search path for executable files and the working directory -are @i{not} used for finding source files.} - -@table @code -@item directory @var{dirname} -Add directory @var{dirname} to the end of the source path. - -@item directory -Reset the source path to just the current working directory of GDB+. -This requires confirmation. - -@samp{directory} with no argument can cause source files previously -found by GDB+ to be found in a different directory. To make this work -correctly, this command also clears out the tables GDB+ maintains -about the source files it has already found. - -@item info directories -@kindex info directories -Print the source path: show which directories it contains. -@end table - -Because the @samp{directory} command adds to the end of the source path, -it does not affect any file that GDB+ has already found. If the source -path contains directories that you do not want, and these directories -contain misleading files with names matching your source files, the -way to correct the situation is as follows: - -@enumerate -@item -Choose the directory you want at the beginning of the source path. -Use the @samp{cd} command to make that the current working directory. - -@item -Use @samp{directory} with no argument to reset the source path to just -that directory. - -@item -Use @samp{directory} with suitable arguments to add any other -directories you want in the source path. -@end enumerate - -@node Data, Symbols, Source, Top -@chapter Examining Data - -@cindex printing data -@cindex examining data -@kindex print -The usual way of examining data in your program is with the @samp{print} -command (abbreviated @samp{p}). It evaluates and prints the value of any -valid expression of the language the program is written in (for now, C). -You type - -@example -print @var{exp} -@end example - -@noindent -where @var{exp} is any valid expression, and the value of @var{exp} -is printed in a format appropriate to its data type. - -A more low-level way of examining data is with the @samp{x} command. -It examines data in memory at a specified address and prints it in a -specified format. - -@menu -* Expressions:: Expressions that can be computed and printed. -* Variables:: Using your program's variables in expressions. -* Assignment:: Setting your program's variables. -* Arrays:: Examining part of memory as an array. -* Formats:: Specifying formats for printing values. -* Memory:: Examining memory explicitly. -* Auto Display:: Printing certain expressions whenever program stops. -* Value History:: Referring to values previously printed. -* Convenience Vars:: Giving names to values for future reference. -* Registers:: Referring to and storing in machine registers. -@end menu - -@node Expressions, Variables, Data, Data -@section Expressions - -@cindex expressions -Many different GDB+ commands accept an expression and compute its value. -Any kind of constant, variable or operator defined by the programming -language you are using is legal in an expression in GDB+. This includes -conditional expressions, function calls, casts and string constants. - -In addition to supporting operators normally found in the C programming -language, GDB+ also supports some C++ constructs. For example, one can -call member functions (GDB+ automatically uses @code{this} when necessary), -and examine and manipulate pointers to members, pointers to member -functions (virtual or otherwise). - -Casts are supported in all languages, not just in C, because it is so -useful to cast a number into a pointer so as to examine a structure -at that address in memory. GDB+ allows pointers to members and pointer to -member functions to be cast to any type and vice-versa. - -GDB+ supports three kinds of operator in addition to those of programming -languages: - -@table @code -@item @@ -@samp{@@} is a binary operator for treating parts of memory as arrays. -@xref{Arrays}, for more information. - -@item :: -@samp{::} allows you to specify a variable in terms of the file or -function it is defined in. @xref{Variables}. It also supports the C++ -convention of qualifying a variable reference according to a type name (or -the global scope). This makes it easy to examing static class variables, -for example. - -@item @{@var{type}@} @var{addr} -Refers to an object of type @var{type} stored at address @var{addr} in -memory. @var{addr} may be any expression whose value is an integer or -pointer (but parentheses are required around nonunary operators, just as in -a cast). This construct is allowed regardless of what kind of data is -officially supposed to reside at @var{addr}.@refill -@end table - -@node Variables, Arrays, Expressions, Data -@section Program Variables - -The most common kind of expression to use is the name of a variable -in your program. - -Variables in expressions are understood in the selected stack frame -(@pxref{Selection}); they must either be global (or static) or be visible -according to the scope rules of the programming language from the point of -execution in that frame. This means that in the function - -@example -foo (a) - int a; -@{ - bar (a); - @{ - int b = test (); - bar (b); - @} -@} -@end example - -@noindent -the variable @code{a} is usable whenever the program is executing -within the function @code{foo}, but the variable @code{b} is visible -only while the program is executing inside the block in which @code{b} -is declared. - -@node Arrays, Formats, Variables, Data -@section Artificial Arrays - -@cindex artificial array -It is often useful to print out several successive objects of the -same type in memory; a section of an array, or an array of -dynamically determined size for which only a pointer exists in the -program. - -This can be done by constructing an @dfn{artificial array} with the -binary operator @samp{@@}. The left operand of @samp{@@} should be -the first element of the desired array, as an individual object. -The right operand should be the length of the array. The result is -an array value whose elements are all of the type of the left argument. -The first element is actually the left argument; the second element -comes from bytes of memory immediately following those that hold the -first element, and so on. Here is an example. If a program says - -@example -int *array = (int *) malloc (len * sizeof (int)); -@end example - -@noindent -you can print the contents of @code{array} with - -@example -p *array@@len -@end example - -The left operand of @samp{@@} must reside in memory. Array values made -with @samp{@@} in this way behave just like other arrays in terms of -subscripting, and are coerced to pointers when used in expressions. -(It would probably appear in an expression via the value history, -after you had printed it out.) - -@node Formats, Memory, Arrays, Data -@section Formats - -@cindex formatted output -@cindex output formats -GDB+ normally prints all values according to their data types. Sometimes -this is not what you want. For example, you might want to print a number -in hex, or a pointer in decimal. Or you might want to view data in memory -at a certain address as a character string or an instruction. These things -can be done with @dfn{output formats}. - -The simplest use of output formats is to say how to print a value -already computed. This is done by starting the arguments of the -@samp{print} command with a slash and a format letter. The format -letters supported are: - -@table @samp -@item x -Regard the bits of the value as an integer, and print the integer in -hexadecimal. - -@item d -Print as integer in signed decimal. - -@item u -Print as integer in unsigned decimal. - -@item o -Print as integer in octal. - -@item a -Print as an address, both absolute in hex and then relative -to a symbol defined as an address below it. - -@item c -Regard as an integer and print it as a character constant. - -@item f -Regard the bits of the value as a floating point number and print -using typical floating point syntax. -@end table - -For example, to print the program counter in hex (@pxref{Registers}), type - -@example -p/x $pc -@end example - -@noindent -Note that no space is required before the slash; this is because command -names in GDB+ cannot contain a slash. - -To reprint the last value in the value history with a different format, -you can use the @samp{print} command with just a format and no -expression. For example, @samp{p/x} reprints the last value in hex. - -@node Memory, Auto Display, Formats, Data -@subsection Examining Memory - -@cindex examining memory -@kindex x -The command @samp{x} (for `examine') can be used to examine memory under -explicit control of formats, without reference to the program's data types. - -@samp{x} is followed by a slash and an output format specification, -followed by an expression for an address. The expression need not have -a pointer value (though it may); it is used as an integer, as the -address of a byte of memory. - -The output format in this case specifies both how big a unit of memory -to examine and how to print the contents of that unit. It is done -with one or two of the following letters: - -These letters specify just the size of unit to examine: - -@table @samp -@item b -Examine individual bytes. - -@item h -Examine halfwords (two bytes each). - -@item w -Examine words (four bytes each). - -@cindex word -Many assemblers and cpu designers still use `word' for a 16-bit quantity, -as a holdover from specific predecessor machines of the 1970's that really -did use two-byte words. But more generally the term `word' has always -referred to the size of quantity that a machine normally operates on and -stores in its registers. This is 32 bits for all the machines that GNU -runs on. - -@item g -Examine giant words (8 bytes). -@end table - -These letters specify just the way to print the contents: - -@table @samp -@item x -Print as integers in unsigned hexadecimal. - -@item d -Print as integers in signed decimal. - -@item u -Print as integers in unsigned decimal. - -@item o -Print as integers in unsigned octal. - -@item a -Print as an address, both absolute in hex and then relative -to a symbol defined as an address below it. - -@item c -Print as character constants. - -@item f -Print as floating point. This works only with sizes @samp{w} and -@samp{g}. - -@item s -Print a null-terminated string of characters. The specified unit size -is ignored; instead, the unit is however many bytes it takes to reach -a null character (including the null character). - -@item i -Print a machine instruction in assembler syntax (or nearly). The -specified unit size is ignored; the number of bytes in an instruction -varies depending on the type of machine, the opcode and the addressing -modes used. -@end table - -If either the manner of printing or the size of unit fails to be specified, -the default is to use the same one that was used last. If you don't want -to use any letters after the slash, you can omit the slash as well. - -You can also omit the address to examine. Then the address used is -just after the last unit examined. This is why string and instruction -formats actually compute a unit-size based on the data: so that the -next string or instruction examined will start in the right place. -The @samp{print} command sometimes sets the default address for -the @samp{x} command; when the value printed resides in memory, the -default is set to examine the same location. @samp{info line} also -sets the default for @samp{x}, to the address of the start of the -machine code for the specified line and @samp{info breakpoints} sets -it to the address of the last breakpoint listed. - -When you use @key{RET} to repeat an @samp{x} command, it does not repeat -exactly the same: the address specified previously (if any) is ignored, so -that the repeated command examines the successive locations in memory -rather than the same ones. - -You can examine several consecutive units of memory with one command by -writing a repeat-count after the slash (before the format letters, if any). -The repeat count must be a decimal integer. It has the same effect as -repeating the @samp{x} command that many times except that the output may -be more compact with several units per line. - -@example -x/10i $pc -@end example - -@noindent -Prints ten instructions starting with the one to be executed next in the -selected frame. After doing this, you could print another ten following -instructions with - -@example -x/10 -@end example - -@noindent -in which the format and address are allowed to default. - -@kindex $_ -@kindex $__ -The addresses and contents printed by the @samp{x} command are not put in -the value history because there is often too much of them and they would -get in the way. Instead, GDB+ makes these values available for subsequent -use in expressions as values of the convenience variables @samp{$_} and -@samp{$__}. - -After an @samp{x} command, the last address examined is available for use -in expressions in the convenience variable @samp{$_}. The contents of that -address, as examined, are available in the convenience variable @samp{$__}. - -If the @samp{x} command has a repeat count, the address and contents saved -are from the last memory unit printed; this is not the same as the last -address printed if several units were printed on the last line of output. - -@node Auto Display, Value History, Memory, Data -@section Automatic Display - -If you find that you want to print the value of an expression frequently -(to see how it changes), you might want to add it to the @dfn{automatic -display list} so that GDB+ will print its value each time the program stops. -Each expression added to the list is given a number to identify it; -to remove an expression from the list, you specify that number. -The automatic display looks like this: - -@example -2: foo = 38 -3: bar[5] = (struct hack *) 0x3804 -@end example - -@noindent -showing item numbers, expressions and their current values. - -@table @code -@item display @var{exp} -@kindex display -Add the expression @var{exp} to the list of expressions to display -each time the program stops. - -@item display/@var{fmt} @var{exp} -For @var{fmt} specifying only a display format and not a size or -count, add the expression @var{exp} to the auto-display list but -arranges to display it each time in the specified format @var{fmt}. - -@item display/@var{fmt} @var{addr} -For @var{fmt} @samp{i} or @samp{s}, or including a unit-size or a -number of units, add the expression @var{addr} as a memory address to -be examined each time the program stops. Examining means in effect -doing @samp{x/@var{fmt} @var{addr}}. @xref{Memory}. - -@item undisplay @var{n} -@kindex undisplay -Remove item number @var{n} from the list of expressions to display. - -@item display -Display the current values of the expressions on the list, just as is -done when the program stops. - -@item info display -@kindex info display -Print the list of expressions to display automatically, each one -with its item number, but without showing the values. -@end table - -@node Value History, Convenience Vars, Auto Display, Data -@section Value History - -@cindex value history -Every value printed by the @samp{print} command is saved for the entire -session in GDB+'s @dfn{value history} so that you can refer to it in -other expressions. - -@cindex $ -@cindex $$ -The values printed are given @dfn{history numbers} for you to refer to them -by. These are successive integers starting with 1. @samp{print} shows you -the history number assigned to a value by printing @samp{$@var{n} = } -before the value; here @var{n} is the history number. - -To refer to any previous value, use @samp{$} followed by the value's -history number. The output printed by @samp{print} is designed to remind -you of this. Just @samp{$} refers to the most recent value in the history, -and @samp{$$} refers to the value before that. - -For example, suppose you have just printed a pointer to a structure and -want to see the contents of the structure. It suffices to type - -@example -p *$ -@end example - -If you have a chain of structures where the component @samp{next} points -to the next one, you can print the contents of the next one with - -@example -p *$.next -@end example - -It might be useful to repeat this command many times by typing @key{RET}. - -Note that the history records values, not expressions. If the value of -@code{x} is 4 and you type - -@example -print x -set x=5 -@end example - -@noindent -then the value recorded in the value history by the @samp{print} command -remains 4 even though @code{x}'s value has changed. - -@table @code -@item info history -@kindex info history -Print the last ten values in the value history, with their item -numbers. This is like @samp{p $$9} repeated ten times, except that -@samp{info history} does not change the history. - -@item info history @var{n} -Print ten history values centered on history item number @var{n}. -@end table - -@node Convenience Vars, Registers, Value History, Data -@section Convenience Variables - -@cindex convenience variables -GDB+ provides @dfn{convenience variables} that you can use within GDB+ to -hold on to a value and refer to it later. These variables exist entirely -within GDB+; they are not part of your program, and setting a convenience -variable has no effect on further execution of your program. That's why -you can use them freely. - -Convenience variables have names starting with @samp{$}. Any name starting -with @samp{$} can be used for a convenience variable, unless it is one of -the predefined set of register names (@pxref{Registers}). - -You can save a value in a convenience variable with an assignment -expression, just as you would set a variable in your program. Example: - -@example -set $foo = *object_ptr -@end example - -@noindent -would save in @samp{$foo} the value contained in the object pointed to by -@code{object_ptr}. - -Using a convenience variable for the first time creates it; but its value -is @code{void} until you assign a new value. You can alter the value with -another assignment at any time. - -Convenience variables have no fixed types. You can assign a convenience -variable any type of value, even if it already has a value of a different -type. The convenience variable as an expression has whatever type its -current value has. - -@table @code -@item info convenience -@kindex info convenience -Print a list of convenience variables used so far, and their values. -Abbreviated @samp{i con}. -@end table - -One of the ways to use a convenience variable is as a counter to be -incremented or a pointer to be advanced. For example: - -@example -set $i = 0 -print bar[$i++]->contents -@i{@dots{}repeat that command by typing @key{RET}.} -@end example - -Some convenience variables are created automatically by GDB+ and given -values likely to be useful. - -@table @samp -@item $_ -The variable @samp{$_} is automatically set by the @samp{x} command to -the last address examined (@pxref{Memory}). Other commands which -provide a default address for @samp{x} to examine also set @samp{$_} -to that address; these commands include @samp{info line} and @samp{info -breakpoint}. - -@item $__ -The variable @samp{$__} is automatically set by the @samp{x} command -to the value found in the last address examined. -@end table - -@node Registers,, Convenience Vars, Data -@section Registers - -@cindex registers -Machine register contents can be referred to in expressions as variables -with names starting with @samp{$}. The names of registers are different -for each machine; use @samp{info registers} to see the names used on your -machine. The names @samp{$pc} and @samp{$sp} are used on all machines for -the program counter register and the stack pointer. Often @samp{$fp} is -used for a register that contains a pointer to the current stack frame. - -GDB+ always considers the contents of an ordinary register as an integer -when the register is examined in this way. Programs can store floating -point values in registers also, but there is currently no GDB+ command -to examine a specified register in floating point. (However, if the -variable in your program which is stored in the register is a floating -point variable, you can see the floating point value by examining -the variable.) - -Some machines have special floating point registers. GDB+ considers these -registers' values as floating point when you examine them explicitly. - -Some registers have distinct ``raw'' and ``virtual'' data formats. This -means that the data format in which the register contents are saved by the -operating system is not the same one that your program normally sees. For -example, the registers of the 68881 floating point coprocessor are always -saved in ``extended'' format, but all C programs expect to work with -``double'' format. In such cases, GDB+ normally works with the virtual -format only (the format that makes sense for your program), but the -@samp{info registers} command prints the data in both formats. - -Register values are relative to the selected stack frame -(@pxref{Selection}). This means that you get the value that the register -would contain if all stack frames farther in were exited and their saved -registers restored. In order to see the real contents of all registers, -you must select the innermost frame (with @samp{frame 0}). - -Some registers are never saved (typically those numbered zero or one) -because they are used for returning function values; for these registers, -relativization makes no difference. - -@table @code -@item info registers -@kindex info registers -Print the names and relativized values of all registers. - -@item info registers @var{regname} -Print the relativized value of register @var{regname}. @var{regname} -may be any register name valid on the machine you are using, with -or without the initial @samp{$}. -@end table - -@subsection Examples - -You could print the program counter in hex with - -@example -p/x $pc -@end example - -@noindent -or print the instruction to be executed next with - -@example -x/i $pc -@end example - -@noindent -or add four to the stack pointer with - -@example -set $sp += 4 -@end example - -@noindent -The last is a way of removing one word from the stack, on machines where -stacks grow downward in memory (most machines, nowadays). This assumes -that the innermost stack frame is selected. Setting @samp{$sp} is -not allowed when other stack frames are selected. - -@node Symbols, Altering, Data, Top -@chapter Examining the Symbol Table - -The commands described in this section allow you to make inquiries for -information about the symbols (names of variables, functions and types) -defined in your program. This information is found by GDB+ in the symbol -table loaded by the @samp{symbol-file} command; it is inherent in the text -of your program and does not change as the program executes. - -@table @code -@item whatis @var{exp} -@kindex whatis -Print the data type of expression @var{exp}. @var{exp} is not -actually evaluated, and any side-effecting operations (such as -assignments or function calls) inside it do not take place. - -@item whatis -Print the data type of @samp{$}, the last value in the value history. - -@item info address @var{symbol} -@kindex info address -Describe where the data for @var{symbol} is stored. For register -variables, this says which register. For other automatic variables, -this prints the stack-frame offset at which the variable is always -stored. Note the contrast with @samp{print &@var{symbol}}, which does -not work at all for register variables and for automatic variables -prints the exact address of the current instantiation of the variable. - -@item ptype @var{typename} -@kindex ptype -Print a description of data type @var{typename}. @var{typename} may be -the name of a type, or for C code it may have the form -@samp{struct @var{struct-tag}}, @samp{union @var{union-tag}} or -@samp{enum @var{enum-tag}}.@refill - -@item info sources -@kindex info sources -Print the names of all source files in the program for which there -is debugging information. - -@item info functions -@kindex info functions -Print the names and data types of all defined functions. - -@item info functions @var{regexp} -Print the names and data types of all defined functions -whose names contain a match for regular expression @var{regexp}. -Thus, @samp{info fun step} finds all functions whose names -include @samp{step}; @samp{info fun ^step} finds those whose names -start with @samp{step}. - -@item info variables -@kindex info variables -Print the names and data types of all variables that are declared -outside of functions. - -@item info variables @var{regexp} -Print the names and data types of all variables, declared outside of -functions, whose names contain a match for regular expression -@var{regexp}. - -@item info types -@kindex info types -Print all data types that are defined in the program. - -@item info types @var{regexp} -Print all data types that are defined in the program whose names -contain a match for regular expression @var{regexp}. - -@item printsyms @var{filename} -@kindex printsyms -Write a complete dump of the debugger's symbol data into the -file @var{filename}. -@end table - -@node Altering, Sequences, Symbols, Top -@chapter Altering Execution - -There are several ways to alter the execution of your program with GDB+ -commands. - -@menu -* Assignment:: Altering variable values or memory contents. -* Jumping:: Altering control flow. -* Signaling:: Making signals happen in the program. -* Returning:: Making a function return prematurely. -@end menu - -@node Assignment, Jumping, Altering, Altering -@section Assignment to Variables - -@cindex assignment -@cindex setting variables -To alter the value of a variable, evaluate an assignment expression. -For example, - -@example -print x=4 -@end example - -@noindent -would store the value 4 into the variable @code{x}, and then print -the value of the assignment expression (which is 4). - -@kindex set -If you are not interested in seeing the value of the assignment, use the -@samp{set} command instead of the @samp{print} command. @samp{set} is -really the same as @samp{print} except that the expression's value is not -printed and is not put in the value history (@pxref{Value History}). The -expression is evaluated only for side effects. - -GDB+ allows more implicit conversions in assignments than C does; you can -freely store an integer value into a pointer variable or vice versa, and -any structure can be converted to any other structure that is the same -length or shorter. - -In C, all the other assignment operators such as @samp{+=} and @samp{++} -are supported as well. - -To store into arbitrary places in memory, use the @samp{@{@dots{}@}} -construct to generate a value of specified type at a specified address -(@pxref{Expressions}). For example, - -@example -set @{int@}0x83040 = 4 -@end example - -@node Jumping, Signaling, Assignment, Altering -@section Continuing at a Different Address - -@table @code -@item jump @var{linenum} -@kindex jump -Resume execution at line number @var{linenum}. Execution may stop -immediately if there is a breakpoint there. - -The @samp{jump} command does not change the current stack frame, or -the stack pointer, or the contents of any memory location or any -register other than the program counter. If line @var{linenum} is in -a different function from the one currently executing, the results may -be wild if the two functions expect different patterns of arguments or -of local variables. For his reason, the @samp{jump} command requests -confirmation if the specified line is not in the function currently -executing. However, even wild results are predictable based on -changing the program counter. - -@item jump *@var{address} -Resume execution at the instruction at address @var{address}. -@end table - -A similar effect can be obtained by storing a new value into the register -@samp{$pc}, but not exactly the same. - -@example -set $pc = 0x485 -@end example - -@noindent -specifies the address at which execution will resume, but does not resume -execution. That does not happen until you use the @samp{cont} command or a -stepping command (@pxref{Stepping}). - -@node Signaling, Returning, Jumping, Altering -@section Giving the Program a Signal - -@table @code -@item signal @var{signalnum} -@kindex signal -Resume execution where the program stopped, but give it immediately -the signal number @var{signalnum}. - -Alternatively, if @var{signalnum} is zero, continue execution and give -no signal. This may be useful when the program has received a signal -and the @samp{cont} command would allow the program to see that -signal. -@end table - -@node Returning,, Signaling, Altering -@section Returning from a Function - -@cindex returning from a function -@kindex return -You can make any function call return immediately, using the @samp{return} -command. - -First select the stack frame that you wish to return from -(@pxref{Selection}). Then type the @samp{return} command. If you wish to -specify the value to be returned, give that as an argument. - -This pops the selected stack frame (and any other frames inside of it), -leaving its caller as the innermost remaining frame. That frame becomes -selected. The specified value is stored in the registers used for -returning values of functions. - -The @samp{return} command does not resume execution; it leaves the program -stopped in the state that would exist if the function had just returned. -Contrast this with the @samp{finish} command (@pxref{Stepping}), which -resumes execution @i{until} the selected stack frame returns naturally. - -@node Sequences, Emacs, Altering, Top -@chapter Canned Sequences of Commands - -GDB+ provides two ways to store sequences of commands for execution as a -unit: user-defined commands and command files. - -@menu -* Define:: User-defined commands. -* Command Files:: Command files. -* Output:: Controlled output commands useful in - user-defined commands and command files. -@end menu - -@node Define, Command Files, Sequences, Sequences -@section User-Defined Commands - -@cindex user-defined commands -A @dfn{user-defined command} is a sequence of GDB+ commands to which you -assign a new name as a command. This is done with the @samp{define} -command. - -@table @code -@item define @var{commandname} -@kindex define -Define a command named @var{commandname}. If there is already a command -by that name, you are asked to confirm that you want to redefine it. - -The definition of the command is made up of other GDB+ command lines, -which are given following the @samp{define} command. The end of these -commands is marked by a line containing @samp{end}. - -@item document @var{commandname} -@kindex document -Give documentation to the user-defined command @var{commandname}. The -command @var{commandname} must already be defined. This command reads -lines of documentation just as @samp{define} reads the lines of the -command definition. After the @samp{document} command is finished, -@samp{help} on command @var{commandname} will print the documentation -you have specified. - -You may use the @samp{document} command again to change the -documentation of a command. Redefining the command with @samp{define} -does not change the documentation. -@end table - -User-defined commands do not take arguments. When they are executed, the -commands of the definition are not printed. An error in any command -stops execution of the user-defined command. - -Commands that would ask for confirmation if used interactively proceed -without asking when used inside a user-defined command. Many GDB+ commands -that normally print messages to say what they are doing omit the messages -when used in user-defined command. - -@node Command Files, Output, Define, Sequences -@section Command Files - -@cindex command files -A command file for GDB+ is a file of lines that are GDB+ commands. Comments -(lines starting with @samp{#}) may also be included. An empty line in a -command file does nothing; it does not mean to repeat the last command, as -it would from the terminal. - -@cindex init file -@cindex .gdbinit -When GDB+ starts, it automatically executes its @dfn{init files}, command -files named @file{.gdbinit}. GDB+ reads the init file (if any) in your home -directory and then the init file (if any) in the current working -directory. (The init files are not executed if the @samp{-nx} option -is given.) You can also request the execution of a command file with the -@samp{source} command: - -@table @code -@item source @var{filename} -@kindex source -Execute the command file @var{filename}. -@end table - -The lines in a command file are executed sequentially. They are not -printed as they are executed. An error in any command terminates execution -of the command file. - -Commands that would ask for confirmation if used interactively proceed -without asking when used in a command file. Many GDB+ commands that -normally print messages to say what they are doing omit the messages -when used in a command file. - -@node Output,, Command Files, Sequences -@section Commands for Controlled Output - -During the execution of a command file or a user-defined command, the only -output that appears is what is explicitly printed by the commands of the -definition. This section describes three commands useful for generating -exactly the output you want. - -@table @code -@item echo @var{text} -@kindex echo -Print @var{text}. Nonprinting characters can be included in -@var{text} using C escape sequences, such as @samp{\n} to print a -newline. @b{No newline will be printed unless you specify one.} - -A backslash at the end of @var{text} is ignored. It is useful for -outputting a string ending in spaces, since trailing spaces are -trimmed from all arguments. A backslash at the beginning preserves -leading spaces in the same way, because @samp{\ } as an escape -sequence stands for a space. Thus, to print @samp{ and foo = }, do - -@example -echo \ and foo = \ -@end example - -@item output @var{expression} -@kindex output -Print the value of @var{expression} and nothing but that value: no -newlines, no @samp{$@var{nn} = }. The value is not entered in the -value history either. - -@item output/@var{fmt} @var{expression} -Print the value of @var{expression} in format @var{fmt}. -@xref{Formats}, for more information. - -@item printf @var{string}, @var{expressions}@dots{} -@kindex printf -Print the values of the @var{expressions} under the control of -@var{string}. The @var{expressions} are separated by commas and may -be either numbers or pointers. Their values are printed as specified -by @var{string}, exactly as if the program were to execute - -@example -printf (@var{string}, @var{expressions}@dots{}); -@end example - -For example, you can print two values in hex like this: - -@example -printf "foo, bar-foo = 0x%x, 0x%x\n", foo, bar-foo -@end example - -The only backslash-escape sequences that you can use in the string are -the simple ones that consist of backslash followed by a letter. -@end table - -@node Emacs, Remote, Sequences, Top -@chapter Using GDB under GNU Emacs - -A special interface allows you to use GNU Emacs to view (and -edit) the source files for the program you are debugging with -GDB. - -To use this interface, use the command @kbd{M-x gdb} in Emacs. -Give the executable file you want to debug as an argument. This -command starts a GDB process as a subprocess of Emacs, with input -and output through a newly created Emacs buffer. - -Using this GDB process is just like using GDB normally except for two things: - -@itemize @bullet -@item -All ``terminal'' input and output goes through the Emacs buffer. This -applies both to GDB commands and their output, and to the input and -output done by the program you are debugging. - -This is useful because it means that you can copy the text of previous -commands and input them again; you can even use parts of the output -in this way. - -All the facilities of Emacs's Shell mode are available for this purpose. - -@item -GDB displays source code through Emacs. Each time GDB displays a -stack frame, Emacs automatically finds the source file for that frame -and puts an arrow (@samp{=>}) at the left margin of the current line. - -Explicit GDB @samp{list} or search commands still produce output as -usual, but you probably will have no reason to use them. -@end itemize - -In the GDB I/O buffer, you can use these special Emacs commands: - -@table @kbd -@item M-s -Execute to another source line, like the GDB @samp{step} command. - -@item M-n -Execute to next source line in this function, skipping all function -calls, like the GDB @samp{next} command. - -@item M-i -Execute one instruction, like the GDB @samp{stepi} command. - -@item M-u -Move up one stack frame (and display that frame's source file in -Emacs), like the GDB @samp{up} command. - -@item M-d -Move down one stack frame (and display that frame's source file in -Emacs), like the GDB @samp{down} command. (This means that you cannot -delete words in the usual fashion in the GDB buffer; I am guessing you -won't often want to do that.) - -@item C-c C-f -Execute until exit from the selected stack frame, like the GDB -@samp{finish} command. -@end table - -In any source file, the Emacs command @kbd{C-x SPC} (@code{gdb-break}) -tells GDB to set a breakpoint on the source line point is on. - -The source files displayed in Emacs are in ordinary Emacs buffers -which are visiting the source files in the usual way. You can edit -the files with these buffers if you wish; but keep in mind that GDB -communicates with Emacs in terms of line numbers. If you add or -delete lines from the text, the line numbers that GDB knows will cease -to correspond properly to the code. - -@node Remote, Commands, Emacs, Top -@chapter Remote Kernel Debugging - -GDB has a special facility for debugging a remote machine via a serial -connection. This can be used for kernel debugging. - -The program to be debugged on the remote machine needs to contain a -debugging device driver which talks to GDB over the serial line using the -protocol described below. The same version of GDB that is used ordinarily -can be used for this. - -@menu -* Remote Commands:: Commands used to start and finish remote debugging. -@end menu - -For details of the communication protocol, see the comments in the GDB -source file @file{remote.c}. - -@node Remote Commands,, Remote, Remote -@section Commands for Remote Debugging - -To start remote debugging, first run GDB and specify as an executable file -the program that is running in the remote machine. This tells GDB how -to find the program's symbols and the contents of its pure text. Then -establish communication using the @samp{attach} command with a device -name rather than a pid as an argument. For example: - -@example -attach /dev/ttyd -@end example - -@noindent -if the serial line is connected to the device named @file{/dev/ttyd}. This -will stop the remote machine if it is not already stopped. - -Now you can use all the usual commands to examine and change data and to -step and continue the remote program. - -To resume the remote program and stop debugging it, use the @samp{detach} -command. - -@node Commands, Concepts, Remote, Top -@unnumbered Command Index - -@printindex ky - -@node Concepts,, Commands, Top -@unnumbered Concept Index - -@printindex cp - -@contents -@bye diff --git a/gdb/gdb.1 b/gdb/gdb.1 new file mode 100644 index 0000000..11a42a6 --- /dev/null +++ b/gdb/gdb.1 @@ -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. + diff --git a/gdb/gdb.ideas b/gdb/gdb.ideas new file mode 100644 index 0000000..96ba662 --- /dev/null +++ b/gdb/gdb.ideas @@ -0,0 +1,1277 @@ +BABYL OPTIONS: +Version: 5 +Labels: +Note: This is the header of an rmail file. +Note: If you are seeing it in rmail, +Note: it means the file has no messages in it. + +From: mly@MICHAEL.AI.MIT.EDU (Richard Mlynarik) +To: rms@prep.ai.mit.edu +Subject: gdb suggestions (from hpux cdb) +Reply-To: mly-prep@prep.ai.mit.edu + +"find-bug" command says "I can see the problem, but it will do you +good to find it yourself" + +The gdb manual should explicitly state that gdb has no control over +forked (or execed or whatever) subprocesses. + +I'd still like it if "delete" said what it had done. + + +Date: Tuesday, 13 May 1986, 00:40-EDT +From: <rms@LMI-ANGEL> +Sender: JC@LMI-ANGEL +Subject: interesting sdb features +To: rms@angel + +output format p = pointer to procedure. + +foo/x or foo/4x uses size of foo as size to print. + +foo[1;4] to get elements 1 thru 4. + +Continue to specified line number. + +Interactively delete all breakpoints (asking about each one). + + + +Command to write backtrace into a file, or even better to duplicate all +output to a file. This could work by playing with descriptor 1, +making it a pipe to `tee'. The original descriptor 1 is saved and +this mode can be turned off by putting it back. + Date: Wed, 18 Feb 87 15:37:14 EST + From: rms (Richard M. Stallman) + Message-Id: <8702182037.AA16492@prep.ai.mit.edu> + To: mly-prep@prep.ai.mit.edu + In-Reply-To: <8702181913.AA16118@prep.ai.mit.edu> + Subject: gdb "photo" command + + I don't think all this is worth the trouble to do now, + because the right way to do it on TRIX is totally different + and much easier. + + +Commands to enable and disable the autodisplays. Associate +autodisplays with breakpoints perhaps, so they only display +at those breakpoints; this is easier than using breakpoint commands. + +Remember how each breakpoint's position was specified. +Have command to reread symbol table and respecify each +breakpoint using same args (line number or function name) as before. + +Have way to proceed process in background so that can then suspend +gdb but have subprocess continue + + +Date: Fri, 24 Jul 87 21:30:25 EDT +From: phr@PREP.AI.MIT.EDU (Paul Rubin) +To: bug-gdb@PREP.AI.MIT.EDU + +After rereading the symbol table when user runs the "symbol-file" +command, when GDB notices that some of the source files are newer +it should reload them rather than just printing a message saying +they are newer. + + + +Message-Id: <8704171941.AA05045@orville.arpa> +To: mly@prep.ai.mit.edu +Cc: raible@orville.arpa, fouts@orville.arpa, creon@orville.arpa +Subject: gdb hack/questions, etc +Date: 17 Apr 87 11:41:42 PST (Fri) +From: raible@orville.arpa + + +A couple of things: + +1) Will gdb ever get dbx-sytly tracing? Wouldn't it be fairly easy to add? + +2) How about an xemacs gdb mode which has various windows, perhaps using + terminal.el for generality? + +3) Any word about that stupid IRIS SIGIOT problem? Do you know of anyone + else who has gotten IRIS subprocesses to work more reliably? + +4) Below is a hack adapted from ramsdell@linus.uucp which can be pretty + useful in gdb. Instead of using gdb to patch extensive changes to a + particular function, you can do the following (assuming the 50 lines + of code below is part of your executable): + 1) create a new file (foo.c) containing the new function + 2) run cc -c foo.c + 3) in gdb, and patch in the new function as follows: + +(gdb) info breakpoints +/* Load in the new object code... */ +#1 y 0x00000125 in main (dyn.c line 46) + break only if $function = funload ("foo"), 1 + silent + echo new code for func ($function) initialized\n + cont + +/* ...and use it instead of the old code. */ +#2 y 0x000001c2 in func (dyn.c line 59) + break only if $ret = $function (a), 1 + silent + set a = $ret + j 60 /* func has a return on line 60 */ + + This is more complicated than it has to be because of 2 bugs in v2.1: + 1) function calls in a breakpoint command list seem to abort + the execution of the rest of the command list. This is + why all function calls are in the conditional part. + (gdb reference manual section 5.5). + + 2) A 'return' in a command list also aborts the execution, and + in addition, prompts you for a y/n. + (gdb reference manual section 11.1). + + On the other hand, after doing 'cc -c foo.c' (which is pretty fast), + you can simply rerun your program to check out the changes. + This can be a big win! + +The code for this is included below (compile with cc -g): +======================================================== + +#include <stdio.h> +#include <a.out.h> + +typedef int (*intfun)(); +char *myname; + +intfun funload (filename) /* Dynamically load 1st function from a .o */ + char *filename; +{ + int fd, size; + struct exec hdr; + char buf[100]; + intfun fun; + + /* -A => incremental loading - use dyn as the base symbol table + -T => set the text segment origin to the following hex address + -N => magic number 407 (text not read-only) + */ + sprintf (buf, "ld -A %s -T %x -N %s.o -o %s -lc", + myname, sbrk (0), filename, filename); + + /* NOTE: if anything mallocs space between here and below, this will fail */ + system (buf); + + fd = open (filename, 0); + read (fd, &hdr, sizeof(hdr)); + size = hdr.a_text + hdr.a_data + hdr.a_bss; + + if ((fun = (intfun) sbrk (size)) < 0) + printf ("Couldn't find the space"), exit(); + + read (fd, fun, size); /* Load code. */ + /* NOTE: if anything mallocs space between here and above, this will fail */ + + close (fd); + return ((intfun) fun); +} + +main (argc, argv) + char **argv; +{ + intfun fun1, fun2; + + myname = *argv; + + fun1 = funload("fun1"); + printf ("The answer is %d.\n", (*fun1)(11) ); + + fun2 = funload("fun2"); + printf ("The answer is %d.\n", (*fun2)() ); +} +1,edited,, +Received: by PREP.AI.MIT.EDU; Tue, 16 Jun 87 03:12:54 EDT +Date: Tue, 16 Jun 87 03:12:54 EDT +From: rms (Richard M. Stallman) +Message-Id: <8706160712.AA07910@prep.ai.mit.edu> +To: rms +Subject: GDB ideas + +*** EOOH *** +Date: Tue, 16 Jun 87 03:12:54 EDT +From: rms (Richard M. Stallman) +To: rms +Subject: GDB ideas + +* Within a user-defined command, have local convenience variables, +local functions, local defined commands. + +** Optionally echo commands within a user-defined command. + +** Optionally record all user-typed commands in a log file. +Optionally record GDB output there too, marked as output so it +will not be executed if replayed. + +* Execution commands + +** Step until next branch, or next call. +(finish is step until next return). + +step branch +or should it be +continue branch + +** Stop on any branch, call or return +affecting ordinary step and continue commands. + +stop branch + +** Trace all branches, calls, returns. +This could be done by stopping on those events +and having a continue command to be executed after. + +stop branch +commands branch +continue +end + +** Commands to continue or step without any display after stop. +These may be useful in user-defined commands. + +Have one prefix command that does this, modifying whatever other +command you might use. For example, + +silent step 5 +silent cont + +** Clear all breakpoint ignore-counts when inferior exits or is killed. + +** Trace changes to a location (watchpoint). +Enable and disable them. + +** Info command to show command-line for running the program. + +* Auto-display + +** Enable and disable display expressions. +Allow syntax 1d, 2d, etc. in enable, disable and delete commands. +Then there is no more need for an undisplay command. + +** Displaying an auto variable should not do it in the wrong stack frame. +Either it should search for the proper stack frame to apply to +or it should deactivate itself when in the wrong frame. + +* Printing + +** Print an address as <file:line>+offset. + +** Abbreviate initial whitespace modulo 16. + +** p/x of an array should print each element with /x. + +** Change the stack scan so that it has a more general idea +of what info is needed to describe a frame fully. + +* Expressions + +** Array slices. Can replace @. + +** %name for use of symbol names containing funny characters. + +** User-defined convenience functions that can appear in expressions. + +** Expression syntax to convert line number to address. + +** Expression syntax to specify a name scope with an address, line number +or frame number. + +Use the line number by itself, or an address with *, just as in b or l cmd: +38:foo or *0x40a:foo. No good; the latter would be parsed as +*(0x40a:foo). + +** Expression syntax to convert a frame number to its pc. +Perhaps unary %. + +* Possible bugs + +** Does set $pc= cause the current scope to be recalculated? +It should. + +1,, +Received: by PREP.AI.MIT.EDU; Wed, 17 Jun 87 09:59:37 EDT +From: phr@ATHENA.MIT.EDU +Received: by ATHENA (5.45/4.7) + id AA09084; Wed, 17 Jun 87 08:54:36 EDT +Received: by ORPHEUS.MIT.EDU (5.45/4.7) id AA02565; Wed, 17 Jun 87 08:54:29 EDT +Date: Wed, 17 Jun 87 08:54:29 EDT +Message-Id: <8706171254.AA02565@ORPHEUS.MIT.EDU> +To: rms@prep.ai.mit.edu +Subject: gdb suggestion +Status: RO + +*** EOOH *** +From: phr@ATHENA.MIT.EDU +Date: Wed, 17 Jun 87 08:54:29 EDT +To: rms@prep.ai.mit.edu +Subject: gdb suggestion + +Completion of file and function names; e.g. typing + break XWriteBi +prints + No such symbol: XWriteBi. + Setting default command to "break XWriteBitmapFile" +so you can set a break at XWriteBitmapFile by hitting return a second +time. Other interfaces ("complete to XWriteBitmapFile? (y/n)") +are also possible. + + +1,edited,, +Received: by PREP.AI.MIT.EDU; Wed, 24 Sep 86 16:33:11 EDT +Date: Wed, 24 Sep 86 16:33:11 EDT +From: mly (Richard Mlynarik) +Message-Id: <8609242033.AA11520@prep.ai.mit.edu> +To: rms +Cc: mly-prep +Subject: gdb gripes/suggestions/requests + +*** EOOH *** +Date: Wed, 24 Sep 86 16:33:11 EDT +From: mly (Richard Mlynarik) +To: rms +Cc: mly-prep +Subject: gdb gripes/suggestions/requests + +If would be really nice to have some way to do conditionals in user + commands -- though this is really stretching the functionality of + gdb a little too much, perhaps. (see ~mly/e/.gdbint for some of + the contortions I go through with || to get conditional + evaluation...) + +A -real- win wuold be some way to execute until he next function-call + (like c-d in the cadr debugger) This would even be useful if it + were rather slow -- it would probably be faster than setting + temporary breakpoints in all the functions which might be called, + and would certainly be faster than "step"ping one's way until a + funcall happened. + +"info source" should mention what the directory search-path is (ie + what "info dir" says) and in which directory it found each of the + source files (and which source files it cannot locate in the + search-path) + + +1,, +Received: by xcssun.Berkeley.EDU (5.57/1.25) + id AA22869; Thu, 22 Oct 87 09:50:30 PDT +Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Thu, 22 Oct 87 12:17:59 EDT +Received: by PREP.AI.MIT.EDU; Thu, 22 Oct 87 12:21:00 EDT +Received: from pp.mcc.com by MCC.COM with TCP; Thu 22 Oct 87 10:54:41-CDT +Posted-Date: Thu, 22 Oct 87 10:55:13 CDT +Received: from big-d.aca.mcc.com by pp.mcc.com (4.12/KA70822) + id AA16571; Thu, 22 Oct 87 10:55:19 cdt +Return-Path: <tiemann@big-d.aca.mcc.com> +Received: by big-d.aca.mcc.com (3.2/KA70106) + id AA04247; Thu, 22 Oct 87 10:55:13 CDT +Date: Thu, 22 Oct 87 10:55:13 CDT +From: tiemann%pp.mcc.com@mcc.com (Michael Tiemann) +Message-Id: <8710221555.AA04247@big-d.aca.mcc.com> +To: bug-gdb@prep.ai.mit.edu +Subject: expanding file names + +*** EOOH *** +Posted-Date: Thu, 22 Oct 87 10:55:13 CDT +Return-Path: <tiemann@big-d.aca.mcc.com> +Date: Thu, 22 Oct 87 10:55:13 CDT +From: tiemann%pp.mcc.com@mcc.com (Michael Tiemann) +To: bug-gdb@prep.ai.mit.edu +Subject: expanding file names + +When running a program, gdb thoughtfully passes the argument list +through the shell, expanding files and environment variables as +needed. It would be nice if the same facility were added to the +command which adds directories to search paths. For example, it would +be nice to say "dir ~/foo" . + +Michael + + +1,, +Received: by xcssun.Berkeley.EDU (5.57/1.25) + id AA25075; Fri, 23 Oct 87 10:42:52 PDT +Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Fri, 23 Oct 87 13:39:37 EDT +Received: by PREP.AI.MIT.EDU; Fri, 23 Oct 87 13:42:53 EDT +Received: from relay2.cs.net by RELAY.CS.NET id ac11193; 23 Oct 87 13:03 EDT +Received: from umb.edu by RELAY.CS.NET id ac05949; 23 Oct 87 13:01 EDT +Received: by umb.umb.edu; Fri, 23 Oct 87 10:18:40 EDT +Received: by ileaf.uucp (1.1/SMI-3.0DEV3) + id AA00599; Wed, 21 Oct 87 10:56:52 EDT +Received: from marvin.io.uucp by io.uucp (1.1/SMI-3.0DEV3) + id AA01359; Wed, 21 Oct 87 10:58:45 EDT +Received: by marvin.io.uucp (3.2/SMI-3.2) + id AA00334; Wed, 21 Oct 87 11:02:20 EDT +Date: Wed, 21 Oct 87 11:02:20 EDT +From: Mark Dionne <io!marvin!md%ileaf.uucp%umb.umb.edu@relay.cs.net> +Message-Id: <8710211502.AA00334@marvin.io.uucp> +To: ileaf!umb!bug-gdb@prep.ai.mit.edu +Subject: gdb bug + +*** EOOH *** +Date: Wed, 21 Oct 87 11:02:20 EDT +From: Mark Dionne <io!marvin!md%ileaf.uucp%umb.umb.edu@relay.cs.net> +To: ileaf!umb!bug-gdb@prep.ai.mit.edu +Subject: gdb bug + +The /FMT and @ options of the "print" command seem to interact +in GDB 2.1. For example: + +(gdb) p ($cmpn.buf[-1])@($cmpn.gapb - $cmpn.buf + 1) +$17 = {-16383, -24285, 55, 27944, -24285, -24285, 55, 28010, -24285, +-24285, 55, 28076, -24285, -24285, 55, 28142, -24285} +(gdb) p/x ($cmpn.buf[-1])@($cmpn.gapb - $cmpn.buf + 1) +$18 = 0xc001 + +I guess I see what's happening: the /x is applying to the whole +array rather than to the individual elements. Feature or bug? + + ...!harvard!umb!ileaf!md Mark Dionne, Interleaf + ...!sun!sunne!ileaf!md Ten Canal Park, Cambridge, MA 02141 + (617) 577-9813 x5551 + + + +1,, +Received: by PREP.AI.MIT.EDU; Sun, 6 Sep 87 14:27:19 EDT +Message-Id: <8709061827.AA18170@prep.ai.mit.edu> +Received: from relay2.cs.net by RELAY.CS.NET id af03990; 6 Sep 87 14:22 EDT +Received: from umb.edu by RELAY.CS.NET id ab03029; 6 Sep 87 14:16 EDT +Received: by umb.umb.edu; Sun, 6 Sep 87 12:10:34 EDT +Date: Sun, 6 Sep 87 12:10:34 EDT +Received: by typo.umb.edu; Sun, 6 Sep 87 12:04:21 EDT +From: Robert Morris <ram%typo.umb.edu@RELAY.CS.NET> +To: bug-gdb@PREP.AI.MIT.EDU +Subject: convenient script + +*** EOOH *** +Date: Sun, 6 Sep 87 12:10:34 EDT +From: Robert Morris <ram%typo.umb.edu@RELAY.CS.NET> +To: bug-gdb@PREP.AI.MIT.EDU +Subject: convenient script + +I find it easier to maintain binaries on our heterogenous +network if I keep this trivial script in gdb source directory. Use it +if you want. + + +------------ + +#! /bin/csh -f +# SETUP +# setup gdb files for presently known machines +# ram@umb.edu +# (ram%umb.edu@relay.cs.net if you have an incomplete mailer) +# or ...!harvard!umb!ram +# +# e.g. SETUP sun3 +# note that sunX means major release X of sun software, generally +# sun3 at this writing (gnu 18.41) +# +# note GDB with gnuemacs 18.41 is already configured for vaxen + +# Bob Morris, UMASS-Boston 9/6/87 +switch ($1) + case "sun2": + ; + case "sun3" : + set cputype="m68k"; + set inittype="suninit"; + breaksw; + default : + set cputype=$1; + set inittype=$1init; + breaksw; +endsw +echo \#include \"m-$1.h\" > param.h +echo \#include \"$cputype-pinsn.c\" > pinsn.c +ed initialize.h <<! >& /dev/null +/init.h/ +c +#include "m-$inittype.h" +. +w +q +! + + + + +1,answered,, +Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Sat, 19 Dec 87 18:18:50 EST +Received: by PREP.AI.MIT.EDU; Sat, 19 Dec 87 18:24:38 EST +Received: from big-d.aca.mcc.com by MCC.COM with TCP; Sat 19 Dec 87 17:19:48-CST +Date: Sat, 19 Dec 87 17:19:41 CST +From: tiemann@mcc.com (Michael Tiemann) +Posted-Date: Sat, 19 Dec 87 17:19:41 CST +Message-Id: <8712192319.AA26775@big-d.aca.mcc.com> +Received: by big-d.aca.mcc.com (3.2/ACA-V2.1) + id AA26775; Sat, 19 Dec 87 17:19:41 CST +To: rms@prep.ai.mit.edu +Subject: gdb + +*** EOOH *** +Date: Sat, 19 Dec 87 17:19:41 CST +From: tiemann@mcc.com (Michael Tiemann) +Posted-Date: Sat, 19 Dec 87 17:19:41 CST +To: rms@prep.ai.mit.edu +Subject: gdb + +file values.c, function unpack_field_as_long: + + val &= (1 << bitsize) - 1; + +This is not as machine independent as it could be. If you feel like +fixing this potential problem, there are many other instances to worry +about. + +Michael + + +1,, +Received: by xcssun.Berkeley.EDU (5.57/1.25) + id AA04771; Thu, 20 Aug 87 22:33:25 PDT +Received: from [128.52.22.14] by ucbvax.Berkeley.EDU (5.58/1.27) + id AA07119; Thu, 20 Aug 87 00:37:04 PDT +Received: by PREP.AI.MIT.EDU; Thu, 20 Aug 87 03:37:35 EDT +Date: Thu, 20 Aug 87 03:37:35 EDT +From: rms@prep.ai.mit.edu (Richard M. Stallman) +Message-Id: <8708200737.AA15589@prep.ai.mit.edu> +To: rms@prep.ai.mit.edu +Subject: GDB changes for next version + +*** EOOH *** +Date: Thu, 20 Aug 87 03:37:35 EDT +From: rms@prep.ai.mit.edu (Richard M. Stallman) +To: rms@prep.ai.mit.edu +Subject: GDB changes for next version + +1. Use links, rather than editing some files, to configure it. + +2. Can misc functions eval as their addresses rather than as + a char in that address? Is this reasonable in all cases + given that non-functions cannot be distinguished + and that you might use the result in various ways (arithmetic, etc.). + + +1,, +Received: by xcssun.Berkeley.EDU (5.57/1.25) + id AA09136; Sat, 29 Aug 87 02:20:15 PDT +Received: from PREP.AI.MIT.EDU by ucbvax.Berkeley.EDU (5.58/1.27) + id AA26072; Sat, 29 Aug 87 02:21:51 PDT +Received: by PREP.AI.MIT.EDU; Sat, 29 Aug 87 05:22:30 EDT +Received: by RUTGERS.EDU (5.54/1.14) with UUCP + id AA22247; Sat, 29 Aug 87 05:21:13 EDT +Received: from sequent.UUCP by spool.wisc.edu; Sat, 29 Aug 87 04:18:41 CDT +Received: from reed.UUCP by ogcvax.OGC.EDU (5.51/OGC_4.8) + id AA08044; Fri, 28 Aug 87 20:06:41 PDT +Received: by reed.UUCP (5.51/5.17) + id AA05059; Fri, 28 Aug 87 19:19:15 PDT +From: uwvax!sequent!ogcvax!reed!keith@rutgers.edu (Keith Packard) +Message-Id: <8708290219.AA05059@reed.UUCP> +To: rms@prep.ai.mit.edu +Subject: Re: GDB +In-Reply-To: Your message of Thu, 20 Aug 87 03:39:37 EDT. + <8708200735.AA26546@EDDIE.MIT.EDU> +Date: Fri, 28 Aug 87 19:19:13 PDT + +*** EOOH *** +From: uwvax!sequent!ogcvax!reed!keith@rutgers.edu (Keith Packard) +To: rms@prep.ai.mit.edu +Subject: Re: GDB +In-Reply-To: Your message of Thu, 20 Aug 87 03:39:37 EDT. + <8708200735.AA26546@EDDIE.MIT.EDU> +Date: Fri, 28 Aug 87 19:19:13 PDT + + +Here is a simple test program for exibiting the trouble with signals: + +----- +# include <signal.h> + +main () +{ + int handle (); + int i; + signal (SIGALRM, handle); + alarm (5); + for (i = 0; i < 100000; i++) + printf ("%d\n", i); +} + +handle () +{ + printf ("signal!\n"); + alarm (5); +} +----- + +To demonstrate the problem, simply place a breakpoint before the call to +alarm and then start stepping through the program: + +(gdb) break 7 +(gdb) step +... +... + +Eventually, the alarm call occurs and the program ends up in some +signal handling code -- unfortuantely a machine dependent location. At this +point, because the fp has moved out of the current function (in fact on +many machines the frame is not in a consistent state at this point) gdb +assumes that a new function has started and suspends execution with another +prompt. + +A reasonable solution would be to have gdb insert a breakpoint at the +expected signal return address and continue to that breakpoint -- I've +implemented this and found that it works. There is, however, one nasty +problem -- longjmp around the suspended frame and the breakpoint is not hit +at the expected time. + +Have fun... + +keith packard + +tektronix!reed!keith + + +1,, +Received: by xcssun.Berkeley.EDU (5.57/1.25) + id AA09143; Sat, 29 Aug 87 02:24:58 PDT +Received: by neptune.Berkeley.EDU (5.57/1.25) + id AA03738; Sat, 29 Aug 87 02:24:50 PDT +Date: Sat, 29 Aug 87 02:24:50 PDT +From: rms@neptune.berkeley.edu (Richard Stallman) +Message-Id: <8708290924.AA03738@neptune.Berkeley.EDU> +To: rms@neptune.Berkeley.EDU +Subject: GDB bug +Reply-To: rms@prep.ai.mit.edu + +*** EOOH *** +Date: Sat, 29 Aug 87 02:24:50 PDT +From: rms@neptune.berkeley.edu (Richard Stallman) +To: rms@neptune.Berkeley.EDU +Subject: GDB bug +Reply-To: rms@prep.ai.mit.edu + +Is there any way to make GDB, when stepping across a function call, +notice any attempt to longjump out of that call? +Perhaps an implicit breakpoint at longjump. +If longjump is called, find the pc in the jmp_buf and put +a self-deleting breakpoint there. + + +1,, +Received: by xcssun.Berkeley.EDU (5.57/1.25) + id AA07976; Fri, 28 Aug 87 09:26:12 PDT +Received: from PREP.AI.MIT.EDU by ucbvax.Berkeley.EDU (5.58/1.27) + id AA03230; Fri, 28 Aug 87 09:28:04 PDT +Received: by PREP.AI.MIT.EDU; Fri, 28 Aug 87 12:28:43 EDT +Date: Fri, 28 Aug 87 12:28:43 EDT +From: phr@prep.ai.mit.edu (Paul Rubin) +Message-Id: <8708281628.AA09926@prep.ai.mit.edu> +To: rms@prep.ai.mit.edu +Subject: gdb suggestions + +*** EOOH *** +Date: Fri, 28 Aug 87 12:28:43 EDT +From: phr@prep.ai.mit.edu (Paul Rubin) +To: rms@prep.ai.mit.edu +Subject: gdb suggestions + +1. I wish gdb had a command to re-read the sources so that I can edit +the program and recompile it without having to kill and restart gdb. + +2. Would be nice if gdb could somehow connect the subprocess's tty channels +to a pty, so I can run gdb in an X window and the subprocess in a different +(xterm) window. + +This might need hair to detect if the subprocess is running when you try +to examine variables, etc. and stop the subproc or report an error if it is. + + +1,, +Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Mon, 4 Apr 88 12:43:31 EDT +Received: from CCA.CCA.COM by prep.ai.mit.edu; Mon, 4 Apr 88 11:30:55 EST +Received: by CCA.CCA.COM; Mon, 4 Apr 88 12:42:16 EDT +Date: Mon, 4 Apr 88 12:42:16 EDT +From: alex@cca.cca.com (Alexis Layton) +Message-Id: <8804041642.AA28917@CCA.CCA.COM> +To: rms@prep.ai.mit.edu +Subject: Wish List for GDB +Cc: tiemann@mcc.com + +*** EOOH *** +Date: Mon, 4 Apr 88 12:42:16 EDT +From: alex@cca.cca.com (Alexis Layton) +To: rms@prep.ai.mit.edu +Subject: Wish List for GDB +Cc: tiemann@mcc.com + +GDB is a good debugger. I like it. I think it is lacking in functionality +in the following areas: + +1. "Finish this loop" capability. If I am stepping through code and +encounter a for-, do-, or while-loop, after a few iterations I generally +get bored. I want to be able to say "finish this loop"; i.e. continue +until the next statement after the loop is executed. Note this is +complicated by gotos and nested loops. + +2. GDB only prints the last line of a multi-line statement which has been +continued. Since this is often of the form + + foobar)); + +it is not very convenient. When stepping through a file using next (or step), +ALL non-blank text lines (excepting perhaps close-braces?) between the last +displayed line and the current one should be displayed. + +3. If there is a way to call a function interactively, I couldn't find it +in the on-line help. (Having neither GNU Emacs or TeX, reading the .texinfo +files is a bit tedious.) + +4. On occasion, when debugging a function with deeply nested code in a loop, +I want to have "hierarchical" breakpoints -- that is, I want certain +breakpoints automatically enabled if a certain breakpoint is triggered, +but not if it hasn't. I haven't thought of a good design for this yet. + +5. tbreak is not temporary enough; It should delete the breakpoint, not +disable it. + +6. what about "next to linenumber", or "continue to linenumber" -- the +only difference being next single-steps and continue sets an ephemeral +breakpoint and then deletes it. This would also make debugging large +functions easier. + +7. variable access breakpoints (break when variable changes value) + +8. should be able to use "set" to change initialization values before +"run" is issued. Makes setting of static debugging control variables +easier. Right now I have to break main all the time. + +9. GDB seems to be slow in reading/processing the symbol table -- can +this be improved? + +10. Preprocessor support. Is there any way to run the command input through +the preprocessor or otherwise get a handle on defines? Particlarly in +debugging things like ncurses, which use umpteen defines. + +(E.g., "delete_line" is defined as SP->_StrCaps[28] or some such nonsense.) + +Perhaps you could spawn off a CPP and then pipe the command input to it, +appropriately down-loading the included files and whatever # text was in +the C file being debugged.... + +Most of these comments of course apply to GDB+ as well. + +Well, that's just a few of my thoughts. Hope they give you some ideas. + + Alexis Layton + alex@CCA.CCA.COM + + +1,, +Summary-line: 27-Nov steve%next.com@relay.cs.n #gdb +Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Wed, 2 Dec 87 16:58:16 EST +Received: by PREP.AI.MIT.EDU; Wed, 2 Dec 87 17:00:22 EST +Message-Id: <8712022200.AA09856@prep.ai.mit.edu> +Received: from relay2.cs.net by RELAY.CS.NET id ag03066; 2 Dec 87 16:06 EST +Received: from next.com by RELAY.CS.NET id ae26721; 2 Dec 87 16:00 EST +Received: from indiana.next.com by next.next.com (3.2/SMI-3.0DEV3) + id AA08711; Fri, 27 Nov 87 10:47:36 PST +Date: Fri, 27 Nov 87 10:41:41 PST +From: steve%next.com@relay.cs.net +To: rms@prep.ai.mit.edu +Subject: gdb + +*** EOOH *** +Date: Fri, 27 Nov 87 10:41:41 PST +From: steve%next.com@relay.cs.net +To: rms@prep.ai.mit.edu +Subject: gdb + + I copied it into wheaties:gdb.tar.next.Z. The following is our "TODO" list. +An asterisk notes an entry is completed. + +- objc features: + * printing objects: + - printing indexed instance variables. + * implement object-print command which lists + class, methods, source file, etc. + * info objects command which lists all objects. + + * message expression evaluation: + * Use symbolic method name/object name. + - Add varargs support. + - printing instance variables: + - When all else fails, attempt to lookup an unknown + local as an instance variable (if currently in a + method handler/.m file). + * breakpoints: + - set breakpoints in object/method handler. + * stepping: + - stepm command that steps over _msg call into the + message handler when source is available. + * printing methods: + * info method that lists objects that implement a given + method. + * list command: + - modifiy it so that you can list the source for a given + object/method pair. + - backtrace: + - fix braindamaged backtrace (_msg doesn't maintain a6 linkage). + - poseAs: + - Reinitialize Obj-C-Data when poseAs is used. +- tenex: + * Finish incremental history searches. + * Add history search/reverse search. + * Add \e< and \e> + - Save macros on exit. + - Add commands to reset/append/prepend macrofiles. + - Add ability to read macrofiles once in emacs mode. + - print bindings command. + - command completion: + - gdb commands? + - symbol table entries? +- symbol tables: + - Modify current .sym file information to be left in .o files and + relocated by the debugger at load time. + - Load .sym file info on demand. +- documentation: +- mach port: + - use shared memory. + - multiple threads. + - multiple tasks. + - /dev/proc???? + - debug an already running task. + - debug a program with minimal symbol information. + - debugger support for shared libraries. +- misc: + - watchpoints. + - add a way to set evaluation scope/context to a file. + - disassembly enhancement: + - support symbolic names for locals and registers and + args. + - macro args (for user commands). + - case insensitivity for searches (info command/list searches). + - by default, load symbol table with exec-file. + - clean up structure printing. + - assmebler source level debugging. + - CPP info in the debugger (be able to get to #defines). +- gdbtool: + Source windows: + menus: + - tag support (callee/caller ala dir). + - break on line. + - unbreak on line. + - set one shot breakpoint. + - continue until line (with/without enabling other breakpoints). + - search forward/reverse. + - yank text for command window. + attributes: + - dir-like interface where each stack frame has a window. + Windows can be closed and are re-created when that stack frame + is reached again. If windows are too slow, beat up Leo. + - source windows have line-numbers/breakpoint indicator/last + PC in that window/current PC. + - full dir-like tags support for bringing up new windows (not on + the execution stack). + - Allow editing of source in a window (gray-scale for new lines/ + deleted lines) so that current debugging session still works. ??? + - incremental compiles (dream on!). + Data display windows: + - auto display window. + - graphic structure display. + Stack display window: + - stack trace display. Menu buttons: + - up/down. + - continue until stack level. + Command window: + menu: + - evaluate selected expression. + attributes: +- Remote debugging: + - Add other protocols (ethernet?, shared memory). +- C Interpreter. + - Control flow. + - Interpret changed code. + - Add subroutines. + + + +1,, +Summary-line: 22-Oct tiemann%pp.mcc.com@mcc.co #expanding file names +Received: by xcssun.Berkeley.EDU (5.57/1.25) + id AA22869; Thu, 22 Oct 87 09:50:30 PDT +Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Thu, 22 Oct 87 12:17:59 EDT +Received: by PREP.AI.MIT.EDU; Thu, 22 Oct 87 12:21:00 EDT +Received: from pp.mcc.com by MCC.COM with TCP; Thu 22 Oct 87 10:54:41-CDT +Posted-Date: Thu, 22 Oct 87 10:55:13 CDT +Received: from big-d.aca.mcc.com by pp.mcc.com (4.12/KA70822) + id AA16571; Thu, 22 Oct 87 10:55:19 cdt +Return-Path: <tiemann@big-d.aca.mcc.com> +Received: by big-d.aca.mcc.com (3.2/KA70106) + id AA04247; Thu, 22 Oct 87 10:55:13 CDT +Date: Thu, 22 Oct 87 10:55:13 CDT +From: tiemann%pp.mcc.com@mcc.com (Michael Tiemann) +Message-Id: <8710221555.AA04247@big-d.aca.mcc.com> +To: bug-gdb@prep.ai.mit.edu +Subject: expanding file names + +*** EOOH *** +Posted-Date: Thu, 22 Oct 87 10:55:13 CDT +Return-Path: <tiemann@big-d.aca.mcc.com> +Date: Thu, 22 Oct 87 10:55:13 CDT +From: tiemann%pp.mcc.com@mcc.com (Michael Tiemann) +To: bug-gdb@prep.ai.mit.edu +Subject: expanding file names + +When running a program, gdb thoughtfully passes the argument list +through the shell, expanding files and environment variables as +needed. It would be nice if the same facility were added to the +command which adds directories to search paths. For example, it would +be nice to say "dir ~/foo" . + +Michael + + +1, edited, answered,, +Received: by xcssun.Berkeley.EDU (5.57/1.25) + id AA26610; Wed, 2 Mar 88 05:27:51 PST +Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Wed, 2 Mar 88 08:26:23 EST +Received: from cgl.ucsf.EDU by prep.ai.mit.edu; Wed, 2 Mar 88 08:25:58 EST +Received: by cgl.ucsf.edu (5.54/GSC4.5) + id AA27646; Wed, 2 Mar 88 05:23:57 PST +Received: by hop.toad.com id AA00787; Wed, 2 Mar 88 05:22:55 PST +Date: Wed, 2 Mar 88 05:22:55 PST +From: hoptoad.UUCP!gnu@cgl.ucsf.edu (John Gilmore) +Message-Id: <8803021322.AA00787@hop.toad.com> +To: rms@cgl.ucsf.edu +Subject: A few things Sun dbx does that gdb doesn't... + +*** EOOH *** +Date: Wed, 2 Mar 88 05:22:55 PST +From: hoptoad.UUCP!gnu@cgl.ucsf.edu (John Gilmore) +To: rms@cgl.ucsf.edu +Subject: A few things Sun dbx does that gdb doesn't... + + * gdb won't reread the executable's symbol table when its mod time +has changed. The user has to explicitly reread it after recompiling +the software and before typing "run". + + * gdb has no command to report the current argv for "run" commands. +"info program" or "info environment" should display this info. (dbx +doesn't do this either, but I noticed it at the same time.) + + +1, answered,, +Received: by xcssun.Berkeley.EDU (5.57/1.25) + id AA14587; Tue, 16 Feb 88 16:19:12 PST +Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Tue, 16 Feb 88 19:17:21 EST +Received: from UNIX.SRI.COM by prep.ai.mit.edu; Tue, 16 Feb 88 19:08:02 EST +Received: by sri-unix.ARPA (5.31/5.14) + id AA25586; Tue, 16 Feb 88 16:12:32 PST +From: ozona!chase@pisa.orc.olivetti.com +Received: from ozona.orc.olivetti.com by orc.uucp (3.2/SMI-3.2) + id AA01567; Tue, 16 Feb 88 16:01:02 PST +Received: from localhost by ozona.orc.olivetti.com (3.2/SMI-3.2) + id AA08259; Tue, 16 Feb 88 16:02:22 PST +Message-Id: <8802170002.AA08259@ozona.orc.olivetti.com> +To: rms@prep.ai.mit.edu +Subject: GDB suggestion +Reply-To: chase%orc.uucp@unix.sri.com +Date: Tue, 16 Feb 88 16:02:18 -0800 + +*** EOOH *** +From: ozona!chase@pisa.orc.olivetti.com +To: rms@prep.ai.mit.edu +Subject: GDB suggestion +Reply-To: chase%orc.uucp@unix.sri.com +Date: Tue, 16 Feb 88 16:02:18 -0800 + + +Today I found myself wanting a feature in a debugger that neither GDB +nor DBX supports. I checked the GDB documentation and could not find +it there. This may be too Unix-specific, so you may not want to add +it. It may also not be of general use. Nevertheless, I will suggest +it; it's certainly easy to ignore the suggestion. + +What I wanted to do was limit the datasize of a program that I was +debugging (I am debugging someone else's garbage collector, lucky +me) without also imposing that limit on the debugger. I didn't see +any mention of such a command in either debugger's documentation. + +In other news, the alleged (ansi) C and Modula library is beginning to +work. (The garbage collector is part of the Modula-2+ half.) + +David Chase +Olivetti Research Center, Menlo Park + + +1,, +Return-Path: <rms@wheaties.ai.mit.edu> +Received: by frosted-flakes.ai.mit.edu; Sat, 30 Apr 88 17:05:42 EDT +Date: Sat, 30 Apr 88 17:05:42 EDT +From: rms@wheaties.ai.mit.edu (Richard Stallman) +Message-Id: <8804302105.AA25303@frosted-flakes.ai.mit.edu> +To: rms +Subject: GDB idea + +*** EOOH *** +Return-Path: <rms@wheaties.ai.mit.edu> +Date: Sat, 30 Apr 88 17:05:42 EDT +From: rms@wheaties.ai.mit.edu (Richard Stallman) +To: rms +Subject: GDB idea + +Expressions should record the block that symbols were looked up in, +if the symbols proved not to be static, +and an auto-display should be disabled automatically when it is +not in the block where the results would be meaningful. + + +1,, +Received: from ai.ai.mit.edu by wheaties.ai.mit.edu; Sun, 8 May 88 12:52:31 EDT +Received: from prep.ai.mit.edu (TCP 20015020016) by AI.AI.MIT.EDU 8 May 88 05:38:21 EDT +Received: from lilac.Berkeley.EDU by prep.ai.mit.edu; Sun, 8 May 88 04:12:02 EST +Received: from web5h.berkeley.edu + by lilac.berkeley.edu (5.54 (CFC 4.22.3)/1.16.18) + id AA27424; Sun, 8 May 88 02:33:06 PDT +Received: by web5h.berkeley.edu (3.2/SMI-3.0DEV3.8MXl) + id AA05599; Sun, 8 May 88 02:33:41 PDT +Date: Sun, 8 May 88 02:33:41 PDT +From: phr%widow.Berkeley.EDU@lilac.berkeley.edu +Message-Id: <8805080933.AA05599@web5h.berkeley.edu> +To: bug-gdb@prep.ai.mit.edu +Subject: suggestion (gdb 2.4): print function names + +*** EOOH *** +Date: Sun, 8 May 88 02:33:41 PDT +From: phr%widow.Berkeley.EDU@lilac.berkeley.edu +To: bug-gdb@prep.ai.mit.edu +Subject: suggestion (gdb 2.4): print function names + +If p is a pointer to function, "print p" should print the name +of the function that p points to, as well as the numeric value. +Dbx does this. + + + +1,, +Received: from lilac.berkeley.edu by wheaties.ai.mit.edu; Wed, 11 May 88 23:14:39 EDT +Received: from web8e.berkeley.edu + by lilac.berkeley.edu (5.54 (CFC 4.22.3)/1.16.18) + id AA11864; Wed, 11 May 88 20:11:12 PDT +Received: by web8e.berkeley.edu (3.2/SMI-3.0DEV3.8MXl) + id AA06549; Wed, 11 May 88 20:11:44 PDT +Date: Wed, 11 May 88 20:11:44 PDT +From: phr%widow.Berkeley.EDU@lilac.berkeley.edu +Message-Id: <8805120311.AA06549@web8e.berkeley.edu> +To: rms@wheaties.ai.mit.edu +Subject: gdb suggestion + +*** EOOH *** +Date: Wed, 11 May 88 20:11:44 PDT +From: phr%widow.Berkeley.EDU@lilac.berkeley.edu +To: rms@wheaties.ai.mit.edu +Subject: gdb suggestion + +If the process signal mask of a program is saved in the core dump, +then gdb should have a way to read it. I have an xemacs that hangs +in a blocking read from XCreateWindow when I run it from the csh, +but works fine when run under gdb. (Does this mean a gdb bug?). + + +1, answered,, +Return-Path: <tmb@wheaties.ai.mit.edu> +Received: by sugar-smacks.ai.mit.edu; Tue, 24 May 88 00:34:01 EDT +Date: Tue, 24 May 88 00:34:01 EDT +From: tmb@wheaties.ai.mit.edu (Thomas M. Breuel) +Message-Id: <8805240434.AA02268@sugar-smacks.ai.mit.edu> +To: rms +Subject: problem with gdb... + +*** EOOH *** +Return-Path: <tmb@wheaties.ai.mit.edu> +Date: Tue, 24 May 88 00:34:01 EDT +From: tmb@wheaties.ai.mit.edu (Thomas M. Breuel) +To: rms +Subject: problem with gdb... + +When tracing a program that forks, the breakpoints aren't removed in the +child and it dies with a trace/bpt trap. Isn't there a more proper way to +handle this? + + Thomas. + + +1, forwarded, answered,, +Received: from ATHENA (ATHENA.MIT.EDU) by wheaties.ai.mit.edu; Sat, 25 Jun 88 04:02:57 EDT +From: jbs@athena.mit.edu +Received: by ATHENA.MIT.EDU (5.45/4.7) id AA21892; Sat, 25 Jun 88 04:00:11 EDT +Received: by BRIDGETOWN.MIT.EDU (5.45/4.7) id AA13640; Sat, 25 Jun 88 03:59:57 EDT +Date: Sat, 25 Jun 88 03:59:57 EDT +Message-Id: <8806250759.AA13640@BRIDGETOWN.MIT.EDU> +To: rms@wheaties.ai.mit.edu +Subject: gdb suggestion + +*** EOOH *** +From: jbs@athena.mit.edu +Date: Sat, 25 Jun 88 03:59:57 EDT +To: rms@wheaties.ai.mit.edu +Subject: gdb suggestion + +Debugging X toolkit stuff involves looking at structures that fill up +several screens. GDB would be a lot easier to use if it supported +some sort of pretty-printing of these structures. + +Jeff + + +1, forwarded,, +Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Thu, 23 Jun 88 04:32:12 EDT +Received: from ic.Berkeley.EDU by prep.ai.mit.edu; Thu, 23 Jun 88 03:19:27 EST +Received: by ic.berkeley.edu (5.57/1.28) + id AA02077; Thu, 23 Jun 88 01:28:08 PDT +Date: Thu, 23 Jun 88 01:28:08 PDT +From: faustus@ic.berkeley.edu (Wayne A. Christopher) +Message-Id: <8806230828.AA02077@ic.berkeley.edu> +To: rms@prep.ai.mit.edu +Subject: gdb request + +*** EOOH *** +Date: Thu, 23 Jun 88 01:28:08 PDT +From: faustus@ic.berkeley.edu (Wayne A. Christopher) +To: rms@prep.ai.mit.edu +Subject: gdb request + +One suggestion for future versions of gdb -- the trace command of dbx is very +useful, and a lot easier to use than the "commands" feature in gdb. Although +it's not necessary, it would be nice to have it. + + Wayne + + +1, forwarded,, +Return-Path: <faustus@scruff.berkeley.edu> +Received: from prep.ai.mit.edu by life.ai.mit.edu; Sun, 24 Jul 88 03:40:33 EDT +Received: from scruff.Berkeley.EDU by prep.ai.mit.edu; Sun, 24 Jul 88 02:17:27 EST +Received: by scruff.berkeley.edu (5.57/1.28) + id AA19389; Sun, 24 Jul 88 00:35:41 PDT +Date: Sun, 24 Jul 88 00:35:41 PDT +From: faustus@scruff.berkeley.edu (Wayne A. Christopher) +Message-Id: <8807240735.AA19389@scruff.berkeley.edu> +To: rms@prep.ai.mit.edu +Subject: gdb feature + +*** EOOH *** +Return-Path: <faustus@scruff.berkeley.edu> +Date: Sun, 24 Jul 88 00:35:41 PDT +From: faustus@scruff.berkeley.edu (Wayne A. Christopher) +To: rms@prep.ai.mit.edu +Subject: gdb feature + +It would be nice if I could stop and background a process running under +gdb. Now gdb lets the process get the ^Z and gives me a prompt, instead +of stopping also. + + Wayne + + +1,, +Return-Path: <wesommer@athena.mit.edu> +Received: from prep.ai.mit.edu by life.ai.mit.edu; Tue, 30 Aug 88 23:18:51 EDT +Received: from ATHENA.MIT.EDU by prep.ai.mit.edu; Tue, 30 Aug 88 21:44:58 EST +Received: by ATHENA.MIT.EDU (5.45/4.7) id AA29972; Tue, 30 Aug 88 23:16:03 EDT +Received: by E40-342A-3 (5.45/4.7) + id AA10004; Tue, 30 Aug 88 23:15:58 EDT +Date: Tue, 30 Aug 88 23:15:58 EDT +From: Bill Sommerfeld <wesommer@athena.mit.edu> +Message-Id: <8808310315.AA10004@E40-342A-3> +To: bug-gdb@prep.ai.mit.edu +Subject: SET_STACK_LIMIT_HUGE. + +*** EOOH *** +Return-Path: <wesommer@athena.mit.edu> +Date: Tue, 30 Aug 88 23:15:58 EDT +From: Bill Sommerfeld <wesommer@athena.mit.edu> +To: bug-gdb@prep.ai.mit.edu +Subject: SET_STACK_LIMIT_HUGE. + +I just had the pleasure of figuring out why a program which worked +under GDB failed (with a segv) when run under the shell. It turns out +that it was allocating too much space in the stack, and dying with a +segmentation violation when it overran the stack. + +I note that gdb/main.c unlimits the stack, presumably to allow gdb to +use alloca to its heart's content. This is well and good, but in the +interests of making the execution and debugging environments +functionally identical, could it at least set the limit back down to +what it used to be when it starts the child process? + + - Bill + + +1, answered,, +Return-Path: <randy@wheaties.ai.mit.edu> +Received: from hobbes.ai.mit.edu by wheaties.ai.mit.edu; Thu, 1 Sep 88 23:13:03 EDT +Received: from localhost.ARPA by hobbes.ai.mit.edu; Thu, 1 Sep 88 23:08:41 est +Message-Id: <8809020408.AA09913@hobbes.ai.mit.edu> +To: rms@wheaties.ai.mit.edu (Richard Stallman) +Cc: randy@wheaties.ai.mit.edu +Subject: Re: GDB work that needs to be done +In-Reply-To: Your message of Thu, 01 Sep 88 19:23:47 -0400. + <8809012323.AA01639@sugar-bombs.ai.mit.edu> +Date: Thu, 01 Sep 88 23:08:39 +0900 +From: randy@wheaties.ai.mit.edu + +*** EOOH *** +Return-Path: <randy@wheaties.ai.mit.edu> +To: rms@wheaties.ai.mit.edu (Richard Stallman) +Cc: randy@wheaties.ai.mit.edu +Subject: Re: GDB work that needs to be done +In-Reply-To: Your message of Thu, 01 Sep 88 19:23:47 -0400. + <8809012323.AA01639@sugar-bombs.ai.mit.edu> +Date: Thu, 01 Sep 88 23:08:39 +0900 +From: randy@wheaties.ai.mit.edu + + +Also: + +5. Step until past current line or out of stack frame. + + +1,, +Return-Path: <rms@wheaties.ai.mit.edu> +Received: by sugar-bombs.ai.mit.edu; Fri, 2 Sep 88 12:43:28 EDT +Date: Fri, 2 Sep 88 12:43:28 EDT +From: rms@wheaties.ai.mit.edu (Richard Stallman) +Message-Id: <8809021643.AA00263@sugar-bombs.ai.mit.edu> +To: randy@wheaties.ai.mit.edu +Cc: rms +In-Reply-To: randy@wheaties.ai.mit.edu's message of Thu, 01 Sep 88 23:08:39 +0900 <8809020408.AA09913@hobbes.ai.mit.edu> +Subject: GDB work that needs to be done + +*** EOOH *** +Return-Path: <rms@wheaties.ai.mit.edu> +Date: Fri, 2 Sep 88 12:43:28 EDT +From: rms@wheaties.ai.mit.edu (Richard Stallman) +To: randy@wheaties.ai.mit.edu +Cc: rms +In-Reply-To: randy@wheaties.ai.mit.edu's message of Thu, 01 Sep 88 23:08:39 +0900 <8809020408.AA09913@hobbes.ai.mit.edu> +Subject: GDB work that needs to be done + + Step until past current line or out of stack frame. + +I think this should be a command called `until': + + until LINE run until line LINE. + until run until reach the following line. + +It can work by setting a temporary (delete when hit) breakpoint +at the specified destination and then doing `finish'. + + +
\ No newline at end of file diff --git a/gdb/gld-pinsn.c b/gdb/gld-pinsn.c new file mode 100644 index 0000000..947c979 --- /dev/null +++ b/gdb/gld-pinsn.c @@ -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); +} diff --git a/gdb/infcmd.c b/gdb/infcmd.c index c66809d..d87afa4 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -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); diff --git a/gdb/inflow.c b/gdb/inflow.c index b88352c..386a2e1 100644 --- a/gdb/inflow.c +++ b/gdb/inflow.c @@ -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 int tflags_ours; -static struct sgttyb sg_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; -static int tflags_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, <c_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, <c_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, <c_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 *)<c_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, ®val); + } + 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 *) ®isters[(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 *) ®isters[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 *) ®isters[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, <c_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; } diff --git a/gdb/infrun.c b/gdb/infrun.c index 97966e4..596e17c 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -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; } diff --git a/gdb/initialize.h b/gdb/initialize.h index 05d570e..8037dd6 100644 --- a/gdb/initialize.h +++ b/gdb/initialize.h @@ -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 diff --git a/gdb/m-hp9k320.h b/gdb/m-hp9k320.h new file mode 100644 index 0000000..3b83833 --- /dev/null +++ b/gdb/m-hp9k320.h @@ -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 */ diff --git a/gdb/m-hp9k320bsd.h b/gdb/m-hp9k320bsd.h new file mode 100644 index 0000000..66c9b3b --- /dev/null +++ b/gdb/m-hp9k320bsd.h @@ -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"); } diff --git a/gdb/m-suninit.h b/gdb/m-init.h index 5f71ea1..5f71ea1 100644 --- a/gdb/m-suninit.h +++ b/gdb/m-init.h diff --git a/gdb/m-isi-ov.h b/gdb/m-isi.h index 46c1816..1e2bb84 100644 --- a/gdb/m-isi-ov.h +++ b/gdb/m-isi.h @@ -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. */ diff --git a/gdb/m-isiinit.h b/gdb/m-isiinit.h new file mode 100644 index 0000000..3b5532a --- /dev/null +++ b/gdb/m-isiinit.h @@ -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 diff --git a/gdb/m-merlin.h b/gdb/m-merlin.h new file mode 100644 index 0000000..3f30f50 --- /dev/null +++ b/gdb/m-merlin.h @@ -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 diff --git a/gdb/m-news.h b/gdb/m-news.h new file mode 100644 index 0000000..1ae6a17 --- /dev/null +++ b/gdb/m-news.h @@ -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 + diff --git a/gdb/m-newsinit.h b/gdb/m-newsinit.h new file mode 100644 index 0000000..d902edf --- /dev/null +++ b/gdb/m-newsinit.h @@ -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) diff --git a/gdb/m-npl.h b/gdb/m-npl.h new file mode 100644 index 0000000..135e5ba --- /dev/null +++ b/gdb/m-npl.h @@ -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"); } diff --git a/gdb/m-nplinit.h b/gdb/m-nplinit.h new file mode 100644 index 0000000..840c2c7 --- /dev/null +++ b/gdb/m-nplinit.h @@ -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) diff --git a/gdb/m-pn.h b/gdb/m-pn.h new file mode 100644 index 0000000..6e0bf76 --- /dev/null +++ b/gdb/m-pn.h @@ -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"); } diff --git a/gdb/m-pninit.h b/gdb/m-pninit.h new file mode 100644 index 0000000..4f12eaa --- /dev/null +++ b/gdb/m-pninit.h @@ -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) diff --git a/gdb/m-sun2.h b/gdb/m-sun2.h index 833c923..9babd6b 100644 --- a/gdb/m-sun2.h +++ b/gdb/m-sun2.h @@ -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. */ diff --git a/gdb/m-sun2init.h b/gdb/m-sun2init.h new file mode 100644 index 0000000..2e2f08c --- /dev/null +++ b/gdb/m-sun2init.h @@ -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) diff --git a/gdb/m-sun3.h b/gdb/m-sun3.h index 61b67cd..83ebf45 100644 --- a/gdb/m-sun3.h +++ b/gdb/m-sun3.h @@ -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. */ diff --git a/gdb/m-sun3init.h b/gdb/m-sun3init.h new file mode 100644 index 0000000..5f71ea1 --- /dev/null +++ b/gdb/m-sun3init.h @@ -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) diff --git a/gdb/m-umax.h b/gdb/m-umax.h new file mode 100644 index 0000000..f918738 --- /dev/null +++ b/gdb/m-umax.h @@ -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; \ +} diff --git a/gdb/m-umaxinit.h b/gdb/m-umaxinit.h new file mode 100644 index 0000000..34cc75a --- /dev/null +++ b/gdb/m-umaxinit.h @@ -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) diff --git a/gdb/m-vax.h b/gdb/m-vax.h index 578af44..5eb2a9f 100644 --- a/gdb/m-vax.h +++ b/gdb/m-vax.h @@ -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). */ diff --git a/gdb/m68k-opcode.h b/gdb/m68k-opcode.h index 111fd84..acb9df9 100644 --- a/gdb/m68k-opcode.h +++ b/gdb/m68k-opcode.h @@ -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: */ diff --git a/gdb/m68k-pinsn.c b/gdb/m68k-pinsn.c index 5b59ee1..94ac7f7 100644 --- a/gdb/m68k-pinsn.c +++ b/gdb/m68k-pinsn.c @@ -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 */ } @@ -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. */ diff --git a/gdb/npl-opcode.h b/gdb/npl-opcode.h new file mode 100644 index 0000000..a0421bb --- /dev/null +++ b/gdb/npl-opcode.h @@ -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]); diff --git a/gdb/ns32k-opcode.h b/gdb/ns32k-opcode.h new file mode 100644 index 0000000..2d5ff30 --- /dev/null +++ b/gdb/ns32k-opcode.h @@ -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 diff --git a/gdb/ns32k-pinsn.c b/gdb/ns32k-pinsn.c new file mode 100644 index 0000000..3247edb --- /dev/null +++ b/gdb/ns32k-pinsn.c @@ -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 */ +} diff --git a/gdb/obstack.c b/gdb/obstack.c index 320e1b7..3b5bdef 100644 --- a/gdb/obstack.c +++ b/gdb/obstack.c @@ -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 */ diff --git a/gdb/obstack.h b/gdb/obstack.h index 069afc6..f80f2b1 100644 --- a/gdb/obstack.h +++ b/gdb/obstack.h @@ -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__ */ diff --git a/gdb/opcode.h b/gdb/opcode.h new file mode 100644 index 0000000..acb9df9 --- /dev/null +++ b/gdb/opcode.h @@ -0,0 +1,1272 @@ +/* Opcode table for m68000/m68020 and m68881. */ + +struct m68k_opcode +{ + char *name; + unsigned long opcode; + unsigned long match; + char *args; +}; + +/* 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 is as much longer as necessary to + hold the operands it has. + + The match 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 two characters + for each operand of the instruction. The first specifies + the kind of operand; the second, the place it is stored. */ + +/* Kinds of operands: + D data register only. Stored as 3 bits. + A address register only. Stored as 3 bits. + R either kind of register. Stored as 4 bits. + F floating point coprocessor register only. Stored as 3 bits. + O an offset (or width): immediate data 0-31 or data register. + Stored as 6 bits in special format for BF... insns. + + autoincrement only. Stored as 3 bits (number of the address register). + - autodecrement only. Stored as 3 bits (number of the address register). + Q quick immediate data. Stored as 3 bits. + This matches an immediate operand only when value is in range 1 .. 8. + M moveq immediate data. Stored as 8 bits. + This matches an immediate operand only when value is in range -128..127 + T trap vector immediate data. Stored as 4 bits. + + k K-factor for fmove.p instruction. Stored as a 7-bit constant or + a three bit register offset, depending on the field type. + + # immediate data. Stored in special places (b, w or l) + which say how many bits to store. + ^ immediate data for floating point instructions. Special places + are offset by 2 bytes from '#'... + B pc-relative address, converted to an offset + that is treated as immediate data. + d displacement and register. Stores the register as 3 bits + and stores the displacement in the entire second word. + + C the CCR. No need to store it; this is just for filtering validity. + S the SR. No need to store, just as with CCR. + U the USP. No need to store, just as with CCR. + + I Coprocessor ID. Not printed if 1. The Coprocessor ID is always + extracted from the 'd' field of word one, which means that an extended + coprocessor opcode can be skipped using the 'i' place, if needed. + + s System Control register for the floating point coprocessor. + + J Misc register for movec instruction, stored in 'j' format. + Possible values: + 000 SFC Source Function Code reg + 001 DFC Data Function Code reg + 002 CACR Cache Control Register + 800 USP User Stack Pointer + 801 VBR Vector Base reg + 802 CAAR Cache Address Register + 803 MSP Master Stack Pointer + 804 ISP Interrupt Stack Pointer + + These specify various classes of addressing modes. + They are all stored as 6 bits using an address mode and a register number; + they differ in which addressing modes they match. + + * all (modes 0-6,7.*) + ~ alterable memory (modes 2-6,7.0,7.1)(not 0,1,7.~) + % alterable (modes 0-6,7.0,7.1)(not 7.~) + ; data (modes 0,2-6,7.*)(not 1) + @ data, but not immediate (modes 0,2-6,7.???)(not 1,7.?) This may really be ;, the 68020 book says it is + ! control (modes 2,5,6,7.*-)(not 0,1,3,4,7.4) + & alterable control (modes 2,5,6,7.0,7.1)(not 0,1,7.???) + $ alterable data (modes 0,2-6,7.0,7.1)(not 1,7.~) + ? alterable control, or data register (modes 0,2,5,6,7.0,7.1)(not 1,3,4,7.~) + / control, or data register (modes 0,2,5,6,7.0,7.1,7.2,7.3)(not 1,3,4,7.4) +*/ + +/* Places to put an operand, for non-general operands: + s source, low bits of first word. + d dest, shifted 9 in first word + 1 second word, shifted 12 + 2 second word, shifted 6 + 3 second word, shifted 0 + 4 third word, shifted 12 + 5 third word, shifted 6 + 6 third word, shifted 0 + 7 second word, shifted 7 + 8 second word, shifted 10 + D store in both place 1 and place 3; for divul and divsl. + b second word, low byte + w second word (entire) + l second and third word (entire) + g branch offset for bra and similar instructions. + The place to store depends on the magnitude of offset. + t store in both place 7 and place 8; for floating point operations + c branch offset for cpBcc operations. + The place to store is word two if bit six of word one is zero, + and words two and three if bit six of word one is one. + i Increment by two, to skip over coprocessor extended operands. Only + works with the 'I' format. + k Dynamic K-factor field. Bits 6-4 of word 2, used as a register number. + Also used for dynamic fmovem instruction. + C floating point coprocessor constant - 7 bits. Also used for static + K-factors... + j Movec register #, stored in 12 low bits of second word. + + Places to put operand, for general operands: + d destination, shifted 6 bits in first word + b source, at low bit of first word, and immediate uses one byte + w source, at low bit of first word, and immediate uses two bytes + l source, at low bit of first word, and immediate uses four bytes + s source, at low bit of first word. + Used sometimes in contexts where immediate is not allowed anyway. + f single precision float, low bit of 1st word, immediate uses 4 bytes + F double precision float, low bit of 1st word, immediate uses 8 bytes + x extended precision float, low bit of 1st word, immediate uses 12 bytes + p packed float, low bit of 1st word, immediate uses 12 bytes +*/ + +#define one(x) ((x) << 16) +#define two(x, y) (((x) << 16) + y) + +/* 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 m68k_opcode m68k_opcodes[] = +{ +{"abcd", one(0140400), one(0170770), "DsDd"}, +{"abcd", one(0140410), one(0170770), "-s-d"}, + + /* Add instructions */ +{"addal", one(0150700), one(0170700), "*lAd"}, +{"addaw", one(0150300), one(0170700), "*wAd"}, +{"addib", one(0003000), one(0177700), "#b$b"}, +{"addil", one(0003200), one(0177700), "#l$l"}, +{"addiw", one(0003100), one(0177700), "#w$w"}, +{"addqb", one(0050000), one(0170700), "Qd$b"}, +{"addql", one(0050200), one(0170700), "Qd%l"}, +{"addqw", one(0050100), one(0170700), "Qd%w"}, + +{"addb", one(0003000), one(0177700), "#b$b"}, /* addi written as add */ +{"addb", one(0050000), one(0170700), "Qd$b"}, /* addq written as add */ +{"addb", one(0150000), one(0170700), ";bDd"}, /* addb <ea>, Dd */ +{"addb", one(0150400), one(0170700), "Dd~b"}, /* addb Dd, <ea> */ + +{"addw", one(0003100), one(0177700), "#w$w"}, /* addi written as add */ +{"addw", one(0150300), one(0170700), "*wAd"}, /* adda written as add */ +{"addw", one(0050100), one(0170700), "Qd%w"}, /* addq written as add */ +{"addw", one(0150100), one(0170700), "*wDd"}, /* addw <ea>, Dd */ +{"addw", one(0150500), one(0170700), "Dd~w"}, /* addw Dd, <ea> */ + +{"addl", one(0003200), one(0177700), "#l$l"}, /* addi written as add */ +{"addl", one(0150700), one(0170700), "*lAd"}, /* adda written as add */ +{"addl", one(0050200), one(0170700), "Qd%l"}, /* addq written as add */ +{"addl", one(0150200), one(0170700), "*lDd"}, /* addl <ea>, Dd */ +{"addl", one(0150600), one(0170700), "Dd~l"}, /* addl Dd, <ea> */ + +{"addxb", one(0150400), one(0170770), "DsDd"}, +{"addxb", one(0150410), one(0170770), "-s-d"}, +{"addxl", one(0150600), one(0170770), "DsDd"}, +{"addxl", one(0150610), one(0170770), "-s-d"}, +{"addxw", one(0150500), one(0170770), "DsDd"}, +{"addxw", one(0150510), one(0170770), "-s-d"}, + +{"andib", one(0001000), one(0177700), "#b$b"}, +{"andib", one(0001074), one(0177777), "#bCb"}, /* andi to ccr */ +{"andiw", one(0001100), one(0177700), "#w$w"}, +{"andiw", one(0001174), one(0177777), "#wSw"}, /* andi to sr */ +{"andil", one(0001200), one(0177700), "#l$l"}, + +{"andb", one(0001000), one(0177700), "#b$b"}, /* andi written as or */ +{"andb", one(0001074), one(0177777), "#bCb"}, /* andi to ccr */ +{"andb", one(0140000), one(0170700), ";bDd"}, /* memory to register */ +{"andb", one(0140400), one(0170700), "Dd~b"}, /* register to memory */ +{"andw", one(0001100), one(0177700), "#w$w"}, /* andi written as or */ +{"andw", one(0001174), one(0177777), "#wSw"}, /* andi to sr */ +{"andw", one(0140100), one(0170700), ";wDd"}, /* memory to register */ +{"andw", one(0140500), one(0170700), "Dd~w"}, /* register to memory */ +{"andl", one(0001200), one(0177700), "#l$l"}, /* andi written as or */ +{"andl", one(0140200), one(0170700), ";lDd"}, /* memory to register */ +{"andl", one(0140600), one(0170700), "Dd~l"}, /* register to memory */ + +{"aslb", one(0160400), one(0170770), "QdDs"}, +{"aslb", one(0160440), one(0170770), "DdDs"}, +{"asll", one(0160600), one(0170770), "QdDs"}, +{"asll", one(0160640), one(0170770), "DdDs"}, +{"aslw", one(0160500), one(0170770), "QdDs"}, +{"aslw", one(0160540), one(0170770), "DdDs"}, +{"aslw", one(0160700), one(0177700), "~s"}, /* Shift memory */ +{"asrb", one(0160000), one(0170770), "QdDs"}, +{"asrb", one(0160040), one(0170770), "DdDs"}, +{"asrl", one(0160200), one(0170770), "QdDs"}, +{"asrl", one(0160240), one(0170770), "DdDs"}, +{"asrw", one(0160100), one(0170770), "QdDs"}, +{"asrw", one(0160140), one(0170770), "DdDs"}, +{"asrw", one(0160300), one(0177700), "~s"}, /* Shift memory */ + +{"bhi", one(0061000), one(0177400), "Bg"}, +{"bls", one(0061400), one(0177400), "Bg"}, +{"bcc", one(0062000), one(0177400), "Bg"}, +{"bcs", one(0062400), one(0177400), "Bg"}, +{"bne", one(0063000), one(0177400), "Bg"}, +{"beq", one(0063400), one(0177400), "Bg"}, +{"bvc", one(0064000), one(0177400), "Bg"}, +{"bvs", one(0064400), one(0177400), "Bg"}, +{"bpl", one(0065000), one(0177400), "Bg"}, +{"bmi", one(0065400), one(0177400), "Bg"}, +{"bge", one(0066000), one(0177400), "Bg"}, +{"blt", one(0066400), one(0177400), "Bg"}, +{"bgt", one(0067000), one(0177400), "Bg"}, +{"ble", one(0067400), one(0177400), "Bg"}, + +{"bchg", one(0000500), one(0170700), "Dd$s"}, +{"bchg", one(0004100), one(0177700), "#b$s"}, +{"bclr", one(0000600), one(0170700), "Dd$s"}, +{"bclr", one(0004200), one(0177700), "#b$s"}, +{"bfchg", two(0165300, 0), two(0177700, 0170000), "?sO2O3"}, +{"bfclr", two(0166300, 0), two(0177700, 0170000), "?sO2O3"}, +{"bfexts", two(0165700, 0), two(0177700, 0100000), "/sO2O3D1"}, +{"bfextu", two(0164700, 0), two(0177700, 0100000), "/sO2O3D1"}, +{"bfffo", two(0166700, 0), two(0177700, 0100000), "/sO2O3D1"}, +{"bfins", two(0167700, 0), two(0177700, 0100000), "D1?sO2O3"}, +{"bfset", two(0167300, 0), two(0177700, 0170000), "?sO2O3"}, +{"bftst", two(0164300, 0), two(0177700, 0170000), "/sO2O3"}, +{"bset", one(0000700), one(0170700), "Dd$s"}, +{"bset", one(0004300), one(0177700), "#b$s"}, +{"btst", one(0000400), one(0170700), "Dd@s"}, +{"btst", one(0004000), one(0177700), "#b@s"}, + +{"bkpt", one(0044110), one(0177770), "Qs"}, +{"bra", one(0060000), one(0177400), "Bg"}, +{"bsr", one(0060400), one(0177400), "Bg"}, +{"callm", one(0003300), one(0177700), "#b!s"}, +{"cas2l", two(0007374, 0), two(0177777, 0107070), "D3D6D2D5R1R4"}, /* JF FOO this is really a 3 word ins */ +{"cas2w", two(0006374, 0), two(0177777, 0107070), "D3D6D2D5R1R4"}, /* JF ditto */ +{"casb", two(0005300, 0), two(0177700, 0177070), "D3D2~s"}, +{"casl", two(0007300, 0), two(0177700, 0177070), "D3D2~s"}, +{"casw", two(0006300, 0), two(0177700, 0177070), "D3D2~s"}, + +/* {"chk", one(0040600), one(0170700), ";wDd"}, JF FOO this looks wrong */ +{"chk2b", two(0000300, 0004000), two(0177700, 07777), "!sR1"}, +{"chk2l", two(0002300, 0004000), two(0177700, 07777), "!sR1"}, +{"chk2w", two(0001300, 0004000), two(0177700, 07777), "!sR1"}, +{"chkl", one(0040400), one(0170700), ";lDd"}, +{"chkw", one(0040600), one(0170700), ";wDd"}, +{"clrb", one(0041000), one(0177700), "$s"}, +{"clrl", one(0041200), one(0177700), "$s"}, +{"clrw", one(0041100), one(0177700), "$s"}, + +{"cmp2b", two(0000300, 0), two(0177700, 07777), "!sR1"}, +{"cmp2l", two(0002300, 0), two(0177700, 07777), "!sR1"}, +{"cmp2w", two(0001300, 0), two(0177700, 07777), "!sR1"}, +{"cmpal", one(0130700), one(0170700), "*lAd"}, +{"cmpaw", one(0130300), one(0170700), "*wAd"}, +{"cmpib", one(0006000), one(0177700), "#b;b"}, +{"cmpil", one(0006200), one(0177700), "#l;l"}, +{"cmpiw", one(0006100), one(0177700), "#w;w"}, +{"cmpb", one(0006000), one(0177700), "#b;b"}, /* cmpi written as cmp */ +{"cmpb", one(0130000), one(0170700), ";bDd"}, +{"cmpw", one(0006100), one(0177700), "#w;w"}, +{"cmpw", one(0130100), one(0170700), "*wDd"}, +{"cmpw", one(0130300), one(0170700), "*wAd"}, /* cmpa written as cmp */ +{"cmpl", one(0006200), one(0177700), "#l;l"}, +{"cmpl", one(0130200), one(0170700), "*lDd"}, +{"cmpl", one(0130700), one(0170700), "*lAd"}, +{"cmpmb", one(0130410), one(0170770), "+s+d"}, +{"cmpml", one(0130610), one(0170770), "+s+d"}, +{"cmpmw", one(0130510), one(0170770), "+s+d"}, + +{"dbcc", one(0052310), one(0177770), "DsBw"}, +{"dbcs", one(0052710), one(0177770), "DsBw"}, +{"dbeq", one(0053710), one(0177770), "DsBw"}, +{"dbf", one(0050710), one(0177770), "DsBw"}, +{"dbge", one(0056310), one(0177770), "DsBw"}, +{"dbgt", one(0057310), one(0177770), "DsBw"}, +{"dbhi", one(0051310), one(0177770), "DsBw"}, +{"dble", one(0057710), one(0177770), "DsBw"}, +{"dbls", one(0051710), one(0177770), "DsBw"}, +{"dblt", one(0056710), one(0177770), "DsBw"}, +{"dbmi", one(0055710), one(0177770), "DsBw"}, +{"dbne", one(0053310), one(0177770), "DsBw"}, +{"dbpl", one(0055310), one(0177770), "DsBw"}, +{"dbra", one(0050710), one(0177770), "DsBw"}, +{"dbt", one(0050310), one(0177770), "DsBw"}, +{"dbvc", one(0054310), one(0177770), "DsBw"}, +{"dbvs", one(0054710), one(0177770), "DsBw"}, + +{"divsl", two(0046100, 0006000), two(0177700, 0107770), ";lD3D1"}, +{"divsl", two(0046100, 0004000), two(0177700, 0107770), ";lDD"}, +{"divsll", two(0046100, 0004000), two(0177700, 0107770), ";lD3D1"}, +{"divsw", one(0100700), one(0170700), ";wDd"}, +{"divs", one(0100700), one(0170700), ";wDd"}, +{"divul", two(0046100, 0002000), two(0177700, 0107770), ";lD3D1"}, +{"divul", two(0046100, 0000000), two(0177700, 0107770), ";lDD"}, +{"divull", two(0046100, 0000000), two(0177700, 0107770), ";lD3D1"}, +{"divuw", one(0100300), one(0170700), ";wDd"}, +{"divu", one(0100300), one(0170700), ";wDd"}, +{"eorb", one(0005000), one(0177700), "#b$s"}, /* eori written as or */ +{"eorb", one(0005074), one(0177777), "#bCs"}, /* eori to ccr */ +{"eorb", one(0130400), one(0170700), "Dd$s"}, /* register to memory */ +{"eorib", one(0005000), one(0177700), "#b$s"}, +{"eorib", one(0005074), one(0177777), "#bCs"}, /* eori to ccr */ +{"eoril", one(0005200), one(0177700), "#l$s"}, +{"eoriw", one(0005100), one(0177700), "#w$s"}, +{"eoriw", one(0005174), one(0177777), "#wSs"}, /* eori to sr */ +{"eorl", one(0005200), one(0177700), "#l$s"}, +{"eorl", one(0130600), one(0170700), "Dd$s"}, +{"eorw", one(0005100), one(0177700), "#w$s"}, +{"eorw", one(0005174), one(0177777), "#wSs"}, /* eori to sr */ +{"eorw", one(0130500), one(0170700), "Dd$s"}, + +{"exg", one(0140500), one(0170770), "DdDs"}, +{"exg", one(0140510), one(0170770), "AdAs"}, +{"exg", one(0140610), one(0170770), "DdAs"}, +{"exg", one(0140610), one(0170770), "AsDd"}, + +{"extw", one(0044200), one(0177770), "Ds"}, +{"extl", one(0044300), one(0177770), "Ds"}, +{"extbl", one(0044700), one(0177770), "Ds"}, +{"extb.l", one(0044700), one(0177770), "Ds"}, /* Not sure we should support this one*/ + +{"illegal", one(0045374), one(0177777), ""}, +{"jmp", one(0047300), one(0177700), "!s"}, +{"jsr", one(0047200), one(0177700), "!s"}, +{"lea", one(0040700), one(0170700), "!sAd"}, +{"linkw", one(0047120), one(0177770), "As#w"}, +{"linkl", one(0044010), one(0177770), "As#l"}, +{"link", one(0047120), one(0177770), "As#w"}, +{"link", one(0044010), one(0177770), "As#l"}, + +{"lslb", one(0160410), one(0170770), "QdDs"}, /* lsrb #Q, Ds */ +{"lslb", one(0160450), one(0170770), "DdDs"}, /* lsrb Dd, Ds */ +{"lslw", one(0160510), one(0170770), "QdDs"}, /* lsrb #Q, Ds */ +{"lslw", one(0160550), one(0170770), "DdDs"}, /* lsrb Dd, Ds */ +{"lslw", one(0161700), one(0177700), "~s"}, /* Shift memory */ +{"lsll", one(0160610), one(0170770), "QdDs"}, /* lsrb #Q, Ds */ +{"lsll", one(0160650), one(0170770), "DdDs"}, /* lsrb Dd, Ds */ + +{"lsrb", one(0160010), one(0170770), "QdDs"} /* lsrb #Q, Ds */, +{"lsrb", one(0160050), one(0170770), "DdDs"}, /* lsrb Dd, Ds */ +{"lsrl", one(0160210), one(0170770), "QdDs"}, /* lsrb #Q, Ds */ +{"lsrl", one(0160250), one(0170770), "DdDs"}, /* lsrb #Q, Ds */ +{"lsrw", one(0160110), one(0170770), "QdDs"}, /* lsrb #Q, Ds */ +{"lsrw", one(0160150), one(0170770), "DdDs"}, /* lsrb #Q, Ds */ +{"lsrw", one(0161300), one(0177700), "~s"}, /* Shift memory */ + +{"moveal", one(0020100), one(0170700), "*lAd"}, +{"moveaw", one(0030100), one(0170700), "*wAd"}, +{"moveb", one(0010000), one(0170000), ";b$d"}, /* move */ + +{"movec", one(0047173), one(0177777), "R1Jj"}, +{"movec", one(0047173), one(0177777), "R1#j"}, +{"movec", one(0047172), one(0177777), "JjR1"}, +{"movec", one(0047172), one(0177777), "#jR1"}, + +{"movel", one(0020000), one(0170000), "*l$d"}, +{"movel", one(0020100), one(0170700), "*lAd"}, +{"movel", one(0047140), one(0177770), "AsUd"}, /* move to USP */ +{"movel", one(0047150), one(0177770), "UdAs"}, /* move from USP */ +{"movel", one(0070000), one(0170400), "MsDd"}, /* moveq written as move */ + +{"moveml", one(0044300), one(0177700), "#w&s"}, /* movem reg to mem. */ +{"moveml", one(0044340), one(0177770), "#w-s"}, /* movem reg to autodecrement. */ +{"moveml", one(0046300), one(0177700), "!s#w"}, /* movem mem to reg. */ +{"moveml", one(0046330), one(0177770), "+s#w"}, /* movem autoinc to reg. */ + +{"movemw", one(0044200), one(0177700), "#w&s"}, /* movem reg to mem. */ +{"movemw", one(0044240), one(0177770), "#w-s"}, /* movem reg to autodecrement. */ +{"movemw", one(0046200), one(0177700), "!s#w"}, /* movem mem to reg. */ +{"movemw", one(0046230), one(0177770), "+s#w"}, /* movem autoinc to reg. */ + +{"movepl", one(0000510), one(0170770), "dsDd"}, /* memory to register */ +{"movepl", one(0000710), one(0170770), "Ddds"}, /* register to memory */ +{"movepw", one(0000410), one(0170770), "dsDd"}, /* memory to register */ +{"movepw", one(0000610), one(0170770), "Ddds"}, /* register to memory */ +{"moveq", one(0070000), one(0170400), "MsDd"}, +{"movew", one(0030000), one(0170000), "*w$d"}, +{"movew", one(0030100), one(0170700), "*wAd"}, /* movea, written as move */ +{"movew", one(0040300), one(0177700), "Ss$s"}, /* Move from sr */ +{"movew", one(0041300), one(0177700), "Cs$s"}, /* Move from ccr */ +{"movew", one(0042300), one(0177700), ";wCd"}, /* move to ccr */ +{"movew", one(0043300), one(0177700), ";wSd"}, /* move to sr */ + +{"movesb", two(0007000, 0), two(0177700, 07777), "~sR1"}, /* moves from memory */ +{"movesb", two(0007000, 04000), two(0177700, 07777), "R1~s"}, /* moves to memory */ +{"movesl", two(0007200, 0), two(0177700, 07777), "~sR1"}, /* moves from memory */ +{"movesl", two(0007200, 04000), two(0177700, 07777), "R1~s"}, /* moves to memory */ +{"movesw", two(0007100, 0), two(0177700, 07777), "~sR1"}, /* moves from memory */ +{"movesw", two(0007100, 04000), two(0177700, 07777), "R1~s"}, /* moves to memory */ + +{"mulsl", two(0046000, 004000), two(0177700, 0107770), ";lD1"}, +{"mulsl", two(0046000, 006000), two(0177700, 0107770), ";lD3D1"}, +{"mulsw", one(0140700), one(0170700), ";wDd"}, +{"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), ";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"}, +{"negw", one(0042100), one(0177700), "$s"}, +{"negxb", one(0040000), one(0177700), "$s"}, +{"negxl", one(0040200), one(0177700), "$s"}, +{"negxw", one(0040100), one(0177700), "$s"}, +{"nop", one(0047161), one(0177777), ""}, +{"notb", one(0043000), one(0177700), "$s"}, +{"notl", one(0043200), one(0177700), "$s"}, +{"notw", one(0043100), one(0177700), "$s"}, + +{"orb", one(0000000), one(0177700), "#b$s"}, /* ori written as or */ +{"orb", one(0000074), one(0177777), "#bCs"}, /* ori to ccr */ +{"orb", one(0100000), one(0170700), ";bDd"}, /* memory to register */ +{"orb", one(0100400), one(0170700), "Dd~s"}, /* register to memory */ +{"orib", one(0000000), one(0177700), "#b$s"}, +{"orib", one(0000074), one(0177777), "#bCs"}, /* ori to ccr */ +{"oril", one(0000200), one(0177700), "#l$s"}, +{"oriw", one(0000100), one(0177700), "#w$s"}, +{"oriw", one(0000174), one(0177777), "#wSs"}, /* ori to sr */ +{"orl", one(0000200), one(0177700), "#l$s"}, +{"orl", one(0100200), one(0170700), ";lDd"}, /* memory to register */ +{"orl", one(0100600), one(0170700), "Dd~s"}, /* register to memory */ +{"orw", one(0000100), one(0177700), "#w$s"}, +{"orw", one(0000174), one(0177777), "#wSs"}, /* ori to sr */ +{"orw", one(0100100), one(0170700), ";wDd"}, /* memory to register */ +{"orw", one(0100500), one(0170700), "Dd~s"}, /* register to memory */ + +{"pack", one(0100500), one(0170770), "DsDd#w"}, /* pack Ds, Dd, #w */ +{"pack", one(0100510), one(0170770), "-s-d#w"}, /* pack -(As), -(Ad), #w */ +{"pea", one(0044100), one(0177700), "!s"}, +{"reset", one(0047160), one(0177777), ""}, + +{"rolb", one(0160430), one(0170770), "QdDs"}, /* rorb #Q, Ds */ +{"rolb", one(0160470), one(0170770), "DdDs"}, /* rorb Dd, Ds */ +{"roll", one(0160630), one(0170770), "QdDs"}, /* rorb #Q, Ds */ +{"roll", one(0160670), one(0170770), "DdDs"}, /* rorb Dd, Ds */ +{"rolw", one(0160530), one(0170770), "QdDs"}, /* rorb #Q, Ds */ +{"rolw", one(0160570), one(0170770), "DdDs"}, /* rorb Dd, Ds */ +{"rolw", one(0163700), one(0177700), "~s"}, /* Rotate memory */ +{"rorb", one(0160030), one(0170770), "QdDs"}, /* rorb #Q, Ds */ +{"rorb", one(0160070), one(0170770), "DdDs"}, /* rorb Dd, Ds */ +{"rorl", one(0160230), one(0170770), "QdDs"}, /* rorb #Q, Ds */ +{"rorl", one(0160270), one(0170770), "DdDs"}, /* rorb Dd, Ds */ +{"rorw", one(0160130), one(0170770), "QdDs"}, /* rorb #Q, Ds */ +{"rorw", one(0160170), one(0170770), "DdDs"}, /* rorb Dd, Ds */ +{"rorw", one(0163300), one(0177700), "~s"}, /* Rotate memory */ + +{"roxlb", one(0160420), one(0170770), "QdDs"}, /* roxrb #Q, Ds */ +{"roxlb", one(0160460), one(0170770), "DdDs"}, /* roxrb Dd, Ds */ +{"roxll", one(0160620), one(0170770), "QdDs"}, /* roxrb #Q, Ds */ +{"roxll", one(0160660), one(0170770), "DdDs"}, /* roxrb Dd, Ds */ +{"roxlw", one(0160520), one(0170770), "QdDs"}, /* roxrb #Q, Ds */ +{"roxlw", one(0160560), one(0170770), "DdDs"}, /* roxrb Dd, Ds */ +{"roxlw", one(0162700), one(0177700), "~s"}, /* Rotate memory */ +{"roxrb", one(0160020), one(0170770), "QdDs"}, /* roxrb #Q, Ds */ +{"roxrb", one(0160060), one(0170770), "DdDs"}, /* roxrb Dd, Ds */ +{"roxrl", one(0160220), one(0170770), "QdDs"}, /* roxrb #Q, Ds */ +{"roxrl", one(0160260), one(0170770), "DdDs"}, /* roxrb Dd, Ds */ +{"roxrw", one(0160120), one(0170770), "QdDs"}, /* roxrb #Q, Ds */ +{"roxrw", one(0160160), one(0170770), "DdDs"}, /* roxrb Dd, Ds */ +{"roxrw", one(0162300), one(0177700), "~s"}, /* Rotate memory */ + +{"rtd", one(0047164), one(0177777), "#w"}, +{"rte", one(0047163), one(0177777), ""}, +{"rtm", one(0003300), one(0177760), "Rs"}, +{"rtr", one(0047167), one(0177777), ""}, +{"rts", one(0047165), one(0177777), ""}, + +{"scc", one(0052300), one(0177700), "$s"}, +{"scs", one(0052700), one(0177700), "$s"}, +{"seq", one(0053700), one(0177700), "$s"}, +{"sf", one(0050700), one(0177700), "$s"}, +{"sge", one(0056300), one(0177700), "$s"}, +{"sgt", one(0057300), one(0177700), "$s"}, +{"shi", one(0051300), one(0177700), "$s"}, +{"sle", one(0057700), one(0177700), "$s"}, +{"sls", one(0051700), one(0177700), "$s"}, +{"slt", one(0056700), one(0177700), "$s"}, +{"smi", one(0055700), one(0177700), "$s"}, +{"sne", one(0053300), one(0177700), "$s"}, +{"spl", one(0055300), one(0177700), "$s"}, +{"st", one(0050300), one(0177700), "$s"}, +{"svc", one(0054300), one(0177700), "$s"}, +{"svs", one(0054700), one(0177700), "$s"}, + +{"sbcd", one(0100400), one(0170770), "DsDd"}, +{"sbcd", one(0100410), one(0170770), "-s-d"}, +{"stop", one(0047162), one(0177777), "#w"}, + +{"subal", one(0110700), one(0170700), "*lAd"}, +{"subaw", one(0110300), one(0170700), "*wAd"}, +{"subb", one(0002000), one(0177700), "#b$s"}, /* subi written as sub */ +{"subb", one(0050400), one(0170700), "Qd%s"}, /* subq written as sub */ +{"subb", one(0110000), one(0170700), ";bDd"}, /* subb ??, Dd */ +{"subb", one(0110400), one(0170700), "Dd~s"}, /* subb Dd, ?? */ +{"subib", one(0002000), one(0177700), "#b$s"}, +{"subil", one(0002200), one(0177700), "#l$s"}, +{"subiw", one(0002100), one(0177700), "#w$s"}, +{"subl", one(0002200), one(0177700), "#l$s"}, +{"subl", one(0050600), one(0170700), "Qd%s"}, +{"subl", one(0110200), one(0170700), "*lDd"}, +{"subl", one(0110600), one(0170700), "Dd~s"}, +{"subl", one(0110700), one(0170700), "*lAd"}, +{"subqb", one(0050400), one(0170700), "Qd%s"}, +{"subql", one(0050600), one(0170700), "Qd%s"}, +{"subqw", one(0050500), one(0170700), "Qd%s"}, +{"subw", one(0002100), one(0177700), "#w$s"}, +{"subw", one(0050500), one(0170700), "Qd%s"}, +{"subw", one(0110100), one(0170700), "*wDd"}, +{"subw", one(0110300), one(0170700), "*wAd"}, /* suba written as sub */ +{"subw", one(0110500), one(0170700), "Dd~s"}, + +{"subxb", one(0110400), one(0170770), "DsDd"}, /* subxb Ds, Dd */ +{"subxb", one(0110410), one(0170770), "-s-d"}, /* subxb -(As), -(Ad) */ +{"subxl", one(0110600), one(0170770), "DsDd"}, +{"subxl", one(0110610), one(0170770), "-s-d"}, +{"subxw", one(0110500), one(0170770), "DsDd"}, +{"subxw", one(0110510), one(0170770), "-s-d"}, + +{"swap", one(0044100), one(0177770), "Ds"}, + +{"tas", one(0045300), one(0177700), "$s"}, +{"trap", one(0047100), one(0177760), "Ts"}, + +{"trapcc", one(0052374), one(0177777), ""}, +{"trapcs", one(0052774), one(0177777), ""}, +{"trapeq", one(0053774), one(0177777), ""}, +{"trapf", one(0050774), one(0177777), ""}, +{"trapge", one(0056374), one(0177777), ""}, +{"trapgt", one(0057374), one(0177777), ""}, +{"traphi", one(0051374), one(0177777), ""}, +{"traple", one(0057774), one(0177777), ""}, +{"trapls", one(0051774), one(0177777), ""}, +{"traplt", one(0056774), one(0177777), ""}, +{"trapmi", one(0055774), one(0177777), ""}, +{"trapne", one(0053374), one(0177777), ""}, +{"trappl", one(0055374), one(0177777), ""}, +{"trapt", one(0050374), one(0177777), ""}, +{"trapvc", one(0054374), one(0177777), ""}, +{"trapvs", one(0054774), one(0177777), ""}, + +{"trapcc.w", one(0052372), one(0177777), ""}, +{"trapcs.w", one(0052772), one(0177777), ""}, +{"trapeq.w", one(0053772), one(0177777), ""}, +{"trapf.w", one(0050772), one(0177777), ""}, +{"trapge.w", one(0056372), one(0177777), ""}, +{"trapgt.w", one(0057372), one(0177777), ""}, +{"traphi.w", one(0051372), one(0177777), ""}, +{"traple.w", one(0057772), one(0177777), ""}, +{"trapls.w", one(0051772), one(0177777), ""}, +{"traplt.w", one(0056772), one(0177777), ""}, +{"trapmi.w", one(0055772), one(0177777), ""}, +{"trapne.w", one(0053372), one(0177777), ""}, +{"trappl.w", one(0055372), one(0177777), ""}, +{"trapt.w", one(0050372), one(0177777), ""}, +{"trapvc.w", one(0054372), one(0177777), ""}, +{"trapvs.w", one(0054772), one(0177777), ""}, + +{"trapcc.l", one(0052373), one(0177777), ""}, +{"trapcs.l", one(0052773), one(0177777), ""}, +{"trapeq.l", one(0053773), one(0177777), ""}, +{"trapf.l", one(0050773), one(0177777), ""}, +{"trapge.l", one(0056373), one(0177777), ""}, +{"trapgt.l", one(0057373), one(0177777), ""}, +{"traphi.l", one(0051373), one(0177777), ""}, +{"traple.l", one(0057773), one(0177777), ""}, +{"trapls.l", one(0051773), one(0177777), ""}, +{"traplt.l", one(0056773), one(0177777), ""}, +{"trapmi.l", one(0055773), one(0177777), ""}, +{"trapne.l", one(0053373), one(0177777), ""}, +{"trappl.l", one(0055373), one(0177777), ""}, +{"trapt.l", one(0050373), one(0177777), ""}, +{"trapvc.l", one(0054373), one(0177777), ""}, +{"trapvs.l", one(0054773), one(0177777), ""}, + +{"trapv", one(0047166), one(0177777), ""}, + +{"tstb", one(0045000), one(0177700), ";b"}, +{"tstw", one(0045100), one(0177700), "*w"}, +{"tstl", one(0045200), one(0177700), "*l"}, + +{"unlk", one(0047130), one(0177770), "As"}, +{"unpk", one(0100600), one(0170770), "DsDd#w"}, +{"unpk", one(0100610), one(0170770), "-s-d#w"}, + /* JF floating pt stuff moved down here */ + +{"fabsb", two(0xF000, 0x5818), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fabsd", two(0xF000, 0x5418), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fabsl", two(0xF000, 0x4018), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fabsp", two(0xF000, 0x4C18), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fabss", two(0xF000, 0x4418), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fabsw", two(0xF000, 0x5018), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fabsx", two(0xF000, 0x0018), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fabsx", two(0xF000, 0x4818), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fabsx", two(0xF000, 0x0018), two(0xF1C0, 0xE07F), "IiFt"}, + +{"facosb", two(0xF000, 0x581C), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"facosd", two(0xF000, 0x541C), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"facosl", two(0xF000, 0x401C), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"facosp", two(0xF000, 0x4C1C), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"facoss", two(0xF000, 0x441C), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"facosw", two(0xF000, 0x501C), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"facosx", two(0xF000, 0x001C), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"facosx", two(0xF000, 0x481C), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"facosx", two(0xF000, 0x001C), two(0xF1C0, 0xE07F), "IiFt"}, + +{"faddb", two(0xF000, 0x5822), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"faddd", two(0xF000, 0x5422), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"faddl", two(0xF000, 0x4022), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"faddp", two(0xF000, 0x4C22), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fadds", two(0xF000, 0x4422), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"faddw", two(0xF000, 0x5022), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"faddx", two(0xF000, 0x0022), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"faddx", two(0xF000, 0x4822), two(0xF1C0, 0xFC7F), "Ii;xF7"}, + +{"fasinb", two(0xF000, 0x580C), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fasind", two(0xF000, 0x540C), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fasinl", two(0xF000, 0x400C), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fasinp", two(0xF000, 0x4C0C), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fasins", two(0xF000, 0x440C), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fasinw", two(0xF000, 0x500C), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fasinx", two(0xF000, 0x000C), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fasinx", two(0xF000, 0x480C), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fasinx", two(0xF000, 0x000C), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fatanb", two(0xF000, 0x580A), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fatand", two(0xF000, 0x540A), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fatanl", two(0xF000, 0x400A), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fatanp", two(0xF000, 0x4C0A), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fatans", two(0xF000, 0x440A), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fatanw", two(0xF000, 0x500A), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fatanx", two(0xF000, 0x000A), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fatanx", two(0xF000, 0x480A), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fatanx", two(0xF000, 0x000A), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fatanhb", two(0xF000, 0x580D), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fatanhd", two(0xF000, 0x540D), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fatanhl", two(0xF000, 0x400D), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fatanhp", two(0xF000, 0x4C0D), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fatanhs", two(0xF000, 0x440D), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fatanhw", two(0xF000, 0x500D), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fatanhx", two(0xF000, 0x000D), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fatanhx", two(0xF000, 0x480D), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fatanhx", two(0xF000, 0x000D), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fbeq", one(0xF081), one(0xF1FF), "IdBc"}, +{"fbf", one(0xF080), one(0xF1FF), "IdBc"}, +{"fbge", one(0xF093), one(0xF1FF), "IdBc"}, +{"fbgl", one(0xF096), one(0xF1FF), "IdBc"}, +{"fbgle", one(0xF097), one(0xF1FF), "IdBc"}, +{"fbgt", one(0xF092), one(0xF1FF), "IdBc"}, +{"fble", one(0xF095), one(0xF1FF), "IdBc"}, +{"fblt", one(0xF094), one(0xF1FF), "IdBc"}, +{"fbne", one(0xF08E), one(0xF1FF), "IdBc"}, +{"fbnge", one(0xF09C), one(0xF1FF), "IdBc"}, +{"fbngl", one(0xF099), one(0xF1FF), "IdBc"}, +{"fbngle", one(0xF098), one(0xF1FF), "IdBc"}, +{"fbngt", one(0xF09D), one(0xF1FF), "IdBc"}, +{"fbnle", one(0xF09A), one(0xF1FF), "IdBc"}, +{"fbnlt", one(0xF09B), one(0xF1FF), "IdBc"}, +{"fboge", one(0xF083), one(0xF1FF), "IdBc"}, +{"fbogl", one(0xF086), one(0xF1FF), "IdBc"}, +{"fbogt", one(0xF082), one(0xF1FF), "IdBc"}, +{"fbole", one(0xF085), one(0xF1FF), "IdBc"}, +{"fbolt", one(0xF084), one(0xF1FF), "IdBc"}, +{"fbor", one(0xF087), one(0xF1FF), "IdBc"}, +{"fbseq", one(0xF091), one(0xF1FF), "IdBc"}, +{"fbsf", one(0xF090), one(0xF1FF), "IdBc"}, +{"fbsne", one(0xF09E), one(0xF1FF), "IdBc"}, +{"fbst", one(0xF09F), one(0xF1FF), "IdBc"}, +{"fbt", one(0xF08F), one(0xF1FF), "IdBc"}, +{"fbueq", one(0xF089), one(0xF1FF), "IdBc"}, +{"fbuge", one(0xF08B), one(0xF1FF), "IdBc"}, +{"fbugt", one(0xF08A), one(0xF1FF), "IdBc"}, +{"fbule", one(0xF08D), one(0xF1FF), "IdBc"}, +{"fbult", one(0xF08C), one(0xF1FF), "IdBc"}, +{"fbun", one(0xF088), one(0xF1FF), "IdBc"}, + +{"fcmpb", two(0xF000, 0x5838), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fcmpd", two(0xF000, 0x5438), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fcmpl", two(0xF000, 0x4038), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fcmpp", two(0xF000, 0x4C38), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fcmps", two(0xF000, 0x4438), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fcmpw", two(0xF000, 0x5038), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fcmpx", two(0xF000, 0x0038), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fcmpx", two(0xF000, 0x4838), two(0xF1C0, 0xFC7F), "Ii;xF7"}, + +{"fcosb", two(0xF000, 0x581D), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fcosd", two(0xF000, 0x541D), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fcosl", two(0xF000, 0x401D), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fcosp", two(0xF000, 0x4C1D), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fcoss", two(0xF000, 0x441D), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fcosw", two(0xF000, 0x501D), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fcosx", two(0xF000, 0x001D), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fcosx", two(0xF000, 0x481D), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fcosx", two(0xF000, 0x001D), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fcoshb", two(0xF000, 0x5819), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fcoshd", two(0xF000, 0x5419), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fcoshl", two(0xF000, 0x4019), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fcoshp", two(0xF000, 0x4C19), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fcoshs", two(0xF000, 0x4419), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fcoshw", two(0xF000, 0x5019), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fcoshx", two(0xF000, 0x0019), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fcoshx", two(0xF000, 0x4819), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fcoshx", two(0xF000, 0x0019), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fdbeq", two(0xF048, 0x0001), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbf", two(0xF048, 0x0000), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbge", two(0xF048, 0x0013), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbgl", two(0xF048, 0x0016), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbgle", two(0xF048, 0x0017), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbgt", two(0xF048, 0x0012), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdble", two(0xF048, 0x0015), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdblt", two(0xF048, 0x0014), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbne", two(0xF048, 0x000E), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbnge", two(0xF048, 0x001C), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbngl", two(0xF048, 0x0019), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbngle", two(0xF048, 0x0018), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbngt", two(0xF048, 0x001D), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbnle", two(0xF048, 0x001A), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbnlt", two(0xF048, 0x001B), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdboge", two(0xF048, 0x0003), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbogl", two(0xF048, 0x0006), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbogt", two(0xF048, 0x0002), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbole", two(0xF048, 0x0005), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbolt", two(0xF048, 0x0004), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbor", two(0xF048, 0x0007), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbseq", two(0xF048, 0x0011), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbsf", two(0xF048, 0x0010), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbsne", two(0xF048, 0x001E), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbst", two(0xF048, 0x001F), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbt", two(0xF048, 0x000F), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbueq", two(0xF048, 0x0009), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbuge", two(0xF048, 0x000B), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbugt", two(0xF048, 0x000A), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbule", two(0xF048, 0x000D), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbult", two(0xF048, 0x000C), two(0xF1F8, 0xFFFF), "IiDsBw"}, +{"fdbun", two(0xF048, 0x0008), two(0xF1F8, 0xFFFF), "IiDsBw"}, + +{"fdivb", two(0xF000, 0x5820), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fdivd", two(0xF000, 0x5420), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fdivl", two(0xF000, 0x4020), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fdivp", two(0xF000, 0x4C20), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fdivs", two(0xF000, 0x4420), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fdivw", two(0xF000, 0x5020), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fdivx", two(0xF000, 0x0020), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fdivx", two(0xF000, 0x4820), two(0xF1C0, 0xFC7F), "Ii;xF7"}, + +{"fetoxb", two(0xF000, 0x5810), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fetoxd", two(0xF000, 0x5410), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fetoxl", two(0xF000, 0x4010), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fetoxp", two(0xF000, 0x4C10), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fetoxs", two(0xF000, 0x4410), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fetoxw", two(0xF000, 0x5010), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fetoxx", two(0xF000, 0x0010), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fetoxx", two(0xF000, 0x4810), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fetoxx", two(0xF000, 0x0010), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fetoxm1b", two(0xF000, 0x5808), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fetoxm1d", two(0xF000, 0x5408), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fetoxm1l", two(0xF000, 0x4008), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fetoxm1p", two(0xF000, 0x4C08), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fetoxm1s", two(0xF000, 0x4408), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fetoxm1w", two(0xF000, 0x5008), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fetoxm1x", two(0xF000, 0x0008), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fetoxm1x", two(0xF000, 0x4808), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fetoxm1x", two(0xF000, 0x0008), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fgetexpb", two(0xF000, 0x581E), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fgetexpd", two(0xF000, 0x541E), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fgetexpl", two(0xF000, 0x401E), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fgetexpp", two(0xF000, 0x4C1E), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fgetexps", two(0xF000, 0x441E), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fgetexpw", two(0xF000, 0x501E), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fgetexpx", two(0xF000, 0x001E), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fgetexpx", two(0xF000, 0x481E), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fgetexpx", two(0xF000, 0x001E), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fgetmanb", two(0xF000, 0x581F), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fgetmand", two(0xF000, 0x541F), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fgetmanl", two(0xF000, 0x401F), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fgetmanp", two(0xF000, 0x4C1F), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fgetmans", two(0xF000, 0x441F), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fgetmanw", two(0xF000, 0x501F), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fgetmanx", two(0xF000, 0x001F), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fgetmanx", two(0xF000, 0x481F), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fgetmanx", two(0xF000, 0x001F), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fintb", two(0xF000, 0x5801), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fintd", two(0xF000, 0x5401), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fintl", two(0xF000, 0x4001), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fintp", two(0xF000, 0x4C01), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fints", two(0xF000, 0x4401), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fintw", two(0xF000, 0x5001), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fintx", two(0xF000, 0x0001), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fintx", two(0xF000, 0x4801), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fintx", two(0xF000, 0x0001), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fintrzb", two(0xF000, 0x5803), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fintrzd", two(0xF000, 0x5403), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fintrzl", two(0xF000, 0x4003), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fintrzp", two(0xF000, 0x4C03), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fintrzs", two(0xF000, 0x4403), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fintrzw", two(0xF000, 0x5003), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fintrzx", two(0xF000, 0x0003), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fintrzx", two(0xF000, 0x4803), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fintrzx", two(0xF000, 0x0003), two(0xF1C0, 0xE07F), "IiFt"}, + +{"flog10b", two(0xF000, 0x5815), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"flog10d", two(0xF000, 0x5415), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"flog10l", two(0xF000, 0x4015), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"flog10p", two(0xF000, 0x4C15), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"flog10s", two(0xF000, 0x4415), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"flog10w", two(0xF000, 0x5015), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"flog10x", two(0xF000, 0x0015), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"flog10x", two(0xF000, 0x4815), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"flog10x", two(0xF000, 0x0015), two(0xF1C0, 0xE07F), "IiFt"}, + +{"flog2b", two(0xF000, 0x5816), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"flog2d", two(0xF000, 0x5416), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"flog2l", two(0xF000, 0x4016), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"flog2p", two(0xF000, 0x4C16), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"flog2s", two(0xF000, 0x4416), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"flog2w", two(0xF000, 0x5016), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"flog2x", two(0xF000, 0x0016), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"flog2x", two(0xF000, 0x4816), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"flog2x", two(0xF000, 0x0016), two(0xF1C0, 0xE07F), "IiFt"}, + +{"flognb", two(0xF000, 0x5814), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"flognd", two(0xF000, 0x5414), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"flognl", two(0xF000, 0x4014), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"flognp", two(0xF000, 0x4C14), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"flogns", two(0xF000, 0x4414), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"flognw", two(0xF000, 0x5014), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"flognx", two(0xF000, 0x0014), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"flognx", two(0xF000, 0x4814), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"flognx", two(0xF000, 0x0014), two(0xF1C0, 0xE07F), "IiFt"}, + +{"flognp1b", two(0xF000, 0x5806), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"flognp1d", two(0xF000, 0x5406), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"flognp1l", two(0xF000, 0x4006), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"flognp1p", two(0xF000, 0x4C06), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"flognp1s", two(0xF000, 0x4406), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"flognp1w", two(0xF000, 0x5006), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"flognp1x", two(0xF000, 0x0006), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"flognp1x", two(0xF000, 0x4806), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"flognp1x", two(0xF000, 0x0006), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fmodb", two(0xF000, 0x5821), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fmodd", two(0xF000, 0x5421), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fmodl", two(0xF000, 0x4021), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fmodp", two(0xF000, 0x4C21), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fmods", two(0xF000, 0x4421), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fmodw", two(0xF000, 0x5021), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fmodx", two(0xF000, 0x0021), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fmodx", two(0xF000, 0x4821), two(0xF1C0, 0xFC7F), "Ii;xF7"}, + +{"fmoveb", two(0xF000, 0x5800), two(0xF1C0, 0xFC7F), "Ii;bF7"}, /* fmove from <ea> to fp<n> */ +{"fmoveb", two(0xF000, 0x7800), two(0xF1C0, 0xFC7F), "IiF7@b"}, /* fmove from fp<n> to <ea> */ +{"fmoved", two(0xF000, 0x5400), two(0xF1C0, 0xFC7F), "Ii;FF7"}, /* fmove from <ea> to fp<n> */ +{"fmoved", two(0xF000, 0x7400), two(0xF1C0, 0xFC7F), "IiF7@F"}, /* fmove from fp<n> to <ea> */ +{"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%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: */ +{"fmoves", two(0xF000, 0x4400), two(0xF1C0, 0xFC7F), "Ii;fF7"}, /* fmove from <ea> to fp<n> */ +{"fmoves", two(0xF000, 0x6400), two(0xF1C0, 0xFC7F), "IiF7@f"}, /* fmove from fp<n> to <ea> */ +{"fmovew", two(0xF000, 0x5000), two(0xF1C0, 0xFC7F), "Ii;wF7"}, /* fmove from <ea> to fp<n> */ +{"fmovew", two(0xF000, 0x7000), two(0xF1C0, 0xFC7F), "IiF7@w"}, /* fmove from fp<n> to <ea> */ +{"fmovex", two(0xF000, 0x0000), two(0xF1C0, 0xE07F), "IiF8F7"}, /* fmove from <ea> to fp<n> */ +{"fmovex", two(0xF000, 0x4800), two(0xF1C0, 0xFC7F), "Ii;xF7"}, /* fmove from <ea> to fp<n> */ +{"fmovex", two(0xF000, 0x6800), two(0xF1C0, 0xFC7F), "IiF7@x"}, /* fmove from fp<n> to <ea> */ + + /* fmove.l from/to system control registers: */ + +/* fmove.l and fmovem.l are the same instruction. fmovem.l makes sense in + more cases, so I've dumped fmove.l pro tem, but this is the wrong + way to solve the problem in the long run. Hmmm. */ +/* {"fmovel", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Iis8@s"}, */ +/* {"fmovel", two(0xF000, 0x8000), two(0xF1C0, 0xE3FF), "Ii@ss8"}, */ + +{"fmovecrx", two(0xF000, 0x5C00), two(0xF1FF, 0xFC00), "Ii#CF7"}, /* fmovecr.x #ccc, FPn */ +{"fmovecr", two(0xF000, 0x5C00), two(0xF1FF, 0xFC00), "Ii#CF7"}, + +{"fmovemx", two(0xF020, 0xE000), two(0xF1F8, 0xFF00), "Id#3-s"}, /* fmovem.x to autodecrement, static and dynamic */ +{"fmovemx", two(0xF020, 0xE800), two(0xF1F8, 0xFF8F), "IiDk-s"}, /* fmovem.x to autodecrement, static and dynamic */ + +{"fmovemx", two(0xF000, 0xF000), two(0xF1C0, 0xFF00), "Id#3&s"}, /* fmovem.x to control, static and dynamic: */ +{"fmovemx", two(0xF000, 0xF800), two(0xF1C0, 0xFF8F), "IiDk&s"}, /* fmovem.x to control, static and dynamic: */ + +{"fmovemx", two(0xF018, 0xD000), two(0xF1F8, 0xFF00), "Id#3+s"}, /* fmovem.x from autoincrement, static and dynamic: */ +{"fmovemx", two(0xF018, 0xD800), two(0xF1F8, 0xFF8F), "IiDk+s"}, /* fmovem.x from autoincrement, static and dynamic: */ + +{"fmovemx", two(0xF000, 0xD000), two(0xF1C0, 0xFF00), "Id#3&s"}, /* fmovem.x from control, static and dynamic: */ +{"fmovemx", two(0xF000, 0xD800), two(0xF1C0, 0xFF8F), "IiDk&s"}, /* fmovem.x from control, static and dynamic: */ + +/* fmoveml and fmovel are the same instruction. This may cause some + confusion in the assembler. */ + +{"fmoveml", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Ii#8%s"}, /* fmovem.l to/from system control register(s): */ +{"fmoveml", two(0xF000, 0x8000), two(0xF1C0, 0xE3FF), "Ii%s#8"}, /* fmovem.l to/from system control register(s): */ + +{"fmulb", two(0xF000, 0x5823), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fmuld", two(0xF000, 0x5423), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fmull", two(0xF000, 0x4023), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fmulp", two(0xF000, 0x4C23), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fmuls", two(0xF000, 0x4423), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fmulw", two(0xF000, 0x5023), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fmulx", two(0xF000, 0x0023), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fmulx", two(0xF000, 0x4823), two(0xF1C0, 0xFC7F), "Ii;xF7"}, + +{"fnegb", two(0xF000, 0x581A), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fnegd", two(0xF000, 0x541A), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fnegl", two(0xF000, 0x401A), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fnegp", two(0xF000, 0x4C1A), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fnegs", two(0xF000, 0x441A), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fnegw", two(0xF000, 0x501A), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fnegx", two(0xF000, 0x001A), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fnegx", two(0xF000, 0x481A), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fnegx", two(0xF000, 0x001A), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fremb", two(0xF000, 0x5825), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fremd", two(0xF000, 0x5425), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"freml", two(0xF000, 0x4025), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fremp", two(0xF000, 0x4C25), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"frems", two(0xF000, 0x4425), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fremw", two(0xF000, 0x5025), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fremx", two(0xF000, 0x0025), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fremx", two(0xF000, 0x4825), two(0xF1C0, 0xFC7F), "Ii;xF7"}, + +{"frestore", one(0xF140), one(0xF1C0), "Id&s"}, +{"frestore", one(0xF158), one(0xF1F8), "Id+s"}, +{"fsave", one(0xF100), one(0xF1C0), "Id&s"}, +{"fsave", one(0xF120), one(0xF1F8), "Id-s"}, + +{"fsincosb", two(0xF000, 0x5830), two(0xF1C0, 0xFC78), "Ii;bF7FC"}, +{"fsincosd", two(0xF000, 0x5430), two(0xF1C0, 0xFC78), "Ii;FF7FC"}, +{"fsincosl", two(0xF000, 0x4030), two(0xF1C0, 0xFC78), "Ii;lF7FC"}, +{"fsincosp", two(0xF000, 0x4C30), two(0xF1C0, 0xFC78), "Ii;pF7FC"}, +{"fsincoss", two(0xF000, 0x4430), two(0xF1C0, 0xFC78), "Ii;fF7FC"}, +{"fsincosw", two(0xF000, 0x5030), two(0xF1C0, 0xFC78), "Ii;wF7FC"}, +{"fsincosx", two(0xF000, 0x0030), two(0xF1C0, 0xE078), "IiF8F7FC"}, +{"fsincosx", two(0xF000, 0x4830), two(0xF1C0, 0xFC78), "Ii;xF7FC"}, + +{"fscaleb", two(0xF000, 0x5826), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fscaled", two(0xF000, 0x5426), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fscalel", two(0xF000, 0x4026), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fscalep", two(0xF000, 0x4C26), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fscales", two(0xF000, 0x4426), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fscalew", two(0xF000, 0x5026), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fscalex", two(0xF000, 0x0026), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fscalex", two(0xF000, 0x4826), two(0xF1C0, 0xFC7F), "Ii;xF7"}, + +{"fseq", two(0xF040, 0x0001), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsf", two(0xF040, 0x0000), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsge", two(0xF040, 0x0013), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsgl", two(0xF040, 0x0016), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsgle", two(0xF040, 0x0017), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsgt", two(0xF040, 0x0012), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsle", two(0xF040, 0x0015), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fslt", two(0xF040, 0x0014), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsne", two(0xF040, 0x000E), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsnge", two(0xF040, 0x001C), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsngl", two(0xF040, 0x0019), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsngle", two(0xF040, 0x0018), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsngt", two(0xF040, 0x001D), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsnle", two(0xF040, 0x001A), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsnlt", two(0xF040, 0x001B), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsoge", two(0xF040, 0x0003), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsogl", two(0xF040, 0x0006), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsogt", two(0xF040, 0x0002), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsole", two(0xF040, 0x0005), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsolt", two(0xF040, 0x0004), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsor", two(0xF040, 0x0007), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsseq", two(0xF040, 0x0011), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fssf", two(0xF040, 0x0010), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fssne", two(0xF040, 0x001E), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsst", two(0xF040, 0x001F), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fst", two(0xF040, 0x000F), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsueq", two(0xF040, 0x0009), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsuge", two(0xF040, 0x000B), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsugt", two(0xF040, 0x000A), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsule", two(0xF040, 0x000D), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsult", two(0xF040, 0x000C), two(0xF1C0, 0xFFFF), "Ii@s"}, +{"fsun", two(0xF040, 0x0008), two(0xF1C0, 0xFFFF), "Ii@s"}, + +{"fsgldivb", two(0xF000, 0x5824), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fsgldivd", two(0xF000, 0x5424), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fsgldivl", two(0xF000, 0x4024), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fsgldivp", two(0xF000, 0x4C24), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fsgldivs", two(0xF000, 0x4424), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fsgldivw", two(0xF000, 0x5024), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fsgldivx", two(0xF000, 0x0024), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fsgldivx", two(0xF000, 0x4824), two(0xF1C0, 0xFC7F), "Ii;xF7"}, + +{"fsglmulb", two(0xF000, 0x5827), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fsglmuld", two(0xF000, 0x5427), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fsglmull", two(0xF000, 0x4027), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fsglmulp", two(0xF000, 0x4C27), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fsglmuls", two(0xF000, 0x4427), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fsglmulw", two(0xF000, 0x5027), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fsglmulx", two(0xF000, 0x0027), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fsglmulx", two(0xF000, 0x4827), two(0xF1C0, 0xFC7F), "Ii;xF7"}, + +{"fsinb", two(0xF000, 0x580E), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fsind", two(0xF000, 0x540E), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fsinl", two(0xF000, 0x400E), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fsinp", two(0xF000, 0x4C0E), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fsins", two(0xF000, 0x440E), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fsinw", two(0xF000, 0x500E), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fsinx", two(0xF000, 0x000E), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fsinx", two(0xF000, 0x480E), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fsinx", two(0xF000, 0x000E), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fsinhb", two(0xF000, 0x5802), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fsinhd", two(0xF000, 0x5402), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fsinhl", two(0xF000, 0x4002), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fsinhp", two(0xF000, 0x4C02), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fsinhs", two(0xF000, 0x4402), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fsinhw", two(0xF000, 0x5002), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fsinhx", two(0xF000, 0x0002), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fsinhx", two(0xF000, 0x4802), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fsinhx", two(0xF000, 0x0002), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fsqrtb", two(0xF000, 0x5804), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fsqrtd", two(0xF000, 0x5404), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fsqrtl", two(0xF000, 0x4004), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fsqrtp", two(0xF000, 0x4C04), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fsqrts", two(0xF000, 0x4404), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fsqrtw", two(0xF000, 0x5004), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fsqrtx", two(0xF000, 0x0004), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fsqrtx", two(0xF000, 0x4804), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"fsqrtx", two(0xF000, 0x0004), two(0xF1C0, 0xE07F), "IiFt"}, + +{"fsubb", two(0xF000, 0x5828), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"fsubd", two(0xF000, 0x5428), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"fsubl", two(0xF000, 0x4028), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"fsubp", two(0xF000, 0x4C28), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"fsubs", two(0xF000, 0x4428), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"fsubw", two(0xF000, 0x5028), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"fsubx", two(0xF000, 0x0028), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"fsubx", two(0xF000, 0x4828), two(0xF1C0, 0xFC7F), "Ii;xF7"}, + +{"ftanb", two(0xF000, 0x580F), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"ftand", two(0xF000, 0x540F), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"ftanl", two(0xF000, 0x400F), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"ftanp", two(0xF000, 0x4C0F), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"ftans", two(0xF000, 0x440F), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"ftanw", two(0xF000, 0x500F), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"ftanx", two(0xF000, 0x000F), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"ftanx", two(0xF000, 0x480F), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"ftanx", two(0xF000, 0x000F), two(0xF1C0, 0xE07F), "IiFt"}, + +{"ftanhb", two(0xF000, 0x5809), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"ftanhd", two(0xF000, 0x5409), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"ftanhl", two(0xF000, 0x4009), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"ftanhp", two(0xF000, 0x4C09), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"ftanhs", two(0xF000, 0x4409), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"ftanhw", two(0xF000, 0x5009), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"ftanhx", two(0xF000, 0x0009), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"ftanhx", two(0xF000, 0x4809), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"ftanhx", two(0xF000, 0x0009), two(0xF1C0, 0xE07F), "IiFt"}, + +{"ftentoxb", two(0xF000, 0x5812), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"ftentoxd", two(0xF000, 0x5412), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"ftentoxl", two(0xF000, 0x4012), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"ftentoxp", two(0xF000, 0x4C12), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"ftentoxs", two(0xF000, 0x4412), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"ftentoxw", two(0xF000, 0x5012), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"ftentoxx", two(0xF000, 0x0012), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"ftentoxx", two(0xF000, 0x4812), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"ftentoxx", two(0xF000, 0x0012), two(0xF1C0, 0xE07F), "IiFt"}, + +{"ftrapeq", two(0xF07C, 0x0001), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapf", two(0xF07C, 0x0000), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapge", two(0xF07C, 0x0013), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapgl", two(0xF07C, 0x0016), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapgle", two(0xF07C, 0x0017), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapgt", two(0xF07C, 0x0012), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftraple", two(0xF07C, 0x0015), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftraplt", two(0xF07C, 0x0014), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapne", two(0xF07C, 0x000E), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapnge", two(0xF07C, 0x001C), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapngl", two(0xF07C, 0x0019), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapngle", two(0xF07C, 0x0018), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapngt", two(0xF07C, 0x001D), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapnle", two(0xF07C, 0x001A), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapnlt", two(0xF07C, 0x001B), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapoge", two(0xF07C, 0x0003), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapogl", two(0xF07C, 0x0006), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapogt", two(0xF07C, 0x0002), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapole", two(0xF07C, 0x0005), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapolt", two(0xF07C, 0x0004), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapor", two(0xF07C, 0x0007), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapseq", two(0xF07C, 0x0011), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapsf", two(0xF07C, 0x0010), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapsne", two(0xF07C, 0x001E), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapst", two(0xF07C, 0x001F), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapt", two(0xF07C, 0x000F), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapueq", two(0xF07C, 0x0009), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapuge", two(0xF07C, 0x000B), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapugt", two(0xF07C, 0x000A), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapule", two(0xF07C, 0x000D), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapult", two(0xF07C, 0x000C), two(0xF1FF, 0xFFFF), "Ii"}, +{"ftrapun", two(0xF07C, 0x0008), two(0xF1FF, 0xFFFF), "Ii"}, + +{"ftrapeqw", two(0xF07A, 0x0001), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapfw", two(0xF07A, 0x0000), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapgew", two(0xF07A, 0x0013), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapglw", two(0xF07A, 0x0016), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapglew", two(0xF07A, 0x0017), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapgtw", two(0xF07A, 0x0012), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftraplew", two(0xF07A, 0x0015), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapltw", two(0xF07A, 0x0014), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapnew", two(0xF07A, 0x000E), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapngew", two(0xF07A, 0x001C), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapnglw", two(0xF07A, 0x0019), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapnglew", two(0xF07A, 0x0018), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapngtw", two(0xF07A, 0x001D), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapnlew", two(0xF07A, 0x001A), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapnltw", two(0xF07A, 0x001B), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapogew", two(0xF07A, 0x0003), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapoglw", two(0xF07A, 0x0006), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapogtw", two(0xF07A, 0x0002), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapolew", two(0xF07A, 0x0005), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapoltw", two(0xF07A, 0x0004), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftraporw", two(0xF07A, 0x0007), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapseqw", two(0xF07A, 0x0011), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapsfw", two(0xF07A, 0x0010), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapsnew", two(0xF07A, 0x001E), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapstw", two(0xF07A, 0x001F), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftraptw", two(0xF07A, 0x000F), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapueqw", two(0xF07A, 0x0009), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapugew", two(0xF07A, 0x000B), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapugtw", two(0xF07A, 0x000A), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapulew", two(0xF07A, 0x000D), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapultw", two(0xF07A, 0x000C), two(0xF1FF, 0xFFFF), "Ii^w"}, +{"ftrapunw", two(0xF07A, 0x0008), two(0xF1FF, 0xFFFF), "Ii^w"}, + +{"ftrapeql", two(0xF07B, 0x0001), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapfl", two(0xF07B, 0x0000), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapgel", two(0xF07B, 0x0013), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapgll", two(0xF07B, 0x0016), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapglel", two(0xF07B, 0x0017), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapgtl", two(0xF07B, 0x0012), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftraplel", two(0xF07B, 0x0015), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapltl", two(0xF07B, 0x0014), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapnel", two(0xF07B, 0x000E), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapngel", two(0xF07B, 0x001C), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapngll", two(0xF07B, 0x0019), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapnglel", two(0xF07B, 0x0018), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapngtl", two(0xF07B, 0x001D), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapnlel", two(0xF07B, 0x001A), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapnltl", two(0xF07B, 0x001B), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapogel", two(0xF07B, 0x0003), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapogll", two(0xF07B, 0x0006), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapogtl", two(0xF07B, 0x0002), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapolel", two(0xF07B, 0x0005), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapoltl", two(0xF07B, 0x0004), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftraporl", two(0xF07B, 0x0007), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapseql", two(0xF07B, 0x0011), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapsfl", two(0xF07B, 0x0010), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapsnel", two(0xF07B, 0x001E), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapstl", two(0xF07B, 0x001F), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftraptl", two(0xF07B, 0x000F), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapueql", two(0xF07B, 0x0009), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapugel", two(0xF07B, 0x000B), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapugtl", two(0xF07B, 0x000A), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapulel", two(0xF07B, 0x000D), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapultl", two(0xF07B, 0x000C), two(0xF1FF, 0xFFFF), "Ii^l"}, +{"ftrapunl", two(0xF07B, 0x0008), two(0xF1FF, 0xFFFF), "Ii^l"}, + +{"ftstb", two(0xF000, 0x583A), two(0xF1C0, 0xFC7F), "Ii;b"}, +{"ftstd", two(0xF000, 0x543A), two(0xF1C0, 0xFC7F), "Ii;F"}, +{"ftstl", two(0xF000, 0x403A), two(0xF1C0, 0xFC7F), "Ii;l"}, +{"ftstp", two(0xF000, 0x4C3A), two(0xF1C0, 0xFC7F), "Ii;p"}, +{"ftsts", two(0xF000, 0x443A), two(0xF1C0, 0xFC7F), "Ii;f"}, +{"ftstw", two(0xF000, 0x503A), two(0xF1C0, 0xFC7F), "Ii;w"}, +{"ftstx", two(0xF000, 0x003A), two(0xF1C0, 0xE07F), "IiF8"}, +{"ftstx", two(0xF000, 0x483A), two(0xF1C0, 0xFC7F), "Ii;x"}, + +{"ftwotoxb", two(0xF000, 0x5811), two(0xF1C0, 0xFC7F), "Ii;bF7"}, +{"ftwotoxd", two(0xF000, 0x5411), two(0xF1C0, 0xFC7F), "Ii;FF7"}, +{"ftwotoxl", two(0xF000, 0x4011), two(0xF1C0, 0xFC7F), "Ii;lF7"}, +{"ftwotoxp", two(0xF000, 0x4C11), two(0xF1C0, 0xFC7F), "Ii;pF7"}, +{"ftwotoxs", two(0xF000, 0x4411), two(0xF1C0, 0xFC7F), "Ii;fF7"}, +{"ftwotoxw", two(0xF000, 0x5011), two(0xF1C0, 0xFC7F), "Ii;wF7"}, +{"ftwotoxx", two(0xF000, 0x0011), two(0xF1C0, 0xE07F), "IiF8F7"}, +{"ftwotoxx", two(0xF000, 0x4811), two(0xF1C0, 0xFC7F), "Ii;xF7"}, +{"ftwotoxx", two(0xF000, 0x0011), two(0xF1C0, 0xE07F), "IiFt"}, + +/* Alternate mnemonics for SUN */ + +{"jbsr", one(0060400), one(0177400), "Bg"}, +{"jbsr", one(0047200), one(0177700), "!s"}, +{"jra", one(0060000), one(0177400), "Bg"}, +{"jra", one(0047300), one(0177700), "!s"}, + +{"jhi", one(0061000), one(0177400), "Bg"}, +{"jls", one(0061400), one(0177400), "Bg"}, +{"jcc", one(0062000), one(0177400), "Bg"}, +{"jcs", one(0062400), one(0177400), "Bg"}, +{"jne", one(0063000), one(0177400), "Bg"}, +{"jeq", one(0063400), one(0177400), "Bg"}, +{"jvc", one(0064000), one(0177400), "Bg"}, +{"jvs", one(0064400), one(0177400), "Bg"}, +{"jpl", one(0065000), one(0177400), "Bg"}, +{"jmi", one(0065400), one(0177400), "Bg"}, +{"jge", one(0066000), one(0177400), "Bg"}, +{"jlt", one(0066400), one(0177400), "Bg"}, +{"jgt", one(0067000), one(0177400), "Bg"}, +{"jle", one(0067400), one(0177400), "Bg"}, + +{"movql", one(0070000), one(0170400), "MsDd"}, +{"moveql", one(0070000), one(0170400), "MsDd"}, +{"moval", one(0020100), one(0170700), "*lAd"}, +{"movaw", one(0030100), one(0170700), "*wAd"}, +{"movb", one(0010000), one(0170000), ";b$d"}, /* mov */ +{"movl", one(0020000), one(0170000), "*l$d"}, +{"movl", one(0020100), one(0170700), "*lAd"}, +{"movl", one(0047140), one(0177770), "AsUd"}, /* mov to USP */ +{"movl", one(0047150), one(0177770), "UdAs"}, /* mov from USP */ +{"movl", one(0070000), one(0170400), "MsDd"}, /* movq written as mov */ +{"movml", one(0044300), one(0177700), "#w&s"}, /* movm reg to mem. */ +{"movml", one(0044340), one(0177770), "#w-s"}, /* movm reg to autodecrement. */ +{"movml", one(0046300), one(0177700), "!s#w"}, /* movm mem to reg. */ +{"movml", one(0046330), one(0177770), "+s#w"}, /* movm autoinc to reg. */ +{"movmw", one(0044200), one(0177700), "#w&s"}, /* movm reg to mem. */ +{"movmw", one(0044240), one(0177770), "#w-s"}, /* movm reg to autodecrement. */ +{"movmw", one(0046200), one(0177700), "!s#w"}, /* movm mem to reg. */ +{"movmw", one(0046230), one(0177770), "+s#w"}, /* movm autoinc to reg. */ +{"movpl", one(0000510), one(0170770), "dsDd"}, /* memory to register */ +{"movpl", one(0000710), one(0170770), "Ddds"}, /* register to memory */ +{"movpw", one(0000410), one(0170770), "dsDd"}, /* memory to register */ +{"movpw", one(0000610), one(0170770), "Ddds"}, /* register to memory */ +{"movq", one(0070000), one(0170400), "MsDd"}, +{"movw", one(0030000), one(0170000), "*w$d"}, +{"movw", one(0030100), one(0170700), "*wAd"}, /* mova, written as mov */ +{"movw", one(0040300), one(0177700), "Ss$s"}, /* Move from sr */ +{"movw", one(0041300), one(0177700), "Cs$s"}, /* Move from ccr */ +{"movw", one(0042300), one(0177700), ";wCd"}, /* mov to ccr */ +{"movw", one(0043300), one(0177700), ";wSd"}, /* mov to sr */ +/* movc not done*/ + +{"movsb", two(0007000, 0), two(0177700, 07777), "~sR1"}, +{"movsb", two(0007000, 04000), two(0177700, 07777), "R1~s"}, +{"movsl", two(0007200, 0), two(0177700, 07777), "~sR1"}, +{"movsl", two(0007200, 04000), two(0177700, 07777), "R1~s"}, +{"movsw", two(0007100, 0), two(0177700, 07777), "~sR1"}, +{"movsw", two(0007100, 04000), two(0177700, 07777), "R1~s"}, +}; + +int numopcodes=sizeof(m68k_opcodes)/sizeof(m68k_opcodes[0]); + +struct m68k_opcode *endop = m68k_opcodes+sizeof(m68k_opcodes)/sizeof(m68k_opcodes[0]);; diff --git a/gdb/param.h b/gdb/param.h index 426593f..83ebf45 100644 --- a/gdb/param.h +++ b/gdb/param.h @@ -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"); } diff --git a/gdb/parent.c b/gdb/parent.c deleted file mode 100644 index 38b845a..0000000 --- a/gdb/parent.c +++ /dev/null @@ -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; -} diff --git a/gdb/pinsn.c b/gdb/pinsn.c index 0b6414e..94ac7f7 100644 --- a/gdb/pinsn.c +++ b/gdb/pinsn.c @@ -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 */ +} diff --git a/gdb/pn-opcode.h b/gdb/pn-opcode.h new file mode 100644 index 0000000..cdd6280 --- /dev/null +++ b/gdb/pn-opcode.h @@ -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]); diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 04dda07..3fb12e4 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -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, diff --git a/gdb/remote.c b/gdb/remote.c index 23f27df..27a7322 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -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. */ diff --git a/gdb/source.c b/gdb/source.c index e1d1b42..bfce8f9 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -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); - - if (sals.nelts == 0) - return; /* C++ */ - if (sals.nelts != 1) - error ("unreasonable line info request"); - - sal = sals.sals[0]; - free (sals.sals); + sal = decode_line_spec (arg, 0); + /* 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; } diff --git a/gdb/stack.c b/gdb/stack.c index fce015b..6c3443c 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -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); diff --git a/gdb/standalone.c b/gdb/standalone.c index 94adf64..45cca6a 100644 --- a/gdb/standalone.c +++ b/gdb/standalone.c @@ -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"; diff --git a/gdb/symmisc.c b/gdb/symmisc.c index 5dcb886..cb631cb 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -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++; diff --git a/gdb/symseg.h b/gdb/symseg.h index 7b16f8f..e233f17 100644 --- a/gdb/symseg.h +++ b/gdb/symseg.h @@ -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 diff --git a/gdb/symtab.c b/gdb/symtab.c index ec6f0d6..5c08d88 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -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. */ @@ -407,62 +282,6 @@ static struct symbol *lookup_block_symbol (); 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; register struct block *block; @@ -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."); diff --git a/gdb/symtab.h b/gdb/symtab.h index d888dc1..deab276 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -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 (); diff --git a/gdb/test2.c b/gdb/test2.c new file mode 100644 index 0000000..e6964f0 --- /dev/null +++ b/gdb/test2.c @@ -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)); +} diff --git a/gdb/testbit.c b/gdb/testbit.c deleted file mode 100644 index 9359f0b..0000000 --- a/gdb/testbit.c +++ /dev/null @@ -1,12 +0,0 @@ -struct foo -{ - unsigned bar : 1; - unsigned lose : 1; -}; - -main () -{ - struct foo *win; - - printf ("%d, %d\n", win->bar, win->lose); -} diff --git a/gdb/testbpt.c b/gdb/testbpt.c new file mode 100644 index 0000000..baa4e51 --- /dev/null +++ b/gdb/testbpt.c @@ -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 () +{ +} diff --git a/gdb/testkill.c b/gdb/testkill.c deleted file mode 100644 index 0e43c1f..0000000 --- a/gdb/testkill.c +++ /dev/null @@ -1,5 +0,0 @@ - - main() - { - printf("foo\n"); - } diff --git a/gdb/utils.c b/gdb/utils.c index c8f5c06..2a0b943 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -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); } diff --git a/gdb/valarith.c b/gdb/valarith.c index d62815d..03bc1e1 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -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."); } diff --git a/gdb/valops.c b/gdb/valops.c index 76466b6..9f0e3cc 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -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)) - { - 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"); - } - } - - /* 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 (!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--) { - 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! */ + if (!strcmp (TYPE_FIELD_NAME (t, i), name)) + break; } - /* 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; -} + if (i < 0) + error ("Structure has no component named %s.", name); -/* 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 diff --git a/gdb/valprint.c b/gdb/valprint.c index 29df920..8087ef8 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -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 ??? */; - } - 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); + /* Print the field width. */ - 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"); - } + if (TYPE_FIELD_PACKED (type, i)) + fprintf (stream, " : %d", TYPE_FIELD_BITSIZE (type, i)); + fprintf (stream, ";\n"); + } print_spaces (level, stream); fputc ('}', stream); } diff --git a/gdb/value.h b/gdb/value.h index 985e01e..e67f17e 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -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 (); diff --git a/gdb/values.c b/gdb/values.c index 8fa5af9..b9c55df 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -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; diff --git a/gdb/vax-pinsn.c b/gdb/vax-pinsn.c index 9d97415..471f92e 100644 --- a/gdb/vax-pinsn.c +++ b/gdb/vax-pinsn.c @@ -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 diff --git a/gdb/version.c b/gdb/version.c index 033b5d8..b681739 100644 --- a/gdb/version.c +++ b/gdb/version.c @@ -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"; @@ -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 @@ -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]; - - if (! new) - { - int new_top; - - /* 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; - } - - /* 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)); - } + /* Find out where the display is positioned (in case user scrolled it). */ + + if (! must_scroll) + { + int top_line_number; + + 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; + } - /* Set the text display cursor position within the text. */ + /* If appropriate, scroll the text display. */ - XtSetArg (textArgs[0], XtNinsertPosition, - source_line_charpos (source_window_symtab, sal.line)); - XtSetValues (source_text_widget, textArgs, XtNumber (textArgs)); - } + if (must_scroll) + { + int top_line_number = (sal.line > height/3) ? sal.line - height/3 : 1; + + 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. */ - -static void -next_button () -{ - execute_command ("next", 0); - xgdb_display_source (); - print_prompt (); -} - -static void -step_button () -{ - execute_command ("step", 0); - xgdb_display_source (); - print_prompt (); -} - -static void -cont_button () -{ - execute_command ("cont", 0); - xgdb_display_source (); - print_prompt (); -} +/* Handle a button by running the command COMMAND. */ static void -finish_button () +do_command (w, command, call_data) + Widget w; + char *command; + caddr_t call_data; { - execute_command ("finish", 0); + execute_command (command, 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 () +redisplay_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]; - - XtSetArg (commandArgs[0], XtNlabel, name); - XtSetArg (commandArgs[1], XtNfunction, function); - XtCreateWidget (name, commandWidgetClass, parent, - commandArgs, XtNumber (commandArgs)); + static XtCallbackRec Callback[] = + { + {NULL, (caddr_t)NULL}, + {NULL, (caddr_t)NULL}, + }; + static Arg commandArgs[] = + { + {XtNlabel, (XtArgVal)NULL}, + {XtNcallback, (XtArgVal)Callback}, + }; + + 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, "break in", explicit_breakpoint_button, NULL); + addbutton (parent, "break at", breakpoint_button, 0); + addbutton (parent, "go until", breakpoint_button, 1); - addbutton (parent, "Print", print_button); - addbutton (parent, "Print*", print_star_button); + addbutton (parent, "print", print_button, 0); + addbutton (parent, "print*", print_button, 1); - addbutton (parent, "Next", next_button); - addbutton (parent, "Step", step_button); - addbutton (parent, "Cont", cont_button); - addbutton (parent, "Finish", finish_button); + 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}, - }; - - XrmResourceDataBase db; - FILE *rdb_file; - XGCValues dummy; + int width, height; + int sheight; + Arg argl[3]; - /* 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); - { - char *dummy1[1]; - dummy1[0] = 0; - XtInitialize ("gdb", "gdb", 0, 0, 0, dummy1); - } + /* 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)); - /* should be checking .Xdefaults in $HOME */ - rdb_file = fopen (".Xresources", "r"); - if (rdb_file != NULL) + /* If none specified, set a default size. */ + + if (!width || !height) { - XrmGetDataBase (rdb_file, &db); - XrmSetCurrentDataBase (db); - fclose (rdb_file); + 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 the containing_widget. */ + /* Create title */ + { + char buf[200]; + extern char *version; + sprintf (buf, "GDB %s", version); + title_widget = + create_label ("Title", buf); + } - containing_widget = XtCreateWidget ("frame", vPaneWidgetClass, 0, - frameArgs, XtNumber (frameArgs)); - - default_gc = XCreateGC (screen_display, containing_widget, 0, dummy); + /* Create exec file name window and add */ + exec_name_widget = + create_label ("Executable", "No executable specified"); + + /* 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; - - 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 + XDefineCursor (screen_display, XtWindow (main_widget), + XCreateFontCursor (screen_display, XC_circle)); +#endif - 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 + |