diff options
author | svn2git <svn2git@FreeBSD.org> | 1994-05-01 00:00:00 -0800 |
---|---|---|
committer | svn2git <svn2git@FreeBSD.org> | 1994-05-01 00:00:00 -0800 |
commit | a16f65c7d117419bd266c28a1901ef129a337569 (patch) | |
tree | 2626602f66dc3551e7a7c7bc9ad763c3bc7ab40a /gnu/usr.bin/gdb | |
parent | 8503f4f13f77abf7adc8f7e329c6f9c1d52b6a20 (diff) | |
download | src-a16f65c7d117419bd266c28a1901ef129a337569.tar.gz src-a16f65c7d117419bd266c28a1901ef129a337569.zip |
Release FreeBSD 1.1release/1.1.0_cvs
This commit was manufactured to restore the state of the 1.1-RELEASE image.
Releases prior to 5.3-RELEASE are omitting the secure/ and crypto/ subdirs.
Diffstat (limited to 'gnu/usr.bin/gdb')
82 files changed, 60735 insertions, 0 deletions
diff --git a/gnu/usr.bin/gdb/COPYING b/gnu/usr.bin/gdb/COPYING new file mode 100644 index 000000000000..9a1703758111 --- /dev/null +++ b/gnu/usr.bin/gdb/COPYING @@ -0,0 +1,249 @@ + + GNU GENERAL PUBLIC LICENSE + Version 1, February 1989 + + Copyright (C) 1989 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The license agreements of most software companies try to keep users +at the mercy of those companies. By contrast, our General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. The +General Public License applies to the Free Software Foundation's +software and to any other program whose authors commit to using it. +You can use it for your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Specifically, the General Public License is designed to make +sure that you have the freedom to give away or sell copies of free +software, that you receive source code or can get it if you want it, +that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of a such a program, whether +gratis or for a fee, 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +"Program", below, refers to any such program or work, and a "work based +on the Program" means either the Program or any work containing the +Program or a portion of it, either verbatim or with modifications. Each +licensee is addressed as "you". + + 1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this +General Public License and to the absence of any warranty; and give any +other recipients of the Program a copy of this General Public License +along with the Program. You may charge a fee for the physical act of +transferring a copy. + + 2. You may modify your copy or copies of the Program 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 the Program or any part thereof, either + with or without modifications, to be licensed at no charge to all + third parties under the terms of this General Public License (except + that you may choose to grant warranty protection to some or all + third parties, at your option). + + c) If the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the simplest and most usual way, to print or display an + announcement including an appropriate copyright notice and a notice + 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 General + Public License. + + d) You may charge a 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 independent work with the Program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other work under the scope of these terms. + + 3. You may copy and distribute the 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 charge + for the cost of distribution) 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.) + +Source code for a work means the preferred form of the work for making +modifications to it. 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, or for standard header files or definitions files that +accompany that operating system. + + 4. You may not copy, modify, sublicense, distribute or transfer the +Program except as expressly provided under this General Public License. +Any attempt otherwise to copy, modify, sublicense, distribute or transfer +the Program is void, and will automatically terminate your rights to use +the Program under this License. However, parties who have received +copies, or rights to use copies, from you under this General Public +License will not have their licenses terminated so long as such parties +remain in full compliance. + + 5. By copying, distributing or modifying the Program (or any work based +on the Program) you indicate your acceptance of this license to do so, +and all its terms and conditions. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the original +licensor to copy, distribute or modify the Program subject to these +terms and conditions. You may not impose any further restrictions on the +recipients' exercise of the rights granted herein. + + 7. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of the license which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +the license, you may choose any version ever published by the Free Software +Foundation. + + 8. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision 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 generally. + + NO WARRANTY + + 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE 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. + + 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to humanity, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19xx name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items--whatever suits your +program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program `Gnomovision' (a program to direct compilers to make passes + at assemblers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/gnu/usr.bin/gdb/ChangeLog b/gnu/usr.bin/gdb/ChangeLog new file mode 100644 index 000000000000..1f2342b797a7 --- /dev/null +++ b/gnu/usr.bin/gdb/ChangeLog @@ -0,0 +1,4887 @@ +Thu Feb 8 01:11:55 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu) + + * GDB 3.5 released. + + * version.c: Change version number to 3.5 + +Tue Feb 6 15:58:06 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu) + + * m-hp9k320.h: define ATTACH_DETACH. + hp9k320-dep.c [ATTACH_DETACH]: New code. + +Thu Feb 1 17:43:00 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu) + + * valprint.c (is_nan, val_print): Use char * not void *. + + * symmisc.c (print_symbol): Print newline after label. + +Tue Jan 30 15:35:52 1990 Jim Kingdon (kingdon at albert.ai.mit.edu) + + * Makefile.dist (READLINE): Add {readline,history}.texinfo. + + * m-merlin.h: Put in clarifying comments about SHELL_FILE. + config.gdb (merlin): Explain about /usr/local/lib/gdb-sh. + +Sat Jan 27 02:30:27 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu) + + * version.c: Change version number to 3.5alpha.1. + + * dbxread.c (process_one_symbol): Compare context_stack_depth + with !VARIABLES_INSIDE_BLOCK, not VARIABLES_INSIDE_BLOCK. + +Fri Jan 26 01:21:51 1990 Jim Kingdon (kingdon at mole.ai.mit.edu) + + * main.c [ALIGN_STACK_ON_STARTUP]: New code. + m-i386.h: Define ALIGN_STACK_ON_STARTUP. + + * m-merlin.h (NO_SIGINTERRUPT, SHELL_FILE): Define. + + * umax-dep.c (exec_file_command): Add commas to call to + read_section_hdr. + +Tue Jan 23 15:49:47 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu) + + * dbxread.c (define_symbol): Deal with deftype 'X'. + + * convex-dep.c (wait): Make it pid_t. + + * convex-dep.c (comm_registers_info): accept decimal comm register + specification, as "i comm 32768". + + * dbxread.c (process_one_symbol): Make VARIABLES_INSIDE_BLOCK + macro say by itself where variables are. Pass it desc. + m-convex.h (VARIABLES_INSIDE_BLOCK): Nonzero for native compiler. + + * m-convex.h (SET_STACK_LIMIT_HUGE): Define. + (IGNORE_SYMBOL): Take out #ifdef N_MONPT and put in 0xc4. + +Fri Jan 19 20:04:15 1990 Jim Kingdon (kingdon at albert.ai.mit.edu) + + * printcmd.c (print_frame_args): Always set highest_offset to + current_offset when former is -1. + + * dbxread.c (read_struct_type): Print nice error message + when encountering multiple inheritance. + +Thu Jan 18 13:43:30 1990 Jim Kingdon (kingdon at mole.ai.mit.edu) + + * dbxread.c (read_dbx_symtab): Always treat N_FN as a potential + source for a x.o or -lx symbol, ignoring OFILE_FN_FLAGGED. + + * printcmd.c (print_frame_args): Cast -1 to (CORE_ADDR). + + * hp300bsd-dep.c (_initialize_hp300_dep): Get kernel_u_addr. + m-hp300bsd.h (KERNEL_U_ADDR): Use kernel_u_addr. + + * infcmd.c (run_command): #if 0 out call to + breakpoint_clear_ignore_counts. + +Thu Jan 11 12:58:12 1990 Jim Kingdon (kingdon at mole) + + * printcmd.c (print_frame_args) [STRUCT_ARG_SYM_GARBAGE]: + Try looking up name of var before giving up & printing '?'. + +Wed Jan 10 14:00:14 1990 Jim Kingdon (kingdon at pogo) + + * many files: Move stdio.h before param.h. + + * sun3-dep.c (store_inferior_registers): Only try to write FP + regs #ifdef FP0_REGNUM. + +Mon Jan 8 17:56:15 1990 Jim Kingdon (kingdon at pogo) + + * symtab.c: #if 0 out "info methods" code. + +Sat Jan 6 12:33:04 1990 Jim Kingdon (kingdon at pogo) + + * dbxread.c (read_struct_type): Set TYPE_NFN_FIELDS_TOTAL + from all baseclasses; remove vestigial variable baseclass. + + * findvar.c (read_var_value): Check REG_STRUCT_HAS_ADDR. + printcmd.c (print_frame_args): Check STRUCT_ARG_SYM_GARBAGE. + m-sparc.h: Define REG_STRUCT_HAS_ADDR and STRUCT_ARG_SYM_GARBAGE. + + * blockframe.c (get_frame_block): Subtract one from pc if not + innermost frame. + +Fri Dec 29 15:26:33 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * printcmd.c (print_frame_args): check highest_offset != -1, not i. + +Thu Dec 28 16:21:02 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * valops.c (value_struct_elt): Clean up error msg. + + * breakpoint.c (describe_other_breakpoints): + Delete extra space before "also set at" and add period at end. + +Tue Dec 19 10:28:42 1989 Jim Kingdon (kingdon at pogo) + + * source.c (print_source_lines): Tell user which line number + was out of range when printing error message. + +Sun Dec 17 14:14:09 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * blockframe.c (find_pc_partial_function): Use + BLOCK_START (SYMBOL_BLOCK_VALUE (f)) instead of + SYMBOL_VALUE (f) to get start of function. + + * dbxread.c: Make xxmalloc just a #define for xmalloc. + +Thu Dec 14 16:13:16 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * m68k-opcode.h (fseq & following fp instructions): + Change @ to $. + +Fri Dec 8 19:06:44 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * breakpoint.c (breakpoint_clear_ignore_counts): New function. + infcmd.c (run_command): Call it. + +Wed Dec 6 15:03:38 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * valprint.c: Change it so "array-max 0" means there is + no limit. + + * expread.y (yylex): Change error message "invalid token in + expression" to "invalid character '%c' in expression". + +Mon Dec 4 16:12:54 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * blockframe.c (find_pc_partial_function): Always return 1 + for success, 0 for failure, and set *NAME and *ADDRESS to + match the return value. + + * dbxread.c (symbol_file_command): Use perror_with_name on + error from stat. + (psymtab_to_symtab, add_file_command), + core.c (validate_files), source.c (find_source_lines), + default-dep.c (exec_file_command): Check for errors from stat, + fstat, and myread. + +Fri Dec 1 05:16:42 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * valops.c (check_field): When following pointers, just get + their types; don't call value_ind. + +Thu Nov 30 14:45:29 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * config.gdb (pyr): New machine. + core.c [REG_STACK_SEGMENT]: New code. + dbxread.c (process_one_symbol): Cast return from copy_pending + to long before casting to enum namespace. + infrun.c: Split registers_info into DO_REGISTERS_INFO + and registers_info. + m-pyr.h, pyr-{dep.c,opcode.h,pinsn.c}: New files. + + * hp300bsd-dep.c: Stay in sync with default-dep.c. + + * m-hp300bsd.h (IN_SIGTRAMP): Define. + +Mon Nov 27 23:48:21 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * m-sparc.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): + Return floating point values in %f0. + +Tue Nov 21 00:34:46 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * dbxread.c (read_type): #if 0 out code which skips to + comma following x-ref. + +Sat Nov 18 20:10:54 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * valprint.c (val_print): Undo changes of Nov 11 & 16. + (print_string): Add parameter force_ellipses. + (val_print): Pass force_ellipses true when we stop fetching string + before we get to the end, else pass false. + +Thu Nov 16 11:59:50 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * infrun.c (restore_inferior_status): Don't try to restore + selected frame if the inferior no longer exists. + + * valprint.c (val_print): Rewrite string printing code not to + call print_string. + + * Makefile.dist (clean): Remove xgdb and xgdb.o. + +Tue Nov 14 12:41:47 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * Makefile.dist (XGDB, bindir, xbindir, install, all): New stuff. + +Sat Nov 11 15:29:38 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * valprint.c (val_print): chars_to_get: New variable. + +Thu Nov 9 12:31:47 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * main.c (main): Process "-help" as a switch that doesn't + take an argument. + +Wed Nov 8 13:07:02 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * Makefile.dist (gdb.tar.Z): Add "else true". + +Tue Nov 7 12:25:14 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * infrun.c (restore_inferior_status): Don't dereference fid if NULL. + + * config.gdb (sun3, sun4): Accept "sun3" and "sun4". + +Mon Nov 6 09:49:23 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * Makefile.dist (Makefile): Move comments after commands. + + * *-dep.c [READ_COFF_SYMTAB]: Pass optional header size to + read_section_hdr(). + + * inflow.c: Include <fcntl.h> regardless of USG. + + * coffread.c (read_section_hdr): Add optional_header_size. + (symbol_file_command): Pass optional header size to + read_section_hdr(). + (read_coff_symtab): Initialize filestring. + + * version.c: Change version to 3.4.xxx. + + * GDB 3.4 released. + +Sun Nov 5 11:39:01 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * version.c: Change version to 3.4. + + * symtab.c (decode_line_1): Only skip past "struct" if it + is there. + + * valops.c (value_ind), eval.c (evaluate_subexp, case UNOP_IND): + Have "*" <int-valued-exp> return an int, not a LONGEST. + + * utils.c (fprintf_filtered): Pass arg{4,5,6} to sprintf. + + * printcmd.c (x_command): Use variable itself rather + than treating it as a pointer only if it is a function. + (See comment "this makes x/i main work"). + + * coffread.c (symbol_file_command): Use error for + "%s does not have a symbol-table.\n". + +Wed Nov 1 19:56:18 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * dbxread.c [BELIEVE_PCC_PROMOTION_TYPE]: New code. + m-sparc.h: Define BELIEVE_PCC_PROMOTION_TYPE. + +Thu Oct 26 12:45:00 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * infrun.c: Include <sys/dir.h>. + + * dbxread.c (read_dbx_symtab, case N_LSYM, case 'T'): + Check for enum types and put constants in psymtab. + +Mon Oct 23 15:02:25 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * dbxread.c (define_symbol, read_dbx_symtab): Handle enum + constants (e.g. "b:c=e6,0"). + +Thu Oct 19 14:57:26 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * stack.c (frame_info): Use FRAME_ARGS_ADDRESS_CORRECT + m-vax.h (FRAME_ARGS_ADDRESS_CORRECT): New macro. + (FRAME_ARGS_ADDRESS): Restore old meaning. + + * frame.h (Frame_unknown): New macro. + stack.c (frame_info): Check for Frame_unknown return from + FRAME_ARGS_ADDRESS. + m-vax.h (FRAME_ARGS_ADDRESS): Sometimes return Frame_unknown. + + * utils.c (fatal_dump_core): Add "internal error" to message. + + * infrun.c (IN_SIGTRAMP): New macro. + (wait_for_inferior): Use IN_SIGTRAMP. + m-vax.h (IN_SIGTRAMP): New macro. + +Wed Oct 18 15:09:22 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * config.gdb, Makefile.dist: Shorten m-i386-sv32.h. + + * coffread.c (symbol_file_command): Pass 0 to select_source_symtab. + +Tue Oct 17 12:24:41 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * i386-dep.c (i386_frame_num_args): Take function from m-i386.h + file. Check for pfi null. + m-i386.h (FRAME_NUM_ARGS): Use i386_frame_num_args. + + * infrun.c (wait_for_inferior): set stop_func_name to 0 + before calling find_pc_partial_function. + +Thu Oct 12 01:08:50 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * breakpoint.c (_initialize_breakpoint): Add "disa". + + * Makefile.dist: Add GLOBAL_CFLAGS and pass to readline. + + * config.gdb (various): "$machine =" -> "machine =". + +Wed Oct 11 11:54:31 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * inflow.c (try_writing_regs): #if 0 out this function. + + * main.c (main): Add "-help" option. + + * dbxread.c (read_dbx_symtab): Merge code for N_FUN with + N_STSYM, etc. + +Mon Oct 9 14:21:55 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * inflow.c (try_writing_regs_command): Don't write past end + of struct user. + + * dbxread.c (read_struct_type): #if 0 out code which checks for + bitpos and bitsize 0. + + * config.gdb: Accept sequent-i386 (not seq386). + (symmetry): Set depfile and paramfile. + + * m-convex.h (IGNORE_SYMBOL): Check for N_MONPT if defined. + +Thu Oct 5 10:14:26 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * default-dep.c (read_inferior_memory): Put #if 0'd out comment + within /* */. + +Wed Oct 4 18:44:41 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * config.gdb: Change /dev/null to m-i386.h for various + 386 machine "opcodefile" entries. + + * config.gdb: Accept seq386 for sequent symmetry. + +Mon Oct 2 09:59:50 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * hp300bsd-dep.c: Fix copyright notice. + +Sun Oct 1 16:25:30 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * Makefile.dist (DEPFILES): Add isi-dep.c. + + * default-dep.c (read_inferior_memory): Move #endif after else. + +Sat Sep 30 12:50:16 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * version.c: Change version number to 3.3.xxx. + + * GDB 3.3 released. + + * version.c: Change version number to 3.3. + + * Makefile.dist (READLINE): Add vi_mode.c + + * config.gdb (i386): Change /dev/null to m-i386.h + + * config.gdb: Add ';;' before 'esac'. + + * Makefile.dist (gdb.tar.Z): Move comment above dependency. + + * dbxread.c (read_ofile_symtab): Check symbol before start + of source file for GCC_COMPILED_FLAG_SYMBOL. + (start_symtab): Don't clear processing_gcc_compilation. + +Thu Sep 28 22:30:23 1989 Roland McGrath (roland at hobbes.ai.mit.edu) + + * valprint.c (print_string): If LENGTH is zero, print "". + +Wed Sep 27 10:15:10 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * config.gdb: "rm tmp.c" -> "rm -f tmp.c". + +Tue Sep 26 13:02:10 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * utils.c (_initialize_utils): Use termcap to set lines_per_page + and chars_per_line. + +Mon Sep 25 10:06:43 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * dbxread.c (read_dbx_symtab, N_SOL): Do not add the same file + more than once. + +Thu Sep 21 12:43:18 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * infcmd.c (unset_environment_command): Delete all variables + if called with no arg. + + * remote.c, inferior.h (remote_{read,write}_inferior_memory): + New functions. + core.c ({read,write}_memory): Use remote_{read,write}_inferior_memory. + + * valops.c (call_function): When reserving stack space for + arguments, call value_arg_coerce. + + * m-hp9k320.h: define BROKEN_LARGE_ALLOCA. + + * breakpoint.c (delete_command): Ask for confirmation only + when there are breakpoints. + + * dbxread.c (read_struct_type): If lookup_basetype_type has + copied a stub type, call add_undefined_type. + + * sparc_pinsn.c (compare_opcodes): Check for "1+i" anywhere + in args. + + * val_print.c (type_print_base): Print stub types as + "<incomplete type>". + +Wed Sep 20 07:32:00 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * sparc-opcode.h (swapa): Remove i bit from match. + (all alternate space instructions): Delete surplus "foo rs1+0" + patterns. + + * Makefile.dist (LDFLAGS): Set to $(CFLAGS). + + * remote-multi.shar (remote_utils.c, putpkt): Change csum to unsigned. + +Tue Sep 19 14:15:16 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * sparc-opcode.h: Set i bit in lose for many instructions which + aren't immediate. + + * stack.c (print_frame_info): add "func = 0". + +Mon Sep 18 16:19:48 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * sparc-opcode.h (mov): Add mov to/from %tbr, %psr, %wim. + + * sparc-opcode.h (rett): Fix notation to use suggested assembler + syntax from architecture manual. + + * symmetry-dep.c (I386_REGNO_TO_SYMMETRY): New macro. + (i386_frame_find_saved_regs): Use I386_REGNO_TO_SYMMETRY. + +Sat Sep 16 22:21:17 1989 Jim Kingdon (kingdon at spiff) + + * remote.c (remote_close): Set remote_desc to -1. + + * gdb.texinfo (Output): Fix description of echo to match + reality and ANSI C. + +Fri Sep 15 14:28:59 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * symtab.c (lookup_symbol): Add comment about "asm". + + * sparc-pinsn.c: Use NUMOPCODES. + + * sparc-opcode.h (NUMOPCODES): Use sparc_opcodes[0] not *sparc_opcodes. + +Thu Sep 14 15:25:20 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * dbxread.c (xxmalloc): Print error message before calling abort(). + + * infrun.c (wait_for_inferior): Check for {stop,prev}_func_name + null before passing to strcmp. + +Wed Sep 13 12:34:15 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * sparc-opcode.h: New field delayed. + sparc-pinsn.c (is_delayed_branch): New function. + (print_insn): Check for delayed branches. + + * stack.c (print_frame_info): Use misc_function_vector in + case where ar truncates file names. + +Tue Sep 12 00:16:14 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * convex-dep.c (psw_info): Move "struct pswbit *p" with declarations. + +Mon Sep 11 14:59:57 1989 Jim Kingdon (kingdon at spiff) + + * convex-dep.c (core_file_command): Delete redundant printing + of "Program %s". + + * m-convex.h (ENTRY_POINT): New macro. + + * m-convex.h (FRAME_CHAIN_VALID): Change outside_first_object_file + to outside_startup_file + + * main.c: #if 0 out catch_termination and related code. + + * command.c (lookup_cmd_1): Consider underscores part of + command names. + +Sun Sep 10 09:20:12 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * printcmd.c: Change asdump_command to disassemble_command + (_initialize_printcmd): Change asdump to diassemble. + + * main.c (main): Exit with code 0 if we hit the end of a batch + file. + + * Makefile.dist (libreadline.a): Fix syntax of "CC=${CC}". + +Sat Sep 9 01:07:18 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * values.c (history_info): Renamed to value_history_info. + Command renamed to "info value" (with "info history" still + accepted). + + * sparc-pinsn.c (print_insn): Extend symbolic address printing + to cover "sethi" following by an insn which uses 1+i. + +Fri Sep 8 14:24:01 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * m-hp9k320.h, m-hp300bsd.h, m-altos.h, m-sparc.h, m-sun3.h + (READ_GDB_SYMSEGS): Remove. + dbxread.c [READ_GDB_SYMSEGS]: Remove code to read symsegs. + + * sparc-pinsn.c (print_insn): Detect "sethi-or" pairs and + print symbolic address. + + * sparc-opcode.h (sethi, set): Change lose from 0xc0000000 to + 0xc0c00000000. + + * remote.c (remote_desc): Initialize to -1. + + * Makefile.dist (libreadline.a): Pass CC='${CC}' to readline makefile. + +Thu Sep 7 00:07:17 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * dbxread.c (read_struct_type): Check for static member functions. + values.c, eval.c, valarith.c, valprint.c, valops.c: Merge changes + from Tiemann for static member functions. + + * sparc-opcode.h (tst): Fix all 3 patterns. + + * Makefile.dist (gdb1): New rule. + + * sparc-opcode.h: Change comment about what the disassembler + does with the order of the opcodes. + + * sparc-pinsn.c (compare_opcodes): Put 1+i before i+1. + Also fix mistaken comment about preserving order of original table. + + * sparc-opcode.h (clr, mov): Fix incorrect lose entries. + + * m-symmetry.h (FRAME_NUM_ARGS): Add check to deal with code that + GCC sometimes generates. + + * config.gdb: Change all occurances of "skip" to "/dev/null". + + * README (about languages other than C): Update comments about + Pascal and FORTRAN. + + * sparc-opcode.h (nop): Change lose from 0xae3fffff to 0xfe3fffff. + + * values.c (value_virtual_fn_field): #if 0-out assignment to + VALUE_TYPE(vtbl). + +Wed Sep 6 12:19:22 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * utils.c (fatal_dump_core): New function. + Makefile.dist (MALLOC_FLAGS): use -Dbotch=fatal_dump_core + +Tue Sep 5 15:47:18 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * breakpoint.c (enable_command): With no arg, enable all bkpts. + + * Makefile.dist (Makefile): Remove \"'s around $(MD). + + * Makefile.dist: In "cd readline; make . . ." change first + SYSV_DEFINE to SYSV. + + * m68k-pinsn.c (_initialize_pinsn): Use alternate assembler + syntax #ifdef HPUX_ASM + +Sat Sep 2 23:24:43 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * values.c (history_info): Don't check num_exp[0] if num_exp + is nil (just like recent editing_info change). + +Fri Sep 1 19:19:01 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * gdb.texinfo (inc-history, inc-readline): Copy in the inc-* files + because people might not have makeinfo. + + * README (xgdb): Strengthen nasty comments. + + * gdb.texinfo: Change @setfilename to "gdb.info". + +Thu Aug 31 17:23:50 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * main.c (editing_info): Don't check arg[0] if arg is null. + + * m-vax.h: Add comment about known sigtramp bug. + + * sun3-dep.c, sparc-dep.c (IS_OBJECT_FILE, exec_file_command): + Get right text & data addresses for .o files. + +Wed Aug 30 13:54:19 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * utils.c (tilde_expand): Remove function (it's in readline). + + * sparc-opcode.h (call): Change "8" to "9" in first two + patterns (%g7->%o7). + +Tue Aug 29 16:44:41 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * printcmd.c (whatis_command): Change 4th arg to type_print + from 1 to -1. + +Mon Aug 28 12:22:41 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * dbxread.c (psymtab_to_symtab_1): In "and %s ..." change + pst->filename to pst->dependencies[i]->filename. + + * blockframe.c (FRAMELESS_LOOK_FOR_PROLOGUE): New macro + made from FRAMELESS_FUNCTION_INVOCATION from m-sun3.h except + that it checks for zero return from get_pc_function_start. + m-hp9k320.h, m-hp300bsd.h, m-i386.h, m-isi.h, m-altos.h, + m-news.h, m-sparc.h, m-sun2.h, m-sun3.h, m-symmetry.h + (FRAMELESS_FUNCTION_INVOCATION): Use FRAMELESS_LOOK_FOR_PROLOGUE. + + * dbxread.c (read_struct_type): Give warning and ignore field + if bitpos and bitsize are zero. + +Sun Aug 27 04:55:20 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * dbxread.c (psymtab_to_symtab{,_1}): Print message about + reading in symbols before reading stringtab, not after. + +Sat Aug 26 02:01:53 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * dbxread.c (IS_OBJECT_FILE, ADDR_OF_TEXT_SEGMENT): New macros. + (read_dbx_symtab): Use text_addr & text_size to set end_of_text_addr. + (symbol_file_command): pass text_addr & text_size to read_dbx_symtab. + +Fri Aug 25 23:08:13 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * valprint.c (value_print): Try to give the name of function + pointed to when printing a function pointer. + +Thu Aug 24 23:18:40 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * core.c (xfer_core_file): In cases where MEMADDR is above the + largest address that makes sense, set i to len. + +Thu Aug 24 16:04:17 1989 Roland McGrath (roland at hobbes.ai.mit.edu) + + * valprint.c (print_string): New function to print a character + string, doing array-max limiting and repeat count processing. + (val_print, value_print): Use print_string. + (REPEAT_COUNT_THRESHOLD): New #define, the max number of elts to print + without using a repeat count. Set to ten. + (value_print, val_print): Use REPEAT_COUNT_THRESHOLD. + + * utils.c (printchar): Use {fputs,fprintf}_filtered. + + * valprint.c (val_print): Pass the repeat count arg to the + fprintf_filtered call for "<repeats N times>" messages. + +Wed Aug 23 22:53:47 1989 Roland McGrath (roland at hobbes.ai.mit.edu) + + * utils.c: Include <pwd.h>. + + * main.c: Declare free. + +Wed Aug 23 05:05:59 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * utils.c, defs.h: Add tilde_expand. + source.c (directory_command), + main.c (cd_command), + main.c (set_history_filename), + dbxread.c (symbol_file_command), + coffread.c (symbol_file_command), + dbxread.c (add_file_command), + symmisc.c (print_symtabs), + *-dep.c (exec_file_command, core_file_command), + main.c (source_command): Use tilde_expand. + + * dbxread.c (read_type): When we get a cross-reference, resolve + it immediately if possible, only calling add_undefined_type if + necessary. + + * gdb.texinfo: Uncomment @includes and put comment at start + of file telling people to use makeinfo. + + * valprint.c (type_print_base): Print the right thing for + bitfields. + + * config.gdb (sun3os3): Set paramfile and depfile. + +Tue Aug 22 05:38:36 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * dbxread.c (symbol_file_command): Pass string table size to + read_dbx_symtab(). + (read_dbx_symtab): Before indexing into string table, check + string table index for reasonableness. + (psymtab_to_symtab{,_1}, read_ofile_symtab): Same. + +Tue Aug 22 04:04:39 1989 Roland McGrath (roland at hobbes.ai.mit.edu) + + * m68k-pinsn.c: Replaced many calls to fprintf and fputs with + calls to fprintf_filtered and fputs_filtered. + (print_insn_arg): Use normal MIT 68k syntax for postincrement, + predecrement, and register indirect addressing modes. + +Mon Aug 21 10:08:02 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * main.c (initialize_signals): Set signal handler for SIGQUIT + and SIGHUP to do_nothing. + + * ns32k-opcode.h (ord): Change 1D1D to 1D2D. + + * ns32k-pinsn.c (print_insn_arg, print_insn): Handle index + bytes correctly. + + * ns32k-opcode.h: Add comments. + + * dbxread.c (read_type): Put enum fields in type.fields in order + that they were found in the debugging symbols (not reverse order). + +Sun Aug 20 21:17:13 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * main.c (source_command): Read .gdbinit if run without argument. + + * source.c (directory_command): Only print "foo already in path" + if from_tty. + + * version.c: Change version number to 3.2.xxx + +Sat Aug 19 00:24:08 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * m-news.h: Define HAVE_WAIT_STRUCT. + + * m-isi.h, isi-dep.c: Replace with new version from Adam de Boor. + config.gdb: Remove isibsd43. + + * main.c (catch_termination): Don't say we have written + .gdb_history until after we really have. + + * convex-dep.c (attach): Add "sleep (1)". + (write_vector_register): Use "LL" with long long constant. + (wait): Close comment. + (wait): Change "unix 7.1 bug" to "unix 7.1 feature" & related + changes in comment. + (scan_stack): And fp with 0x80000000 in while loop test. + (core_file_command): Move code to set COREFILE. + (many places): Change printf to printf_filtered. + (psw_info): Allow argument giving value to print as a psw. + (_initialize_convex_dep): Update docstrings. + + * m-convex.h (WORDS_BIG_ENDIAN): Correct typo ("WRODS") + define NO_SIGINTERRUPT. + define SET_STACK_LIMIT_HUGE. + add "undef BUILTIN_TYPE_LONGEST" before defining it. + Use "LL" after constants in CALL_DUMMY. + + * dbxread.c: In the 3 places it says error "ridiculous string + table size"... delete extra parameter to error. + + * dbxread.c (scan_file_globals): Check for FORTRAN common block. + Allow multiple references for the sake of common blocks. + + * main.c (initialize_main): Set history_filename to include + current directory. + + * valprint.c (decode_format): Don't return a defaulted size + field if osize is zero. + + * gdb.texinfo (Compilation): Update information on -gg symbols. + Document problem with ar. + +Fri Aug 18 19:45:20 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * valprint.c (val_print, value_print): Add "<repeats %d times>" code. + Also put "..." outside quotes for strings. + + * main.c (initialize_main): Add comment about history output file + being different from history input file. + + * m-newsos3.h: Undefine NO_SIGINTERRUPT. Rearrange a few comments. + + * m-newsos3.h (REGISTER_U_ADDR): Use new version from Hikichi. + + * sparc-opcode.h: Add comment clarifying meaning of the order of + the entries in sparc_opcodes. + + * eval.c (evaluate_subexp, case UNOP_IND): Deal with deferencing + things that are not pointers. + + * valops.c (value_ind): Make dereferencing an int give a LONGEST. + + * expprint.c (print_subexp): Add (int) cast in OP_LAST case. + + * dbxread.c (read_array_type): Set lower and upper if adjustable. + + * symtab.c (lookup_symbol): Don't abort if symbol found in psymtab + but not in symtab. + +Thu Aug 17 15:51:20 1989 Randy Smith (randy at hobbes.ai.mit.edu) + + * config.gdb: Changed "Makefile.c" to "Makefile.dist". + +Thu Aug 17 01:58:04 1989 Roland McGrath (roland at apple-gunkies.ai.mit.edu) + + * sparc-opcode.h (or): Removed incorrect lose bit 0x08000000. + [many]: Changed many `lose' entries to have the 0x10 bit set, so + they don't think %l0 is %g0. + +Wed Aug 16 00:30:44 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * m-symmetry.h (STORE_STRUCT_RETURN): Also write reg 0. + (EXTRACT_RETURN_VALUE): Call symmetry_extract_return_value. + symmetry-dep.c (symmetry_extract_return_value): New fn. + + * main.c (symbol_completion_function): Deal with changed + result_list from lookup_cmd_1 for ambiguous return. + command.c (lookup_cmd): Same. + + * inflow.c [TIOCGETC]: Move #include "param.h" back before + system #includes. Change all #ifdef TIOCGETC to + #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN) + m-i386-sysv3.2.h, m-i386gas-sysv3.2.h: Remove "#undef TIOCGETC" + and add "#define TIOCGETC_BROKEN". + + * command.c (lookup_cmd_1): Give the correct result_list in the + case of an ambiguous return where there is a partial match + (e.g. "info a"). Add comment clarifying what is the correct + result_list. + + * gdb.texinfo (GDB History): Document the two changes below. + + * main.c (command_line_input): Make history expansion not + just occur at the beginning of a line. + + * main.c (initialize_main): Make history expansion off by default. + + * inflow.c: Move #include "param.h" after system #includes. + + * i386-dep.c (i386_float_info): Use U_FPSTATE macro. + + * m-i386-sysv3.2.h, m-i386gas-sysv3.2.h: New files. + Makefile.dist, config.gdb: Know about these new files. + +Tue Aug 15 21:36:11 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * symtab.c (lookup_struct_elt_type): Use type_print rather + than assuming type has a name. + +Tue Aug 15 02:25:43 1989 Roland McGrath (roland at apple-gunkies.ai.mit.edu) + + * sparc-opcode.h (mov): Removed bogus "or i,0,d" pattern. + + * sparc-opcode.h (mov, or): Fixed incorrect `lose' members. + + * sparc-dep.c: Don't include "sparc-opcode.h". + (skip_prologue, isanulled): Declare special types to recognize + instructions, and use them. + + * sparc-pinsn.c (print_insn): Sign-extend 13-bit immediate args. + If they are less than +9, print them in signed decimal instead + of unsigned hex. + + * sparc-opcode.h, sparc-pinsn.c: Completely rewritten to share an + opcode table with gas, and thus produce disassembly that looks + like what the assembler accepts. + +Tue Aug 15 16:20:52 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * symtab.c (find_pc_psymbol): Move best_pc=psymtab->textlow-1 + after test for psymtab null. + + * main.c (editing_info): Remove variable retval. + + * config.gdb (sun3, isi): Comment out obsolete message about telling + it whether you have an FPU (now that it detects it). + + * config.gdb (sun3): Accept sun3os3. + + * m68k-insn.h: Include <signal.h>. + + * m68k-pinsn.h (convert_{to,from}_68881): Add have_fpu code + + * m-newsos3.h: Undefine USE_PCB. That code didn't seem to work. + + * sparc-dep.c: Put in insn_fmt and other stuff from the old + sparc-opcode.h. + + * sparc-opcode.h, sparc-pinsn.c: Correct copyright notice. + + * sparc-opcode.h, sparc-pinsn.c: Replace the old ones with the new + ones by roland. + +Tue Aug 15 02:25:43 1989 Roland McGrath (roland at apple-gunkies.ai.mit.edu) + + * Makefile.dist: Don't define CC at all. + + * Makefile.dist (Makefile): Remove tmp.c after preprocessing. + Use $(MD) instead of M_MAKEDEFINE in the cc command. + + * Makefile.dist: Don't define RL_LIB as + "${READLINE}/libreadline.a", since READLINE is a list of files. + +Mon Aug 14 23:49:29 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * main.c (print_version): Change 1988 to 1989. + + * main.c (copying_info, initialize_main): Remove #if 0'd code. + +Tue Aug 1 14:44:56 1989 Hikichi (hikichi at sran203) + + * m-newsos3.h + (NO_SIGINTERRUPT): have SIGINTERRUPT on NEWS os 3. + + * m-news.h(FRAME_FIND_SAVED_REGS): use the sun3's instead of old + one. + +Mon Aug 14 15:27:01 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * m-news.h, m-newsos3.h, news-dep.c: Merge additional changes + by Hikichi (ChangeLog entries above). + + * Makefile.dist (READLINE): List readline files individually + so we don't accidently get random files from the readline + directory. + + * m-news.h (STORE_RETURN_VALUE, EXTRACT_RETURN_VALUE): + Expect floating point returns to be in fp0. + + * gdb.texinfo (Format options): New node. + + * gdb.texinfo: Comment out "@include"s until bfox fixes the + readline & history docs. + + * dbxread.c (read_addl_syms): Set startup_file_* if necessary at + the end (as well as when we hit ".o"). + + * printcmd.c (decode_format): Set val.format & val.size to '?' at + start and set defaults at end. + + * symtab.c (decode_line_1): Check for class_name null. + + * valops.c: Each place where it compares against field names, + check for null field names. (new t_field_name variables). + + * utils.c (fputs_filtered): Check for linebuffer null before + checking whether to call fputs. Remove later check for linebuffer + null. + +Sun Aug 13 15:56:50 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * m-isi.h, m-sun3.h ({PUSH,POP}_FP_REGS): New macros. + m-sun3.h (NUM_REGS): Conditionalize on FPU. + config.gdb (sun3, isi): Add message about support for machines + without FPU. + + * main.c (catch_termination, initialize_signals): new functions. + + * main.c (editing_info): Add "info editing n" and "info editing +". + Rewrite much of this function. + gdb.texinfo (GDB Readline): Document it. + + * values.c (history_info): Add "info history +". Also add code to + do "info history +" when command is repeated. + gdb.texinfo (Value History): Document "info history +". + + * expprint.c (print_subexp): Add OP_THIS to case stmt. + + * config.gdb (sun4os4): Put quotes around make define. + + * config.gdb: Canonicalize machine name at beginning. + +Sat Aug 12 00:50:59 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * config.gdb: define M_MAKEDEFINE + Makefile (Makefile, MD): Be able to re-make Makefile. + + * main.c (command_line_input): Add comments to + the command history. + + * Makefile.dist (Makefile): Add /bin/false. + +Fri Aug 11 14:35:33 1989 Jim Kingdon (kingdon at spiff) + + * Makefile.dist: Comment out .c.o rule and add TARGET_ARCH. + + * m-altos.h: Include sys/page.h & sys/net.h + + * m-altos.h (FRAME_CHAIN{,_VALID}): Use outside_startup_file. + + * config.gdb (altos, altosgas): Add M_SYSV & M_BSD_NM and remove + M_ALLOCA=alloca.o from makedefine. + + * coffread.c (complete_symtab): Change a_entry to entry. + + * m-altosgas.h: New file. + + * m-symmetry (REGISTER_BYTE): Fix dumb mistake. + +Fri Aug 11 06:39:49 1989 Roland McGrath (roland at hobbes.ai.mit.edu) + + * utils.c (set_screensize_command): Check for ARG being nil, since + that's what execute_command will pass if there's no argument. + + * expread.y (yylex): Recognize "0x" or "0X" as the beginning of a + number. + +Thu Aug 10 15:43:12 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * config.gdb, Makefile.dist: Rename Makefile.c to Makefile.dist. + + * m-altos.h: Add comment about porting to USGR2. + + * config.gdb (sparc): Add -Usparc. + +Wed Aug 9 14:20:39 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * m-sun3os4.h: Define BROKEN_LARGE_ALLOCA. + + * values.c (modify_field): Check for value too large to fit in + bitfield. + + * utils.c (fputs_filtered): Allow LINEBUFFER to be NULL. + + * breakpoint.c (condition_command): Check for attempt to specify + non-numeric breakpoint number. + + * config.gdb, Makefile, m-altos.h, altos-dep.c: Merge Altos + port. + + * README: Change message about editing Makefile. + + * config.gdb: Edit Makefile. + Copied Makefile to Makefile.c and changed to let config.gdb + run us through the C preprocessor. + + * expread.y (yylex): Test correctly for definition of number. + +Wed Aug 9 11:56:05 1989 Randy Smith (randy at hobbes.ai.mit.edu) + + * dbxread.c (read_dbx_symtab): Put bracketing of entry point in + test case for .o symbols so that it will be correct even without + debugging symbols. + (end_psymtab): Took bracketing out. + + * blockframe.c (outside_startup_file): Reverse the sense of the + return value to make the functionality implied by the name + correct. + +Tue Aug 8 11:48:38 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * coffread.c (symbol_file_command): Do not assume presence of a.out + header. + + * blockframe.c: Replace first_object_file_end with + startup_file_{start,end} + (outside_startup_file): New function. + dbxread.c (read_addl_syms, read_dbx_symtab, end_psymbol): set + startup_file_*. Delete first_object_file_end code. + Add entry_point and ENTRY_POINT + coffread.c (complete_symtab): Set startup_file_*. + (first_object_file_end): Add as static. + m-*.h (FRAME_CHAIN, FRAME_CHAIN_VALID): Call outside_startup_file + instead of comparing with first_object_file_end. + + * breakpoint.c (breakpoint_1): Change -1 to (CORE_ADDR)-1. + + * config.gdb (i386, i386gas): Add missing quotes at end of "echo" + + * source.c (directory_command): Add dont_repeat (); + +Mon Aug 7 18:03:51 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * dbxread.c (read_addl_syms): Change strcmp to strncmp and put 3rd + arg back. + + * command.h (struct cmd_list_element): Add comment clarifying + purpose of abbrev_flag. + +Mon Aug 7 12:51:03 1989 Randy Smith (randy at hobbes.ai.mit.edu) + + * printcmd.c (_initialize_printcmd): Changed "undisplay" not to + have abbrev flag set; it isn't an abbreviation of "delete + display", it's an alias. + +Mon Aug 7 00:25:15 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * symtab.c (lookup_symtab_1): Remove filematch (never used). + + * expread.y [type]: Add second argument to 2 calls to + lookup_member_type which were missing them. + + * dbxread.c (symbol_file_command): Add from_tty arg. + Check it before calling query. + + * infcmd.c (tty_command): Add from_tty arg. + + * eval.c (evaluate_subexp): Remove 3rd argument from + calls to value_x_unop. + + * dbxread.c (read_addl_syms): Remove 3rd argument from + call to strcmp. + + * gdb.texinfo (Command editing): @include inc-readline.texinfo + and inc-history.texinfo and reorganize GDB-specific stuff. + + * Makefile: Add line MAKE=make. + + * README (second paragraph): Fix trivial errors. + + * dbxread.c (read_struct_type): Make sure p is initialized. + + * main.c (symbol_completion_function): Complete correctly + on the empty string. + +Sun Aug 6 21:01:59 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * symmetry-dep.c: Remove "long" from definition of i386_follow_jump. + + * gdb.texinfo (Backtrace): Document "where" and "info stack". + + * dbxread.c (cleanup_undefined_types): Strip off "struct " + or "union " from type names before doing comparison + +Sat Aug 5 02:05:36 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * config.gdb (i386, i386gas): Improve makefile editing instructions. + + * Makefile: Fix typo in CLIBS for SYSV. + + * dbxread.c (read_dbx_symtab): Deal with N_GSYM typedefs. + + * dbxread.c (add_file_command): Do not free name. We didn't + allocate it; it just points into arg_string. + + * Makefile, m-*.h: Change LACK_VPRINTF to HAVE_VPRINTF. + +Fri Jul 28 00:07:48 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * valprint.c (val_print): Made sure that all returns returned a + value (usually 0, indicating no memory printed). + + * core.c (read_memory): Changed "return" to "return 0". + + * expread.y (parse_number): Handle scientific notation when the + string does not contain a '.'. + +Thu Jul 27 15:14:03 1989 Randy Smith (randy at hobbes.ai.mit.edu) + + * infrun.c (signals_info): Error if signal number passed is out of + bounds. + + * defs.h: Define alloca to be __builtin_alloca if compiling with + gcc and localized inclusion of alloca.h on the sparc with the + other alloca stuff. + * command.c: Doesn't need to include alloca.h on the sparc; defs.h + does it for you. + + * printcmd.c (print_frame_args): Changed test for call to + print_frame_nameless_args to check i to tell if any args had been + printed. + +Thu Jul 27 04:40:56 1989 Roland McGrath (roland at hobbes.ai.mit.edu) + + * blockframe.c (find_pc_partial_function): Always check that NAME + and/or ADDRESS are not nil before storing into them. + +Wed Jul 26 23:41:21 1989 Roland McGrath (roland at hobbes.ai.mit.edu) + + * m-newsos3.h: Define BROKEN_LARGE_ALLOCA. + * dbxread.c (symbol_file_command, psymtab_to_symtab): + Use xmalloc #ifdef BROKEN_LARGE_ALLOCA. + +Tue Jul 25 16:28:18 1989 Jay Fenlason (hack at apple-gunkies.ai.mit.edu) + + * m68k-opcode.h: moved some of the fmovem entries so they're + all consecutive. This way the assembler doesn't bomb. + +Mon Jul 24 22:45:54 1989 Randy Smith (randy at hobbes.ai.mit.edu) + + * symtab.c (lookup_symbol): Changed error to an informational (if + not very comforting) message about internal problems. This will + get a null symbol returned to decode_line_1, which should force + things to be looked up in the misc function vector. + +Wed Jul 19 13:47:34 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * symtab.c (lookup_symbol): Changed "fatal" to "error" in + external symbol not found in symtab in which it was supposed to be + found. This can be reached because of a bug in ar. + +Tue Jul 18 22:57:43 1989 Randy Smith (roland at hobbes.ai.mit.edu) + + * m-news.h [REGISTER_U_ADDR]: Decreased the assumed offset of fp0 + by 4 to bring it into (apparently) appropriate alignment with + reality. + +Tue Jul 18 18:14:42 1989 Randy Smith (randy at hobbes.ai.mit.edu) + + * Makefile: pinsn.o should depend on opcode.h + + * m68k-opcode.h: Moved fmovemx with register lists to before other + fmovemx. + +Tue Jul 18 11:21:42 1989 Jim Kingdon (kingdon at susie) + + * Makefile, m*.h: Only #define vprintf (to _doprnt or printf, + depends on the system) if the library lacks it (controlled by + LACK_VPRINTF_DEFINE in makefile). Unpleasant, but necessary to + make this work with the GNU C library. + +Mon Jul 17 15:17:48 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * breakpoint.c (breakpoint_1): Change addr-b->address to + b->address-addr. + +Sun Jul 16 16:23:39 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * eval.c (evaluate_subexp): Change error message printed when + right operand of '@' is not an integer to English. + + * infcmd.c (registers_info): Fix call to print_spaces_filtered + to specify right # of arguments. + + * gdb.texinfo (Command Editing): Document info editing command. + + * coffread.c (read_file_hdr): Add MC68MAGIC. + + * source.c (select_source_symtab): Change MAX to max. + +Fri Jul 14 21:19:11 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * infcmd.c (registers_info): Clean up display to look good with long + register names, to say "register" instead of "reg", and to put the + "relative to selected stack frame" bit at the top. + +Fri Jul 14 18:23:09 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (record_misc_function): Put parens around | to force + correct evaluation. + +Wed Jul 12 12:25:53 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * m-newsos3, m-news, infrun.c, Makefile, config.gdb, news-dep.c: + Merge in Hikichi's changes for Sony/News-OS 3 support. + +Tue Jul 11 21:41:32 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * utils.c (fputs_filtered): Don't do any filtering if output is + not to stdout, or if stdout is not a tty. + (fprintf_filtered): Rely on fputs_filtered's check for whether to + do filtering. + +Tue Jul 11 00:33:58 1989 Randy Smith (randy at hobbes.ai.mit.edu) + + * GDB 3.2 Released. + + * valprint.h: Deleted. + + * utils.c (fputs_filtered): Don't do any filtering if filtering is + disabled (lines_per_page == 0). + +Mon Jul 10 22:27:53 1989 Randy Smith (roland at hobbes.ai.mit.edu) + + * expread.y [typebase]: Added "unsigned long int" and "unsigned + short int" to specs. + +Mon Jul 10 21:44:55 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * main.c (main): Make -cd use cd_command to avoid + current_directory with non-absolute pathname. + +Mon Jul 10 00:34:29 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (symbol_file_command): Catch errors from stat (even + though they should never happen). + + * source.c (openp): If the path is null, use the current + directory. + + * dbxread.c (read_dbx_symtab): Put N_SETV symbols into the misc + function vector ... + (record_misc_function): ... as data symbols. + + * utils.c (fprintf_filtered): Return after printing if we aren't + going to do filtering. + + * Makefile: Added several things for make clean to take care of. + + * expread.y: Lowered "@" in precedence below +,-,*,/,%. + + * eval.c (evaluate_subexp): Return an error if the rhs of "@" + isn't integral. + + * Makefile: Added removal of core and gdb[0-9] files to clean + target. + + * Makefile: Made a new target "distclean", which cleans things up + correctly for making a distribution. + +Sun Jul 9 23:21:27 1989 Randy Smith (randy at hobbes.ai.mit.edu) + + * dbxread.c: Surrounded define of gnu symbols with an #ifndef + NO_GNU_STABS in case you don't want them on some machines. + * m-npl.h, m-pn.h: Defined NO_GNU_STABS. + +Sun Jul 9 19:25:22 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * utils.c (fputs_filtered): New function. + (fprintf_filtered): Use fputs_filtered. + utils.c (print_spaces_filtered), + command.c (help_cmd,help_cmd_list), + printcmd.c (print_frame_args), + stack.c (print_block_frame_locals, print_frame_arg_vars), + valprint.c (many functions): Use fputs_filtered instead of + fprintf_filtered to avoid arbitrary limit. + + * utils.c (fprintf_filtered): Fix incorrect comment. + +Sat Jul 8 18:12:01 1989 Randy Smith (randy at hobbes.ai.mit.edu) + + * valprint.c (val_print): Changed assignment of pretty to use + prettyprint as a conditional rather than rely on values of the + enum. + + * Projects: Cleaned up a little for release. + + * main.c (initialize_main): Initialize + rl_completion_entry_function instead of completion_entry_function. + + * Makefile: Modified to use the new readline library setup. + + * breakpoint.c (break_command_1, delete_breakpoint, + enable_breakpoint, disable_breakpoint): Put in new printouts for + xgdb usage triggered off of xgdb_verbose. + * main.c (main): Added check for flag to set xgdb_verbose. + * stack.c (frame_command): Set frame_changed when frame command + used. + +Fri Jul 7 16:20:58 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * Remove valprint.h and move contents to value.h (more logical). + +Fri Jul 7 02:28:06 1989 Randall Smith (randy at rice-chex) + + * m68k-pinsn.c (print_insn): Included a check for register list; + if there is one, make sure to start p after it. + + * breakpoint.c (break_command_1, delete_breakpoint, + enable_breakpoint, disable_breakpoint): #ifdef'd out changes + below; they produce unwanted output in gdb mode in gnu-emacs. + + * gdb.texinfo: Spelled. Also removed index references from + command editing section; the relevance/volume ratio was too low. + Removed all references to the function index. + + * ns32k-opcode.h, ns32k-pinsn.c: Backed out changes of June 24th; + haven't yet received legal papers. + + * .gdbinit: Included message telling the user what it is doing. + + * symmetry-dep.c: Added static decls for i386_get_frame_setup, + i386_follow_jump. + * values.c (unpack_double): Added a return (double)0 at the end to + silence a compiler warning. + + * printcmd.c (containing_function_bounds, asdump_command): Created + to dump the assembly code of a function (support for xgdb and a + useful hack). + (_initialize_printcmd): Added this to command list. + * gdb.texinfo [Memory]: Added documentation for the asdump + command. + * breakpoint.c (break_command_1, delete_breakpoint, + enable_breakpoint, disable_breakpoint): Added extra verbosity for + xgdb conditionalized on the new external frame_full_file_name. + * source.c (identify_source_line): Increase verbosity of fullname + prointout to include pc value. + * stack.c: Added a new variable; "frame_changed" to indicate when + a frame has been changed so that gdb can print out a frame change + message when the frame only changes implicitly. + (print_frame_info): Check the new variable in determining when to + print out a new message and set it to zero when done. + (up_command): Increment it. + (down_command): Decrement it. + + * m68k-pinsn.c (print_insn_arg [lL]): Modified cases for register + lists to reset the point to point to after the word from which the + list is grabbed *if* that would cause point to point farther than + it currently is. + +Thu Jul 6 14:28:11 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * valprint.c (val_print, value_print): Add parameter to control + prettyprinting. + valprint.h: New file containing constants used for passing + prettyprinting parameter to val{,ue}_print. + expprint.c, infcmd.c, printcmd.c, valprint.c, values.c: + Change all calls to val{,ue}_print to use new parameter. + +Mon Jul 3 22:38:11 1989 Randy Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (,process_one_symbol): Moved extern declaration for + index out of function to beginning of file. + +Mon Jul 3 18:40:14 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu) + + * gdb.texinfo (Registers): Add "ps" to list of standard registers. + +Sun Jul 2 23:13:03 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * printcmd.c (enable_display): Change d->next to d = d->next so + that "enable display" without args works. + +Fri Jun 30 23:42:04 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * source.c (list_command): Made error message given when no + symtab is loaded clearer. + + * valops.c (value_assign): Make it so that when assigning to an + internal variable, the type of the assignment exp is the type of + the value being assigned. + +Fri Jun 30 12:12:43 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * main.c (verbose_info): Created. + (initialize_main): Put "info verbose" into command list. + + * utils.c (screensize_info): Created. + (_initialize_utils): Defined "info screensize" as a normal command. + + * valprint.c (format_info): Added information about maximum number + of array elements to function. + + * blockframe.c (find_pc_partial_function): Again. + + * blockframe.c (find_pc_partial_function): Replaced a "shouldn't + happen" (which does) with a zero return. + + * main.c (dont_repeat): Moved ahead of first use. + +Thu Jun 29 19:15:08 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * vax-opcode.h: Made minor modifications (moved an instruction and + removed a typo) to bring this into accord with gas' table; also + changed copyright to reflect it being part of both gdb and gas. + + * m68k-opcode.h: Added whole scads and bunches of new stuff for + the m68851 and changed the coptyrightto recognize that the file + was shared between gdb and gas. + + * main.c (stop_sig): Use "dont_repeat ()" instead of *line = 0; + + * core.c (read_memory): Don't do anything if length is 0. + + * Makefile: Added readline.c to the list of files screwed by + having the ansi ioctl.h compilation with gcc. + + * config.gdb: Added sun4os3 & sun4-os3 as availible options. + +Wed Jun 28 02:01:26 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu) + + * command.c (lookup_cmd): Add ignore_help_classes argument. + (lookup_cmd_1): Add ignore_help_classes argument. + command.c, main.c: Change callers of lookup_cmd{,_1} to supply + value for ignore_help_classes. + +Tue Jun 27 18:01:31 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * utils.c (print_spaces_filtered): Made more efficient. + * defs.h: Declaration. + * valprint.c (val_print): Used in a couple of new places. + +Mon Jun 26 18:27:28 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * m68k-pinsn.c (print_insn_arg ['#', '^']): Combined them into one + case which always gets the argument from the word immediately + following the instruction. + (print_insn_arg ["[lL]w"]): Make sure to always get the register + mask from the word immediately following the instruction. + +Sun Jun 25 19:14:56 1989 Randall Smith (randy at galapas.ai.mit.edu) + + * Makefile: Added hp-include back in as something to distribute. + + * stack.c (print_block_frame_locals): Return value changed from + void to int; return 1 if values printed. Use _filtered. + (print_frame_local_vars): Use return value from + print_block_frame_locals to mention if nothing printed; mention + lack of symbol table, use _filtered. + (print_frame_arg_vars): Tell the user if no symbol table + or no values printed. Use fprintf_filtered instead of fprintf. + * blockframe.c (get_prev_frame_info): Check for no inferior or + core file before crashing. + + * inflow.c (inferior_died): Set current frame to zero to keep from + looking like we're in start. + +Sat Jun 24 15:50:53 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * stack.c (frame_command): Added a check to make sure that there + was an inferior or a core file. + + * expread.y (yylex): Allow floating point numbers of the form ".5" + to be parsed. + + Changes by David Taylor at TMC: + * ns32k-pinsn.c: Added define for ?floating point coprocessor? and + tables for register names to be used for each of the possibilities. + (list_search): Created; searches a list of options for a specific + value. + (print_insn_arg): Added 'Q', 'b', 'M', 'P', 'g', and 'G' options + to the value location switch. + * ns32k-opcode.h: Added several new location flags. + [addr, enter, exit, ext[bwd], exts[bwd], lmr, lpr[bwd], restore, + rett, spr[bwd], smr]: Improved insn format output. + + * symtab.c (list_symbols): Rearrange printing to produce readable + output for "info types". + + * eval.c (evaluate_subexp_for_address): Fixed typo. + + * dbxread.c (read_type): Don't output an error message when + there isn't a ',' after a cross-reference. + + * dbxread.c (read_dbx_symtab): #if'd out N_FN case in + read_dbx_symtab if it has the EXT bit set (otherwise multiple + cases with the same value). + +Fri Jun 23 13:12:08 1989 Randall Smith (randy at plantaris.ai.mit.edu) + + * symmisc.c: Changed decl of print_spaces from static to extern + (since it's defined in utils.c). + + * remote.c (remote_open): Close remote_desc if it's already been + opened. + + * Remote_Makefile, remote_gutils.c, remote_inflow.c, + remote_server.c, remote_utils.c: Combined into remote-multi.shar. + * remote-multi.shar: Created (Vikram Koka's remote stub). + * remote-sa.m68k.shar: Created (Glenn Engel's remcom.c). + * README: Updated to reflect new organization of remote stubs. + + * dbxread.c (read_dbx_symtab): Put an N_FN in with N_FN | N_EXT to + account for those machines which don't use the external bit here. + Sigh. + + * m-symmetry.h: Defined NO_SIGINTERRUPT. + +Thu Jun 22 12:51:37 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * printcmd.c (decode_format): Make sure characters are printed + using a byte size. + + * utils.c (error): Added a terminal_ours here. + + * stack.c (locals_info): Added check for selected frame. + + * dbxread.c (read_type): Checked to make sure that a "," was + actually found in the symbol to end a cross reference. + +Wed Jun 21 10:30:01 1989 Randy Smith (randy at tartarus.uchicago.edu) + + * expread.y (parse_number, [exp]): Allowed for the return of a + number marked as unsigned; this will allow inclusion of unsigned + constants. + + * symtab.h: Put in default definitions for BUILTIN_TYPE_LONGEST + and BUILTIN_TYPE_UNSIGNED_LONGEST. + + * expread.y (parse_number): Will now accept integers suffixed with + a 'u' (though does nothing special with it). + + * valarith.c (value_binop): Added cases to deal with unsigned + arithmetic correctly. + +Tue Jun 20 14:25:54 1989 Randy Smith (randy at tartarus.uchicago.edu) + + * dbxread.c (psymtab_to_symtab_1): Changed reading in info message + to go through printf_filtered. + + * symtab.c (list_symbols): Placed header message after all calls + to psymtab_to_symtab. + + * symtab.c (smash_to_{function, reference, pointer}_type): Carried + attribute of permanence for the type being smashed over the bzero + and allowed any type to point at this one if it is permanent. + + * symtab.c (smash_to_{function, reference, pointer}_type): Fix + typo: check flags of to_type instead of type. + + * m-hp9k320.h: Changed check on __GNU__ predefine to __GNUC__. + + * Makefile: Made MUNCH_DEFINE seperate and based on SYSV_DEFINE; + they aren't the same on hp's. + +Mon Jun 19 17:10:16 1989 Randy Smith (randy at tartarus.uchicago.edu) + + * Makefile: Fixed typo. + + * valops.c (call_function): Error if the inferior has not been + started. + + * ns32k-opcode.h [check[wc], cmpm[bwd], movm[bwd], skpsb]: Fixed + typos. + +Fri Jun 9 16:23:04 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-news.h [NO_SIGINTERRUPT]: Defined. + + * dbxread.c (read_type): Start copy of undefined structure name + past [sue] defining type of cross ref. + + * dbxread.c (process_one_symbol): Changed strchr to index. + + * ns32k-opcode.h, ns32k-pinsn.c: More changes to number of + operands, addition of all of the set condition opcodes, addition + of several flag letters, all patterned after the gas code. + + * ns32k-opcode.h [mov{su,us}[bwd], or[bwd]]: Changed number of + operands from 1 to 2. + +Wed Jun 7 15:04:24 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * symseg.h [TYPE_FLAG_STUB]: Created. + * dbxread.c (read_type): Set flag bit if type is stub. + (cleanup_undefined_types): Don't mark it as a stub if it's been + defined since we first learned about it. + * valprint.c (val_print): Print out a message to that effect if + this type is encountered. + + * symseg.h, symtab.h: Moved the definition of TYPE_FLAG_PERM over + to symseg.h so that all such definitions would be in the same place. + + * valprint.c (val_print): Print out <No data fields> for a + structure if there aren't any. + + * dbxread.c (read_type): Set type name of a cross reference type + to "struct whatever" or something. + +Tue Jun 6 19:40:52 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * breakpoint.c (breakpoint_1): Print out symbolic location of + breakpoints for which there are no debugging symbols. + +Mon Jun 5 15:14:51 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * command.c (help_cmd_list): Made line_size static. + +Sat Jun 3 17:33:45 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * Makefile: Don't include the binutils hp-include directory in the + distribution anymore; refer the users to the binutils distribution. + +Thu Jun 1 16:33:07 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * printcmd.c (disable_display_command): Fixed loop iteration for + no arg case. + + * printcmd.c (disable_display_command): Added from_tty parameter + to function. + + * valops.c (value_of_variable): Call read_var_value with 0 cast to + FRAME instead of CORE_ADDR. + + * eval.c (evaluate_subexp): Corrected number of args passed to + value_subscript (to 2). + + * infrun.c (wait_for_inferior), symtab.c (decode_line_1), + m-convex.h: Changed name of FIRSTLINE_DEBUG_BROKEN to + PROLOGUE_FIRSTLINE_OVERLAP. + + * m-merlin.h: Fixed typo. + * ns32k-opcode.h: Added ns32381 opcodes and "cinv" insn, and fixed + errors in movm[wd], rett, and sfsr. + + * eval.c (evaluate_subexp, evaluate_subexp_for_address), valops.c + (value_zero): Change value_zero over to taking two arguments + instead of three. + + * eval.c (evaluate_subexp) + [OP_VAR_VALUE]: Get correct lval type for AVOID_SIDE_EFFECTS for + all types of symbols. + [BINOP_DIV]: Don't divide if avoiding side effects; just return + an object of the correct type. + [BINOP_REPEAT]: Don't call value_repeat, just allocate a + repeated value. + (evaluete_subexp_for_address) [OP_VAR_VALUE]: Just return a thing + of the right type (after checking to make sure that we are allowed + to take the address of whatever variable has been passed). + +Mon May 29 11:01:02 1989 Randall Smith (randy at galapas.ai.mit.edu) + + * breakpoint.c (until_break_command): Set the breakpoint with a + frame specification so that it won't trip in inferior calls to the + function. Also set things up so that it works based on selected + frame, not current one. + +Sun May 28 15:05:33 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * eval.c (evalue_subexp): Change subscript case to use value_zero + in EVAL_AVOID_SIDE_EFFECTS case. + +Fri May 26 12:03:56 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (read_addl_syms, psymtab_to_symtab): Removed + cleanup_undefined_types; this needs to be done on a symtab basis. + (end_symtab): Called cleanup_undefined_types from here. + (cleanup_undefined_types): No longer uses lookup_symbol (brain + dead idea; oh, well), now it searches through file_symbols. + +Wed May 24 15:52:43 1989 Randall Smith (randy at galapas) + + * source.c (select_source_symtab): Only run through + partial_symtab_list if it exists. + + * coffread.c (read_coff_symtab): Don't unrecord a misc function + when a function symbol is seen for it. + + * expread.y [variable]: Make sure to write a type for memvals if + you don't get a mft you recognize. + +Tue May 23 12:15:57 1989 Randall Smith (randy at plantaris.ai.mit.edu) + + * dbxread.c (read_ofile_symtab, psymtab_to_symtab): Moved cleanup + of undefined types to psymtab_to_symtab. That way it will be + called once for all readins (which will, among other things, + help reduce infinite loops). + + * symtab.h [misc_function_type]: Forced mf_unknown to 0. + * dbxread.c (record_misc_function): Cast enum to unsigned char (to + fit). + * expread.y [variable]: Cast unsigned char back to enum to test. + +Mon May 22 13:08:25 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + Patches by John Gilmore for dealing well with floating point: + * findvar.c (value_from_register, locate_var_value): Used + BYTES_BIG_ENDIAN instead of an inline test. + * m-sparc.h [IEEE_FLOAT]: Created to indicate that the sparc is + IEEE compatible. + * printcmd.c (print_scalar_formatted): Use BYTES_BIG_ENDIAN and + the stream argument for printing; also modify default type for + 'f'. Change handling of invalid floats; changed call syntax for + is_nan. + (print_command): Don't print out anything indicating that + something was recorded on the history list if it wasn't. + * valprint.c (val_print): Fixed to deal properley with new format + of is_nan and unpacking doubles without errors occuring. + (is_nan): Changed argument list and how it figures big endianness + (uses macros). + * values.c (record_latest_value): Return -1 and don't record if + it's an invalid float. + (value_as_double): Changed to use new unpack_double calling + convention. + (unpack_double): Changed not to call error if the float was + invalid; simply to set invp and return. Changed calling syntax. + (unpack_field_as_long, modify_field): Changed to use + BITS_BIG_ENDIAN to determine correct action. + + * m-hp9k320.h [HP_OS_BUG]: Created; deals with problem where a + trap happens after a continue. + * infrun.c (wait_for_inferior): Used. + + * m-convex.h [FIRSTLINE_DEBUG_BROKEN]: Defined a flag to indicate + that the debugging symbols output by the compiler for the first + line of a function were broken. + * infrun.c (wait_for_inferior), symtab.c (decode_line_1): Used. + + * gdb.texinfo [Data, Memory]: Minor cleanups of phrasing. + +Fri May 19 00:16:59 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (add_undefined_type, cleanup_undefined_types): Created + to keep a list of cross references to as yet undefined types. + (read_type): Call add_undefined_type when we run into such a case. + (read_addl_syms, read_ofile_symtab): Call cleanup_undefined_types + when we're done. + + * dbxread.c (psymtab_to_symtab, psymtab_to_symtab_1): Broke + psymtab_to_symtab out into two routines; made sure the string + table was only readin once and the globals were only scanned once, + for any number of dependencies. + +Thu May 18 19:59:18 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-*.h: Defined (or not, as appropriate per machine) + BITS_BIG_ENDIAN, BYTES_BIG_ENDIAN, and WORDS_BIG_ENDIAN. + +Wed May 17 13:37:45 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * main.c (symbol_completion_function): Always complete on result + command list, even if exact match found. If it's really an exact + match, it'll find it again; if there's something longer than it, + it'll get the right result. + + * symtab.c (make_symbol_completion_function): Fixed typo; strcmp + ==> strncmp. + + * dbxread.c (read_dbx_symtab): Change 'G' case to mark symbols as + LOC_EXTERNAL. + + * expread.y [variables]: Changed default type of text symbols to + function returning int so that one can use, eg. strcmp. + + * infrun.c (wait_for_inferior): Include a special flag indicating + that one shouldn't insert the breakpoints on the next step for + returning from a sigtramp and forcing at least one move forward. + + * infrun.c (wait_for_inferior): Change test for nexting into a + function to check for current stack pointer inner than previous + stack pointer. + + * infrun.c (wait_for_inferior): Check for step resume break + address before dealing with normal breakpoints. + + * infrun.c (wait_for_inferior): Added a case to deal with taking + and passing along a signal when single stepping past breakpoints + before inserting breakpoints. + + * infrun.c (wait_for_inferior): Inserted special case to keep + going after taking a signal we are supposed to be taking. + +Tue May 16 12:49:55 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * inflow.c (terminal_ours_1): Cast result of signal to (int + (*)()). + + * gdb.texinfo: Made sure that references to the program were in + upper case. Modify description of the "set prompt" command. + [Running]: Cleaned up introduction. + [Attach]: Cleaned up. + [Stepping]: Change "Proceed" to "Continue running" or "Execute". + Minor cleanup. + [Source Path]: Cleaned up intro. Cleared up distinction between + the executable search path and the source path. Restated effect + of the "directory" command with no arguments. + [Data]: Fixed typos and trivial details. + [Stepping]: Fixed up explanation of "until". + + * source.c (print_source_lines): Print through filter. + + * printcmd.c (x_command): If the format with which to print is + "i", use the address of anything that isn't a pointer instead of + the value. This is for, eg. "x/10i main". + + * gdb.texinfo: Updated last modification date on manual. + +Mon May 15 12:11:33 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * symtab.c (lookup_symtab): Fixed typo (name ==> copy) in call to + lookup_symtab_1. + + * gdb.texinfo: Added documentation for "break [+-]n" and for new + actions of "directory" command (taking multiple directory names at + the same time). + + * m68k-opcode.h: Replaced the version in gdb with an up-to-date + version from the assembler directory. + * m68k-pinsn.c (print_insn_arg): Added cases 'l' & 'L' to switch + to print register lists for movem instructions. + + * dbxread.c, m-convex.h: Moved convex dependent include files over + from dbxread.c to m-convex.h. + + * printcmd.c (disable_display, disable_display_command): Changed + name of first to second, and created first which takes an int as + arg rather than a char pointer. Changed second to use first. + (_initialize_printcmd): Changed to use second as command to call. + (delete_current_display, disable_current_display): Changed name of + first to second, and changed functionality to match. + * infrun.c (normal_stop), main.c (return_to_top_level): Changed to + call disable_current_display. + + * dbxread.c (process_one_symbol, read_dbx_symtab): Changed N_FN to + be N_FN | N_EXT to deal with new Berkeley define; this works with + either the old or the new. + + * Remote_Makefile, remote_gutils.c, remote_inflow.c, + remote_server.c, remote_utils.c: Created. + * Makefile: Included in tag and tar files. + * README: Included a note about them. + + * printcmd.c (print_address): Use find_pc_partial_function to + remove need to readin symtabs for symbolic addresses. + + * source.c (directory_command): Replaced function with new one + that can accept lists of directories seperated by spaces or :'s. + + * inflow.c (new_tty): Replaced calls to dup2 with calls to dup. + +Sun May 14 12:33:16 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * stack.c (args_info): Make sure that you have an inferior or core + file before taking action. + + * ns32k-opcode.h [deiw, deid]: Fixed machine code values for these + opcodes. + + * dbxread.c (scan_file_globals): Modified to use misc function + vector instead of file itself. Killed all arguments to the + funciton; no longer needed. + (psymtab_to_symtab): Changed call for above to reflect new (void) + argument list. + + * dbxread.c (read_dbx_symtab, ): Moved HASH_OFFSET define out of + read_dbx_symtab. + + * expread.y [variable]: Changed default type of misc function in + text space to be (void ()). + + * Makefile: Modified for proper number of s/r conflicts (order is + confusing; the mod that necessitated this change was on May 12th, + not today). + + * expread.y (yylex): Added SIGNED, LONG, SHORT, and INT keywords. + [typename]: Created. + [typebase]: Added rules for LONG, LONG INT, SHORT, SHORT INT, + SIGNED name, and UNSIGNED name (a good approximation of ansi + standard). + + * Makefile: Included .c.o rule to avoid sun's make from throwing + any curves at us. + + * blockframe.c: Included <obstack.h> + + * command.c (lookup_cmd): Clear out trailing whitespace. + + * command.c (lookup_cmd_1): Changed malloc to alloca. + +Fri May 12 12:13:12 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * printcmd.c (print_frame_args): Only print nameless args when you + know how many args there are supposed to be and when you've + printed fewer than them. Don't print nameless args between + printed args. + + * symtab.c (make_symbol_completion_function): Fixed typo (= ==> + ==). + + * remote.c (remote_open): ifdef'd out siginterrupt call by #ifndef + NO_SIGINTERRUPT. + * m-umax.h: Defined NO_SIGINTERRUPT. + + * expread.y [ptype, array_mod, func_mod, direct_abs_decl, + abs_decl]: Added rules for parsing and creating arbitrarily + strange types for casts and sizeofs. + + * symtab.c, symtab.h (create_array_type): Created. Some minor + misfeatures; see comments for details (main one being that you + might end up creating two arrays when you only needed one). + +Thu May 11 13:11:49 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * valops.c (value_zero): Add an argument for type of lval. + * eval.c (evaluate_subexp_for_address): Take address properly in + the avoid side affects case (ie. keep track of whether we have an + lval in memory and we can take the address). + (evaluate_subexp): Set the lval type of expressions created with + value_zero properley. + + * valops.c, value.h (value_zero): Created--will return a value of + any type with contents filled with zero. + * symtab.c, symtab.h (lookup_struct_elt_type): Created. + * eval.c (evaluate_subexp): Modified to not read memory when + called with EVAL_AVOID_SIDE_EFFECTS. + + * Makefile: Moved dbxread.c ahead of coffread.c in the list of + source files. + +Wed May 10 11:29:19 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * munch: Make sure that sysv version substitutes for the whole + line. + + * symtab.h: Created an enum misc_function_type to hold the type of + the misc function being recorded. + * dbxread.c (record_misc_function): Branched on dbx symbols to + decide which type to assign to a misc function. + * coffread.c (record_misc_function): Always assign type unknown. + * expread.y [variable]: Now tests based on new values. + +Tue May 9 13:03:54 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * symtab.c: Changed inclusion of <strings.h> (doesn't work on + SYSV) to declaration of index. + + * Makefile: Changed last couple of READLINE_FLAGS SYSV_DEFINE + + * source.c ({forward, reverse}_search_command): Made a default + search file similar to for the list command. + +Mon May 8 18:07:51 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * printcmd.c (print_frame_args): If we don't know how many + arguments there are to this function, don't print the nameless + arguments. We don't know enough to find them. + + * printcmd.c (print_frame_args): Call print_frame_nameless_args + with proper arguments (start & end as offsets from addr). + + * dbxread.c (read_addl_syms): Removed cases to deal with global + symbols; this should all be done in scan_global_symbols. + +Sun May 7 11:36:23 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * Makefile: Added copying.awk to ${OTHERS}. + +Fri May 5 16:49:01 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * valprint.c (type_print_varspec_prefix): Don't pass + passed_a_pointer onto children. + + * valprint.c (type_print_varspec_suffix): Print "array of" with + whatever the "of" is after tha array brackets. + + * valprint.c (type_print_varspec_{prefix,suffix}): Arrange to + parenthesisze pointers to arrays as well as pointers to other + objects. + + * valprint.c (type_print_varspec_suffix): Make sure to print + subscripts of multi-dimensional arrays in the right order. + + * infcmd.c (run_command): Fixed improper usages of variables + within remote debugging branch. + + * Makefile: Added Convex.notes to the list of extra files to carry + around. + + * dbxread.c (symbol_file_command): Made use of alloca or malloc + dependent on macro define. + +Thu May 4 15:47:04 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * Makefile: Changed READLINE_FLAGS to SYSV_DEFINE and called munch + with it also. + * munch: Check first argument for -DSYSV and be looser about + picking up init routines if you find it. + + * coffread.c: Made fclose be of type int. + + * breakpoint.c (_initialize_breakpoint): Put "unset" into class + alias. + +Wed May 3 14:09:12 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-sparc.h [STACK_END_ADDR]: Parameterized off of + machine/vmparam.h (as per John Gilmore's suggestion). + + * blockframe.c (get_prev_frame_info): Changed this function back + to checking frameless invocation first before checking frame + chain. This means that a backtrace up from start will produce the + wrong value, but that a backtrace from a frameless function called + in main will show up correctly. + + * breakpoint.c (_initialize_breakpoint): Added entry in help for + delete that indicates that unset is an alias for it. + + * main.c (symbol_completion_function): Modified recognition of + being within a single command. + +Tue May 2 15:13:45 1989 Randy Smith (randy at gnu) + + * expread.y [variable]: Add some parens to get checking of the + misc function vector right. + +Mon May 1 13:07:03 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * default-dep.c (core_file_command): Made reg_offset unsigned. + + * default-dep.c (core_file_command): Improved error messages for + reading in registers. + + * expread.y: Allowed a BLOCKNAME to be ok for a variable name (as + per C syntax). + + * dbxread.c (psymtab_to_symtab): Flushed stdout after printing + starting message about reading in symbols. + + * printcmd.c (print_frame_args): Switched starting place for + printing of frameless args to be sizeof int above last real arg + printed. + + * printcmd.c (print_frame_args): Modified final call to + print_nameless_args to not use frame slots used array if none had + been used. + + * infrun.c (wait_for_inferior): Take FUNCTION_START_OFFSET into + account when dealing with comparison of pc values to function + addresses. + + * Makefile: Added note about compiling gdb on a Vax running 4.3. + +Sun Apr 30 12:59:46 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * command.c (lookup_cmd): Got correct error message on bad + command. + + * m-sun3.h [ABOUT_TO_RETURN]: Modified to allow any of the return + instructions, including trapv and return from interupt. + + * command.c (lookup_cmd): If a command is found, use it's values + for error reporting and determination of needed subcommands. + + * command.c (lookup_cmd): Use null string for error if cmdtype is + null; pass *line to error instead of **. + + * command.c (lookup_cmd_1): End of command marked by anything but + alpha numeric or '-'. Included ctype.h. + +Fri Apr 28 18:30:49 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * source.c (select_source_symtab): Kept line number from ever + being less than 1 in main decode. + +Wed Apr 26 13:03:20 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * default-dep.c (core_file_command): Fixed typo. + + * utils.c (fprintf_filtered): Don't use return value from + numchars. + + * main.c, command.c (complete_on_cmdlist): Moved function to + command.c. + + * command.c (lookup_cmd): Modified to use my new routine. Old + version is still there, ifdef'd out. + + * command.c, command.h (lookup_cmd_1): Added a routine to do all + of the work of lookup_cmd with no error reporting and full return + of information garnered in search. + +Tue Apr 25 12:37:54 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * breakpoint.c (_initialize_breakpoint): Change "delete + breakpionts" to be in class alias and not have the abbrev flag + set. + + * main.c (symbol_completion_function): Fix to correctly complete + things that correspond to multiword aliases. + + * main.c (complete_on_cmdlist): Don't complete on something if it + isn't a command or prefix (ie. if it's just a help topic). + + * main.c (symbol_completion_function): Set list index to be 0 if + creating a list with just one element. + + * main.c (complete_on_cmdlist): Don't allow things with + abbrev_flag set to be completion values. + (symbol_completion_function): Don't accept an exact match if the + abbrev flag is set. + + * dbxread.c (read_type): Fixed typo in comparision to check if + type number existed. + + * dbxread.c (read_type): Made sure to only call dbx_lookup_type on + typenums if typenums were not -1. + +Mon Apr 24 17:52:12 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * symtab.c: Added strings.h as an include file. + +Fri Apr 21 15:28:38 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * symtab.c (lookup_partial_symtab): Changed to only return a match + if the name match is exact (which is what I want in all cases in + which this is currently used. + +Thu Apr 20 11:12:34 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * m-isi.h [REGISTER_U_ADDR]: Installed new version from net. + * default-dep.c: Deleted inclusion of fcntl.h; apparently not + necessary. + * Makefile: Added comment about compiling on isi under 4.3. + + * breakpoint.c (break_command_1): Only give decode_line_1 the + default_breakpoint_defaults if there's nothing better (ie. make + the default be off of the current_source notes if at all + possible). + + * blockframe.c (get_prev_frame_info): Clean up comments and + delete code ifdefed out around FRAMELESS_FUNCTION_INVOCATION test. + + * remote.c: Added a "?" message to protocol. + (remote_open): Used at startup. + (putpkt): Read whatever garbage comes over the line until we see a + '+' (ie. don't treat garbage as a timeout). + + * valops.c (call_function): Eliminated no longer appropriate + comment. + + * infrun.c (wait_for_inferior): Changed several convex conditional + compilations to be conditional on CANNOT_EXECUTE_STACK. + +Wed Apr 19 10:18:17 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * printcmd.c (print_frame_args): Added code to attempt to deal + with arguments that are bigger than an int. + + Continuation of Convex/Fortran changes: + * printcmd.c (print_scalar_formatted): Added leading zeros to + printing of large integers. + (address_info, print_frame_args): Added code to deal with + LOC_REF_ARG. + (print_nameless_args): Allow param file to specify a routine with + which to print typeless integers. + (printf_command): Deal with long long values well. + * stack.c (print_frame_arg_vars): Change to deal with LOC_REF_ARG. + * symmisc.c (print_symbol): Change to deal with LOC_REF_ARG. + * symseg.h: Added LOC_REF_ARG to enum address_class. + * symtab.c (lookup_block_symbol): Changed to deal with + LOC_REF_ARG. + * valarith.c (value_subscripted_rvalue): Created. + (value_subscript): Used above when app. + (value_less, value_equal): Change to cast to (char *) before doing + comparison, for machines where that casting does something. + * valops.c (call_function): Setup to deal with machines where you + cannot execute code on the stack segment. + * valprint.c (val_print): Make sure that array element size isn't + zero before printing. Set address of default array to address of + first element. Put in a couple of int cast. Removed some convex + specific code. Added check for endianness of machine in case of a + packed structure. Added code for printing typeless integers and + for LONG LONG's. + (set_maximum_command): Change to use parse_and_eval_address to get + argument (so can use expressions there). + * values.c (value_of_internalvar, set_internalvar_component, + set_internalvar, convenience_info): Add in hooks for trapped + internal vars. + (unpack_long): Deal with LONG_LONG. + (value_field): Remove LONGEST cast. + (using_struct_return): Fixed typo ENUM ==> UNION. + * xgdb.c (_initialize_xgdb): Make sure that specify_exec_file_hook + is not called unless we are setting up a windowing environ. + +Tue Apr 18 13:43:37 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + Various changes involved in 1) getting gdb to work on the convex, + and 2) Getting gdb to work with fortran (due to convex!csmith): + * convex-dep.c, convex-opcode.h, m-convex.h, convex-pinsn.c: + Created (or replaced with new files). + * Makefile: Add convex dependent files. Changed default flags to + gnu malloc to be CFLAGS. + * config.gdb: Added convex to list of machines. + * core.c (files_info): Added a FILES_INFO_HOOK to be used if + defined. + (xfer_core_file): Conditionalized compilation of xfer_core_file on + the macro XFER_CORE_FILE. + * coffread.c (record_misc_function): Made sure it zerod type field + (which is now being used; see next). + * dbxread.c: Included some convex dependent include files. + (copy_pending, fix_common_blocks): Created. + [STAB_REG_REGNUM, BELIEVE_PCC_PROMOTION]: Created default values; + may be overridden in m-*.h. + Included data structures for keeping track of common blocks. + (dbx_alloc_type): Modified; if called with negative 1's will + create a type without putting it into the type vector. + (read_dbx_symtab, read_addl_syms): Modified calls to + record_misc_function to include the new information. + (symbol_file_command, psymtab_to_symtab, add_file_command): + Modified reading in of string table to adapt to machines which + *don't* store the size of the string table in the first four bytes + of the string table. + (read_dbx_symtab, scan_file_globals, read_ofile_symtab, + read_addl_syms): Modified assignment of namestring to accept null + index into symtab as ok. + (read_addl_syms): Modified readin of a new object file to fiddle + with common blocks correctly. + (process_one_symbol): Fixed incorrect comment about convex. Get + symbols local to a lexical context from correct spot on a per + machine basis. Catch a bug in pcc which occaisionally puts an SO + where there should be an SOL. Seperate sections for N_BCOMM & + N_ECOMM. + (define_symbol): Ignore symbols with no ":". Use + STAB_REG_TO_REGNUM. Added support for function args calling by + reference. + (read_type): Only read type number if one is there. Remove old + (#if 0'd out) array code. + (read_array_type): Added code for dealing with adjustable (by + parameter) arrays half-heartedly. + (read_enum_type): Allow a ',' to end a list of values. + (read_range_type): Added code to check for long long. + * expread.y: Modified to use LONGEST instead of long where + necessary. Modified to use a default type of int for objects that + weren't in text space. + * findvar.c (locate_var_value, read_var_value): Modified to deal + with args passed by reference. + * inflow.c (create_inferior): Used CREATE_INFERIOR_HOOK if it + exists. + * infrun.c (attach_program): Run terminal inferior when attaching. + (wait_for_inferior): Removed several convex dependencies. + * main.c (float_handler): Created. + Made whatever signal indicates a stop configurable (via macro + STOP_SIGNAL). + (main): Setup use of above as a signal handler. Added check for + "-nw" in args already processed. + (command_line_input): SIGTSTP ==>STOP_SIGNAL. + + * expread.y: Added token BLOCKNAME to remove reduce/reduce + conflict. + * Makefile: Change message to reflect new grammar. + +Mon Apr 17 13:24:59 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * printcmd.c (compare_ints): Created. + (print_frame_args): Modified to always print arguments in the + order in which they were found in the symbol table. Figure out + what apots are missing on the fly. + + * stack.c (up_command): Error if no inferior or core file. + + * m-i386.h, m-symmetry.h [FRAMELESS_FUNCTION_INVOCATION]: Created; + same as m68k. + + * dbxread.c (define_symbol): Changed "desc==0" test to + "processing_gcc_compilation", which is the correct way to do it. + +Sat Apr 15 17:18:38 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * expread.y: Added precedence rules for arglists, ?:, and sizeof + to eliminate some shift-reduce conflicts. + * Makefile: Modified "Expect" message to conform to new results. + +Thu Apr 13 12:29:26 1989 Randall Smith (randy at plantaris.ai.mit.edu) + + * inflow.c (terminal_init_inferior): Fixed typo in recent diff + installation; TIOGETC ==> TIOCGETC. + + * m-vax.h, m-sun2.h, m-sun3.h, m-sparc.h, m-hp*.h, m-isi.h, + m-news.h [FRAMELESS_FUNCTION_INVOCATION]: Created macro with + appropriate definition. + +Wed Apr 12 15:30:29 1989 Randall Smith (randy at plantaris.ai.mit.edu) + + * blockframe.c (get_prev_frame_info): Added in a macro to specify + when a "frame" is called without a frame pointer being setup. + + * Makefile [clean]: Made sure to delete gnu malloc if it was being + used. + +Mon Apr 10 12:43:49 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (process_one_symbol): Reset within_function to 0 after + last RBRAC of a function. + + * dbxread.c (read_struct_type): Changed check for filling in of + TYPE_MAIN_VARIANT of type. + + * inflow.c (create_inferior): Conditionalized fork so that it + would be used if USG was defined and HAVE_VFORK was not defined. + + * defs.h: Added comment about enum command_class element + class_alias. + + * dbxread.c (process_one_symbol): Fixed a typo with interesting + implications for associative processing in the brain (':' ==> 'c'). + + * sparc-dep.c (isabranch): Changed name to isannulled, modified to + deal with coprocessor branches, and improved comment. + (single_step): Changed to trap at npc + 4 instead of pc +8 on + annulled branches. Changed name in call to isabranch as above. + + * m-sun4os4.h (STACK_END_ADDRESS): Changed it to 0xf8000000 under + os 4.0. + +Sat Apr 8 17:04:07 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (process_one_symbol): In the case N_FUN or N_FNAME the + value being refered to is sometimes just a text segment variable. + Catch this case. + + * infrun.c (wait_for_inferior), breakpoint.c + (breakpoint_stop_status): Move the selection of the frame to + inside breakpoint_stop_status so that the frame only gets selected + (and the symbols potentially read in) if the symbols are needed. + + * symtab.c (find_pc_psymbol): Fixed minor misthough (pc >= + fucntion start, not >). + + * breakpoint.c (_initialize_breakpoint): Change "delete" internal + help entry to simply refer to it being a prefix command (since the + list of subcommands is right there on a "help delete"). + +Fri Apr 7 15:22:18 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * blockframe.c (find_pc_partial_function): Created; figures out + what function pc is in (name and address) without reading in any + new symbols. + * symtab.h: Added decl for above. + * infrun.c (wait_for_inferior): Used instead of + find_pc_function_start. + * stack.c (print_frame_info): Used instead of hand coding for same + thing. + + * dbxread.c (psymtab_to_symtab): No longer patch readin pst's out + of the partial_symtab_list; need them there for some checks. + * blockframe.c (block_for_pc), source.c (select_source_symtab), + symtab.c (lookup_symbol, find_pc_symtab, list_symbols): Made extra + sure not to call psymtab_to_symtab with ->readin == 1, since these + psymtab now stay on the list. + * symtab.c (sources_info): Now distinguishes between psymtabs with + readin set and those with it not set. + + * symtab.c (lookup_symtab): Added check through partial symtabs + for name with .c appended. + + * source.c (select_source_symtab): Changed semantics a little so + that the argument means something. + * source.c (list_command), symtab.c (decode_line_1): Changed call + to select_source_symtab to match new conventions. + + * dbxread.c (add_file_command): This command no longer selects a + symbol table to list from. + + * infrun.c (wait_for_inferior): Only call find_pc_function (to + find out if we have debugging symbols for a function and hence if + we should step over or into it) if we are doing a "step". + +Thu Apr 6 12:42:28 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * main.c (command_line_input): Added a local buffer and only + copied information into the global main.c buffer when it is + appropriate for it to be saved (and repeated). + (dont_repeat): Only nail line when we are reading from stdin + (otherwise null lines won't repeat and what's in line needs to be + saved). + (read_command_lines): Fixed typo; you don't what to repeat when + reading command lines from the input stream unless it's standard + input. + + John Gilmore's (gnu@toad.com) mods for USG gdb: + * inflow.c: Removed inclusion of sys/user.h; no longer necessary. + (, terminal_init_inferior, terminal_inferior, terminal_ours_1, + term_status_command, _initialize_inflow) Seperated out declaration + and usage of terminal mode structures based on the existence of + the individual ioctls. + * utils.c (request_quit): Restore signal handler under USG. If + running under USG initialize sys_siglist at run time (too much + variation between systems). + +Wed Apr 5 13:47:24 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + John Gilmore's (gnu@toad.com) mods for USG gdb: + * default-dep.c: Moved include of sys/user.h to after include of + a.out.h. + (store_inferior_registers): Fixed error message. + (core_file_command): Improved error messages from reading in of + u area in core file. Changed calculation of offset of registers + to account for some machines putting it in as an offset rather + than an absolute address. Changed error messages for reading of + registers from core file. + + * coffread.c (read_file_hdr): Added final check for BADMAG macro + to use if couldn't recognize magic number. + * Makefile: Added explicit directions for alloca addition. + Included alloca.c in list of possible library files. Cleaned up + possible library usage. Included additional information on gcc + and include files. + + * source.c, remote.c, inflow.c, dbxread.c, core.c, coffread.c: + Changed include of sys/fcntl.h to an include of fcntl.h (as per + posix; presumably this will break fewer machines. I hopw). + * README: Added a pointer to comments at top of Makefile. + * Makefile: Added a comment about machines which need fcntl.h in + sys. + +Tue Apr 4 11:29:04 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * valprint.c (set_prettyprint_command, set_unionprint_command, + format_info): Created. + (_initialize_valprint): Added to lists of commands. + + * gdb.texinfo [Backtrace]: Added a section describing the format + if symbols have not yet been read in. + + * valprint.c (val_print): Added code to prettyprint structures if + "prettyprint" is set and only to print unions below the top level + if "unionprint" is set. + + * infcmd.c (registers_info), valprint.c (value_print, val_print): + Added argument to call to val_print indicating deptch of recursion. + + * symtab.[ch] (find_pc_psymbol): Created; finds static function + psymbol with value nearest to but under value passed. + * stack.c (print_frame_info): Used above to make sure I have best + fit to pc value. + + * symseg.h (struct partial_symbol): Added value field. + * dbxread.c (read_dbx_symtab): Set value field for partial symbols + saved (so that we can lookup static symbols). + + * symtab.[ch] (find_pc_symtab): Changed to external. + * stack.c (select_frame): Call above to make sure that symbols for + a selected frame is readin. + +Mon Apr 3 12:48:16 1989 Randall Smith (randy at plantaris.ai.mit.edu) + + * stack.c (print_frame_info): Modified to only print out full + stack frame info on symbols whose tables have been read in. + * symtab.c, symtab.h (find_pc_psymtab): Made function external; + above needed it. + + * main.c (,set_verbose_command, initialize_main): Created a + variable "info_verbose" which says to talk it up in various and + sundry places. Added command to set this variable. + * gdb.texinfo (GDB Output): Added documentation on "set verbose" + and changed the name of the "Screen Output" section to "GDB + Output". + * dbxread.c (psymtab_to_symtab): Added information message about + symbol readin. Conditionalized on above. + + * dbxread.c (define_symbol): Made an "i" constant be of class + LOC_CONST and an "r" constant be of class LOC_CONST_BYTES. + + * README: Made a note about modifications which may be necessary + to the manual for this version of gdb. + + * blockframe.c (get_prev_frame_info): Now we get saved address and + check for validity before we check for leafism. This means that + we will catch the fact that we are in start, but we will miss any + fns that start calls without an fp. This should be fine. + + * m-*.h (FRAME_CHAIN): Modified to return 0 if we are in start. + This is usually a test for within the first object file. + * m-sparc.h (FRAME_CHAIN): The test here is simply if the fp saved + off the the start sp is 0. + + * blockframe.c (get_prev_frame_info): Removed check to see if we + were in start. Screws up sparc. + + * m-sparc.h (FRAME_FIND_SAVED_REGISTERS): Changed test for dummy + frame to not need frame to be innermost. + + * gdb.texinfo: Added section on frameless invocations of functions + and when gdb can and can't deal with this. + + * stack.c (frame_info): Disallowed call if no inferior or core + file; fails gracefully if truely bad stack specfication has been + given (ie. parse_frame_specification returns 0). + +Fri Mar 31 13:59:33 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * infrun.c (normal_stop): Changed references to "unset-env" to + "delete env". + + * infcmd.c (_initialize_infcmd): Change reference to set-args in + help run to "set args". + + * remote.c (getpkt): Allow immediate quit when reading from + device; it could be hung. + + * coffread.c (process_coff_symbol): Modify handling of REG + parameter symbols. + +Thu Mar 30 15:27:23 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (symbol_file_command): Use malloc to allocate the + space for the string table in symbol_file_command (and setup a + cleanup for this). This allows a more graceful error failure if + there isn't any memory availible (and probably allows more memory + to be avail, depending on the machine). + + Additional mods for handling GNU C++ (from Tiemann): + * dbxread.c (read_type): Added case for '#' type (method type, I + believe). + (read_struct_type): If type code is undefined, make the main + variant for the type be itself. Allow recognition of bad format + in reading of structure fields. + * eval.c (evaluate_subexp): Modify evaluation of a member of a + structure and pointer to same to make sure that the syntax is + being used correctly and that the member is being accessed correctly. + * symseg.h: Added TYPE_CODE_METHOD to enum type_code. Add a + pointer to an array of argument types to the type structure. + * symtab.c (lookout_method_type, smash_to_method_type): Created. + * symtab.h (TYPE_ARG_TYPES): Created. + * valops.c (call_function): Modified handling of methods to be the + same as handling of functions; no longer check for members. + * valprint.c (val_print, type_print_varspec_{prefix,suffix}, + type_print_base): Added code to print method args correctly. + * values.c (value_virtual_fn_field): Modify access to virtual + function table. + +Wed Mar 29 13:19:34 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * findvar.c: Special cases for REGISTER_WINDOWS: 1) Return 0 if we + are the innermost frame, and 2) return the next frame in's value + if the SP is being looked for. + + * blockframe.c (get_next_frame): Created; returns the next (inner) + frame of the called frame. + * frame.h: Extern delcaration for above. + + * main.c (command_line_input): Stick null at end before doing + history expansion. + +Tue Mar 28 17:35:50 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (read_dbx_symtab): Added namestring assignment to + N_DATA/BSS/ABS case. Sigh. + +Sat Mar 25 17:49:07 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * expread.y: Defined YYDEBUG. + +Fri Mar 24 20:46:55 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * symtab.c (make_symbol_completion_list): Completely rewrote to + never call psymtab_to_symtab, to do a correct search (no + duplicates) through the visible symbols, and to include structure + and union fields in the things that it can match. + +Thu Mar 23 15:27:44 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (dbx_create_type): Created; allocates and inits space + for a type without putting it on the type vector lists. + (dbx_alloc_type): Uses above. + + * Makefile: xgdb.o now produced by default rules for .o.c. + +Fri Mar 17 14:27:50 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * infrun.c: Fixed up inclusion of aouthdr.h on UMAX_PTRACE. + + * Makefile, config.gdb: Added hp300bsd to potential + configurations. + * hp300bsd-dep.c, m-hp300bsd.h: Created. + + * infrun.c (wait_for_inferior): Rewrote to do no access to + inferior until we make sure it's still there. + + * inflow.c (inferior_died): Added a select to force the selected + frame to null when inferior dies. + + * dbxread.c (symbol_file_command): free and zero symfile when + discarding symbols. + + * core.c (xfer_core_file): Extended and cleaned up logic in + interpeting memory address. + + * core.c (xfer_core_file): Extended opening comment. + +Thu Mar 16 15:39:42 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * coffread.c (symbol_file_command): Free symfile name when freeing + contents. + + * blockframe.c (get_prev_frame_info): Added to fatal error message + to indicate that it should never happen. + + * stack.c (frame_info): Printed out value of "saved" sp seperately + to call attention to the fact that it isn't stored in memory + anywhere; the actual previous frames address is printed. + + * m-sparc.h (FRAME_FIND_SAVED_REGS): Set address of sp saved in + frame to value of fp (rather than value of sp in current frame). + + * expread.y: Allow "unsigned" as a type itself, as well as a type + modifier. + + * coffread.c: Added declaration for fclose + +Fri Mar 10 17:22:31 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * main.c (command_line_input): Checked for -1 return from + readline; indicates EOF. + +Fri Mar 3 00:31:27 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * remote.c (remote_open): Cast return from signal to (void (*)) to + avoid problems on machines where the return type of signal is (int + (*)). + + * Makefile: Removed deletion of version control from it (users + will need it for their changes). + +Thu Mar 2 15:32:21 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * symmetry-dep.c (print_1167_regs): Print out effective doubles on + even number regs. + (fetch_inferior_registers): Get the floating point regs also. + + * xgdb.c (do_command): Copied command before calling execute + command (so that execute_command wouldn't write into text space). + + * copying.awk: Created (will produce copying.c as output when + given COPYING as input). + * Makefile: Used above to create copying.c. + * main.c: Took out info_warranty and info_copying. + + * *.*: Changed copyright notice to use new GNU General Public + License (includes necessary changes to manual). + + * xgdb.c (create_text_widget): Created text_widget before I create + the source and sink. + (print_prompt): Added fflush (stdout). + + * Makefile: Added -lXmu to the compilation line for xgdb. Left + the old one there incase people still had R2. + + * README: Added note about -gg format. + + * remote.c (getpkt): Fixed typo; && ==> &. + + * Makefile: Added new variable READLINE_FLAGS so that I could + force compilation of readline.c and history.c with -DSYSV on + system V machines. Mentioned in Makefile comments at top. + +Wed Mar 1 17:01:01 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * hp9k320-dep.c (store_inferior_registers): Fixed typo. + +Fri Feb 24 14:58:45 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * hp9k320-dep.c (store_inferior_registers, + fetch_inferior_registers): Added support for remote debugging. + + * remote.c (remote_timer): Created. + (remote_open, readchar): Setup to timeout reads if they take + longer than "timeout". This allows one to debug how long such + things take. + (putpkt): Modified to print a debugging message (if such things + are enabled) each time it resends a packet. + (getpkt): Modified to make the variable CSUM unsigned and read it + CSUM with an & 0xff (presumably to deal with poor sign extension + on some machines). Also made c1 and c2 unsigned. + (remote_wait): Changed buffer to unsigned status. + (remote_store_registers, remote_write_bytes): Puts a null byte at + the end of the control string. + + * infcmd.c (attach_command, detach_command, _initialize_infcmd): + Made attach_command and detach_command always availible, but + modified them to only allow device file attaches if ATTACH_DETACH + is not defined. + + * gdb.texinfo: Added cross reference from attach command to remote + debugging. + +Thu Feb 23 12:37:59 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * remote.c (remote_close): Created to close the remote connection + and set the remote_debugging flag to 0. + * infcmd.c (detach_command): Now calls the above when appropriate. + + * gdb.texinfo: Removed references to the ``Distribution'' section + in the copyright. + + * main.c, utils.c (ISATTY): Created default defintions of this + macro which use isatty and fileno. + * utils.c (fprintf_filtered, print_spaces_filtered), main.c + (command_loop, command_line_input): Used this macro. + * m-news.h: Created a definition to override this one. + + * utils.c (fprintf_filtered): Made line_size static (clueless). + + * utils.c (fprintf_filtered): Changed max length of line printed + to be 255 chars or twice the format length. + + * symmetry-dep.c, m-symmetry: Fixed typo (^L ==> ). + + * printcmd.c (do_examine): Fixed typo (\n ==> \t). + +Wed Feb 22 16:00:33 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + Contributed by Jay Vosburgh (jay@mentor.cc.purdue.edu) + * m-symmetry.h, symmetry-dep.c: Created. + * Makefile: Added above in appropriate lists. + * config.gdb: Added "symmetry" target. + + * utils.c (prompt_for_continue): Zero'd chars_printed also. + + * utils.c (fprintf_filtered): Call prompt for continue instead of + doing it yourself. + + * dbxread.c (read_dbx_symtab): Added code to conditionalize what + symbol type holds to "x.o" or "-lx" symbol that indicates the + beginning of a new file. + +Tue Feb 21 16:22:13 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * gdb.texinfo: Deleted @ignore block at end of file. + + * findvar.c, stack.c: Changed comments that refered to "frame + address" to "frame id". + + * findvar.c (locate_var_value): Modified so that taking the + address of an array generates an object whose type is a pointer to + the elements of the array. + +Sat Feb 18 16:35:14 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * gdb.texinfo: Removed reference to "!" as a shell escape + character. Added a section on controling screen output + (pagination); changing "Input" section to "User Interface" + section. Changed many inappropriate subsubsection nodes into + subsections nodes (in the readline and history expansion + sections). + +Fri Feb 17 11:10:54 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * utils.c (set_screensize_command): Created. + (_initialize_utils): Added above to setlist. + + * main.c (main): Added check to see if ~/.gdbinit and .gdbinit + were the same file; only one gets read if so. Had to include + sys/stat.h for this. + + * valprint.c (type_print_base): Changed calls to print_spaces to + print_spaces_filtered. + + * main.c (command_line_input): Chaned test for command line + editing to check for stdin and isatty. + + * main.c (command_loop): Call reinitialize_more_filter before each + command (if reading from stdin and it's a tty). + utils.c (initialize_more_filter): Changed name to + reinitialize_more_filter; killed arguments. + utils.c (_initialize_utils): Created; initialized lines_per_page + and chars_per_line here. + + * utils.c (fprintf_filtered): Removed printing of "\\\n" after + printing linesize - 1 chars; assume that the screen display will + take care of that. Still watching that overflow. + + * main.c: Created the global variables linesize and pagesize to + describe the number of chars per line and lines per page. + +Thu Feb 16 17:27:43 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * printcmd.c (do_examine, print_scalar_formatted, print_address, + whatis_command, do_one_display, ptype_command), valprint.c + (value_print, val_print, type_print_method_args, type_print_1, + type_print_derivation_info, type_print_varspec_suffix, + type_print_base), breakpoint.c (breakpoints_info, breakpoint_1), + values.c (history_info), main.c (editing_info, warranty_info, + copying_info), infcmd.c (registers_info), inflow.c + (term_status_command), infrun.c (signals_info), stack.c + (backtrace_command, print_frame_info), symtab.c (list_symbols, + output_source_filename), command.c (help_cmd, help_list, + help_command_list): Replaced calls to printf, fprintf, and putc + with calls to [f]printf_filtered to handle more processing. + Killed local more emulations where I noticed them. + +Wed Feb 15 15:27:36 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * defs.h, utils.c (initialize_more_filter, fprintf_filtered, + printf_filtered): Created a printf that will also act as a more + filter, prompting the user for a <return> whenever the page length + is overflowed. + + * symtab.c (list_symbols): Elminated some code inside of an #if 0. + +Tue Feb 14 11:11:24 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * Makefile: Turned off backup versions for this file; it changes + too often. + + * command.c (lookup_cmd, _initialize_command): Changed '!' so that + it was no longer a shell escape. "sh" must be used. + + * main.c (command_line_input, set_history_expansion, + initialize_main): Turned history expansion on, made it the + default, and only execute it if the first character in the line is + a '!'. + + * version.c, gdb.texinfo: Moved version to 3.2 (as usual, jumping + the gun some time before release). + + * gdb.texinfo: Added sections (adapted from Brian's notes) on + command line editing and history expansion. + + * main.c (set_command_editing, initialize_main): Modified name to + set_editing and modified command to "set editing". + + * Makefile: Put in dependencies for READLINEOBJS. + + * main.c (history_info, command_info): Combined into new command + info; deleted history_info. + (initialize_main): Deleted "info history" command; it was + interfering with the value history. + + * coffread.c (enter_linenos): Modified to do bit copy instead of + pointer dereference, since the clipper machine can't handle having + longs on short boundaries. + (read_file_hdr): Added code to get number of syms for clipper. + + * stack.c (return_command): Fixed method for checking when all of + the necessary frames had been popped. + + * dbxread.c (read_dbx_symtab (ADD_PSYMBOL_TO_LIST)): Fixed typo in + allocation length. + +Mon Feb 13 10:03:27 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * dbxread.c (read_dbx_symtab): Split assignment to namestring into + several different assignments (so that it wouldn't be done except + when it had to be). Shortened switches and duplicated code to + produce the lowest possible execution time. Commented (at top of + switch) which code I duplicated. + + * dbxread.c (read_dbx_symtab): Modified which variables were + register and deleted several variables which weren't used. Also + eliminated 'F' choice from subswitch, broke out strcmp's, reversed + compare on line 1986, and elminated test for !namestring[0]; it is + caught by following test for null index of ':'. + +Sun Feb 12 12:57:56 1989 Randall Smith (randy at plantaris.ai.mit.edu) + + * main.c (gdb_completer_word_break_characters): Turned \~ into ~. + +Sat Feb 11 15:39:06 1989 Randall Smith (randy at plantaris.ai.mit.edu) + + * symtab.c (find_pc_psymtab): Created; checks all psymtab's till + it finds pc. + (find_pc_symtab): Used; fatal error if psymtab found is readin + (should have been caught in symtab loop). + (lookup_symbol): Added check before scan through partial symtab + list for symbol name to be on the misc function vector (only if in + VAR_NAMESPACE). Also made sure that psymtab's weren't fooled with + if they had already been read in. + (list_symbols): Checked through misc_function_vector for matching + names if we were looking for functions. + (make_symbol_completion_list): Checked through + misc_function_vector for matching names. + * dbxread.c (read_dbx_symtab): Don't bother to do processing on + global function types; this will be taken care of by the + misc_function hack. + + * symtab.h: Modified comment on misc_function structure. + +Fri Feb 10 18:09:33 1989 Randall Smith (randy at plantaris.ai.mit.edu) + + * symseg.h, dbxread.c (read_dbx_symtab, init_psymbol_list, + start_psymtab, end_psymtab), coffread.c (_initialize_coff), + symtab.c (lookup_partial_symbol, list_symbols, + make_symbol_completion_list): Changed separate variables for + description of partial symbol allocation into a specific kind of + structure. + + (read_dbx_symtab, process_symbol_for_psymtab): Moved most of + process_symbol_for_psymtab up into read_dbx_symtab, moved a couple + of symbol types down to the ingore section, streamlined (I hope) + code some, modularized access to psymbol lists. + +Thu Feb 9 13:21:19 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * main.c (command_line_input): Made sure that it could recognize + newlines as indications to repeat the last line. + + * symtab.c (_initialize_symtab): Changed size of builtin_type_void + to be 1 for compatibility with gcc. + + * main.c (initialize_main): Made history_expansion the default + when gdb is compiled with HISTORY_EXPANSION. + + * readline.c, readline.h, history.c, history.h, general.h, + emacs_keymap.c, vi_keymap.c, keymaps.c, funmap.c: Made all of + these links to /gp/gnu/bash/* to keep them updated. + * main.c (initialize_main): Made default be command editing on. + +Wed Feb 8 13:32:04 1989 & Smith (randy at hobbes) + + * dbxread.c (read_dbx_symtab): Ignore N_BSLINE on first + readthrough. + + * Makefile: Removed convex-dep.c from list of distribution files. + +Tue Feb 7 14:06:25 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * main.c: Added command lists sethistlist and unsethistlist to + accesible command lists. + (parse_binary_operation): Created to parse a on/1/yes vs. off/0/no + spec. + (set_command_edit, set_history, set_history_expansion, + set_history_write, set_history_size, set_history_filename, + command_info, history_info): Created to allow users to control + various aspects of command line editing. + + * main.c (symbol_creation_function): Created. + (command_line_input, initialize_main): Added rest of stuff + necessary for calling bfox' command editing routines under + run-time control. + * Makefile: Included readline and history source files for command + editing; also made arrangements to make sure that the termcap + library was available. + * symtab.c (make_symbol_completion_list): Created. + +Mon Feb 6 16:25:25 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * main.c: Invented variables to control command editing. + command_editing_p, history_expansion_p, history_size, + write_history_p, history_filename. Initialized them to default + values in initialize_main. + + * infcmd.c (registers_info), infrun.c (signals_info), + * main.c (gdb_read_line): Changed name to command_line_input. + (readline): Changed name to gdb_readline; added second argument + indicating that the read value shouldn't be saved (via malloc). + * infcmd.c (registers_info), infrun.c (signals_info), main.c + (copying_info), symtab.c (output_source_filename, MORE, + list_symbols): Converted to use gdb_readline in place of + gdb_read_line. + + +Sun Feb 5 17:34:38 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * blockframe.c (get_frame_saved_regs): Removed macro expansion + that had accidentally been left in the code. + +Sat Feb 4 17:54:14 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * main.c (gdb_read_line, readline): Added function readline and + converted gdb_read_line to use it. This was a conversion to the + line at a time style of input, in preparation for full command + editing. + +Fri Feb 3 12:39:03 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (read_dbx_symtab): Call end_psymtab at the end of + read_dbx_symtab if any psymtab still needs to be completed. + + * config.gdb, sun3-dep.c: Brought these into accord with the + actual sun2 status (no floating point period; sun3-dep.c unless + has os > 3.0). + * m-sun2os2.h: Deleted; not needed. + + * config.gdb: Added a couple of aliases for machines in the + script. + + * infrun.c: Added inclusion of aouthdr.h inside of #ifdef UMAX + because ptrace needs to know about the a.out header. + + * Makefile: Made dep.o depend on dep.c and config.status only. + + * expread.y: Added declarations of all of the new write_exp_elt + functions at the include section in the top. + + * Makefile: Added a YACC definition so that people can use bison + if they wish. + + * Makefile: Added rms' XGDB-README to the distribution. + + * Makefile: Added removal of init.o on a "make clean". + +Thu Feb 2 16:27:06 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * *-dep.c: Deleted definition of COFF_FORMAT if AOUTHDR was + defined since 1) We *may* (recent mail message) want to define + AOUTHDR under a basically BSD system, and 2) AOUTHDR is sometimes + a typedef in coff encapsulation setups. Also removed #define's of + AOUTHDR if AOUTHDR is already defined (inside of coff format). + * core.c, dbxread.c: Removed #define's of AOUTHDR if AOUTHDR is + already defined (inside of coff format). + +Tue Jan 31 12:56:01 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * GDB 3.1 released. + + * values.c (modify_field): Changed test for endianness to assign + to integer and reference character (so that all bits would be + defined). + +Mon Jan 30 11:41:21 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * news-dep.c: Deleted inclusion of fcntl.h; just duplicates stuff + found in sys/file.h. + + * i386-dep.c: Included default definition of N_SET_MAGIC for + COFF_FORMAT. + + * config.gdb: Added checks for several different operating + systems. + + * coffread.c (read_struct_type): Put in a flag variable so that + one could tell when you got to the end of a structure. + + * sun3-dep.c (core_file_command): Changed #ifdef based on SUNOS4 + to ifdef based on FPU. + + * infrun.c (restore_inferior_status): Changed error message to + "unable to restore previously selected frame". + + * dbxread.c (read_dbx_symtab): Used intermediate variable in error + message reporting a bad symbol type. (scan_file_globals, + read_ofile_symtab, read_addl_syms): Data type of "type" changed to + unsigned char (which is what it is). + * i386-dep.c: Removed define of COFF_FORMAT if AOUTHDR is defined. + Removed define of a_magic to magic (taken care of by N_MAGIC). + (core_file_command): Zero'd core_aouthdr instead of setting magic + to zero. + * i386-pinsn.c: Changed jcxz == jCcxz in jump table. + (putop): Added a case for 'C'. + (OP_J): Added code to handle possible masking of PC value on + certain kinds of data. + m-i386gas.h: Moved COFF_ENCAPSULATE to before inclusion of + m-i386.h and defined NAMES_HAVE_UNDERSCORE. + + * coffread.c (unrecrod_misc_function, read_coff_symtab): Added + symbol number on which error occured to error output. + +Fri Jan 27 11:55:04 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * Makefile: Removed init.c in make clean. Removed it without -f + and with leading - in make ?gdb. + +Thu Jan 26 15:08:03 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + Changes to get it to work on gould NP1. + * dbxread.c (read_dbx_symtab): Included cases for N_NBDATA and + N_NBBSS. + (psymtab_to_symtab): Changed declaration of hdr to + DECLARE_FILE_HEADERS. Changed access to use STRING_TABLE_SIZE and + SYMBOL_TABLE_SIZE. + * gld-pinsn.c (findframe): Added declaration of framechain() as + FRAME_ADDR. + + * coffread.c (read_coff_symtab): Avoided treating typedefs as + external symbol definitions. + +Wed Jan 25 14:45:43 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * Makefile: Removed reference to alloca.c. If they need it, they + can pull alloca.o from the gnu-emacs directory. + + * version.c, gdb.texinfo: Updated version to 3.1 (jumping the gun + a bit so that I won't forget when I release). + + * m-sun2.h, m-sun2os2.h, m-sun3os4.h, config.gdb: Modified code so + that default includes new sun core, ptrace, and attach-detach. + Added defaults for sun 2 os 2. + + Modifications to reset stack limit back to what it used to be just + before exec. All mods inside of #ifdef SET_STACK_LIMIT_HUGE. + * main.c: Added global variable original_stack_limit. + (main): Set original_stack_limit to original stack limit. + * inflow.c: Added inclusion of necessary files and external + reference to original_stack_limit. + (create_inferior): Reset stack limit to original_stack_limit. + + * dbxread.c (read_dbx_symtab): Killed PROFILE_SYMBOLS ifdef. + + * sparc-dep.c (isabranch): Multiplied offset by 4 before adding it + to addr to get target. + + * Makefile: Added definition of SHELL to Makefile. + + * m-sun2os4.h: Added code to define NEW_SUN_PTRACE, NEW_SUN_CORE, + and ATTACH_DETACH. + * sun3-dep.c: Added code to avoid fp regs if we are on a sun2. + +Tue Jan 24 17:59:14 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (read_array_type): Added function. + (read_type): Added call to above instead of inline code. + + * Makefile: Added ${GNU_MALLOC} to the list of dependencies for + the executables. + +Mon Jan 23 15:08:51 1989 Randall Smith (randy at plantaris.ai.mit.edu) + + * gdb.texinfo: Added paragraph to summary describing languages + with which gdb can be run. Also added descriptions of the + "info-methods" and "add-file" commands. + + * symseg.h: Commented a range type as having TYPE_TARGET_TYPE + pointing at the containing type for the range (often int). + * dbxread.c (read_range_type): Added code to do actual range types + if they are defined. Assumed that the length of a range type is + the length of the target type; this is a lie, but will do until + somebody gets back to me as to what these silly dbx symbols mean. + + * dbxread.c (read_range_type): Added code to be more picky about + recognizing builtins as range types, to treat types defined as + subranges of themselves to be subranges of int, and to recognize + the char type idiom from dbx as a special case. + +Sun Jan 22 01:00:13 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-vax.h: Removed definition of FUNCTION_HAS_FRAME_POINTER. + * blockframe.c (get_prev_frame_info): Removed default definition + and use of above. Instead conditionalized checking for leaf nodes + on FUNCTION_START_OFFSET (see comment in code). + +Sat Jan 21 16:59:19 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (read_range_type): Fixed assumption that integer was + always type 1. + + * gdb.texinfo: Fixed spelling mistake and added a note in the + running section making it clear that users may invoke subroutines + directly from gdb. + + * blockframe.c: Setup a default definition for the macro + FUNCTION_HAS_FRAME_POINTER. + (get_prev_frame_info): Used this macro instead of checking + SKIP_PROLOGUE directly. + * m-vax.h: Overroad definition; all functions on the vax have + frame pointers. + +Fri Jan 20 12:25:35 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * core.c: Added default definition of N_MAGIC for COFF_FORMAT. + + * xgdb.c: Installed a fix to keep the thing from dying when there + isn't any frame selected. + + * core.c: Made a change for the UMAX system; needs a different + file included if using that core format. + + * Makefile: Deleted duplicate obstack.h in dbxread.c dependency. + + * munch: Modified (much simpler) to cover (I hope) all cases. + + * utils.c (save_cleanups, restore_cleanups): Added functions to + allow you to push and pop the chain of cleanups to be done. + * defs.h: Declared the new functions. + * main.c (catch_errors): Made sure that the only cleanups which + would be done were the ones put on the chain *after* the current + location. + + * m-*.h (FRAME_CHAIN_VALID): Removed check on pc in the current + frame being valid. + * blockframe.c (get_prev_frame_info): Made the assumption that if + a frame's pc value was within the first object file (presumed to + be /lib/crt0.o), that we shouldn't go any higher. + + * infrun.c (wait_for_inferior): Do *not* execute check for stop pc + at step_resume_break if we are proceeding over a breakpoint (ie. + if trap_expected != 0). + + * Makefile: Added -g to LDFLAGS. + + * m-news.h (POP_FRAME) Fixed typo. + + * printcmd.c (print_frame_args): Modified to print out register + params in order by .stabs entry, not by register number. + + * sparc-opcode.h: Changed declaration of (struct + arith_imm_fmt).simm to be signed (as per architecture manual). + * sparc-pinsn.c (fprint_addr1, print_insn): Forced a cast to an + int, so that we really would get signed behaivior (default for sun + cc is unsigned). + + * i386-dep.c (i386_get_frame_setup): Replace function with new + function provided by pace to fix bug in recognizing prologue. + +Thu Jan 19 11:01:22 1989 Randall Smith (randy at plantaris.ai.mit.edu) + + * infcmd.c (run_command): Changed error message to "Program not + restarted." + + * value.h: Changed "frame" field in value structure to be a + FRAME_ADDR (actually CORE_ADDR) so that it could survive across + calls. + + * m-sun.h (FRAME_FIND_SAVED_REGS): Fixed a typo. + + * value.h: Added lval: "lval_reg_frame_relative" to indicate a + register that must be interpeted relative to a frame. Added + single entry to value structure: "frame", used to indicate which + frame a relative regnum is relative to. + * findvar.c (value_from_register): Modified to correctly setup + these fields when needed. Deleted section to fiddle with last + register copied on little endian machine; multi register + structures will always occupy an integral number of registers. + (find_saved_register): Made extern. + * values.c (allocate_value, allocate_repeat_value): Zero frame + field on creation. + * valops.c (value_assign): Added case for lval_reg_frame_relative; + copy value out, modify it, and copy it back. Desclared + find_saved_register as being external. + * value.h: Removed addition of kludgy structure; thoroughly + commented file. + * values.c (free_value, free_all_values, clear_value_history, + set_internalvar, clear_internavars): Killed free_value. + +Wed Jan 18 20:09:39 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * value.h: Deleted struct partial_storage; left over from + yesterday. + + * findvar.c (value_from_register): Added code to create a value of + type lval_reg_partsaved if a value is in seperate registers and + saved in different places. + +Tue Jan 17 13:50:18 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * value.h: Added lval_reg_partsaved to enum lval_type and + commented enum lval_type. Commented value structure. + Added "struct partial_register_saved" to value struct; added + macros to deal with structure to value.h. + * values.c (free_value): Created; special cases lval_reg_partsaved + (which has a pointer to an array which also needs to be free). + (free_all_values, clear_value_history, set_internalvar, + clear_internalvars): Modified to use free_values. + + * m-sunos4.h: Changed name to sun3os4.h. + * m-sun2os4.h, m-sun4os4.h: Created. + * config.gdb: Added configuration entries for each of the above. + * Makefile: Added into correct lists. + + * Makefile: Added dependencies on a.out.encap.h. Made + a.out.encap.h dependent on a.out.gnu.h and dbxread.c dependent on + stab.gnu.h. + + * infrun.c, remote.c: Removed inclusion of any a.out.h files in + these files; they aren't needed. + + * README: Added comment about bug reporting and comment about + xgdb. + + * Makefile: Added note to HPUX dependent section warning about + problems if compiled with gcc and mentioning the need to add + -Ihp-include to CFLAGS if you compile on those systems. Added a + note about needing the GNU nm with compilers *of gdb* that use the + coff encapsulate feature also. * hp-include: Made symbolic link + over to /gp/gnu/binutils. + + * Makefile: Added TSOBS NTSOBS OBSTACK and REGEX to list of things + to delete in "make clean". Also changed "squeakyclean" target as + "realclean". + + * findvar.c (value_from_register): Added assignment of VALUE_LVAL + to be lval_memory when that is appropriate (original code didn't + bother because it assumed that it was working with a pre lval + memoried value). + + * expread.y (yylex): Changed to only return type THIS if the + symbol "$this" is defined in some block superior or equal to the + current expression context block. + +Mon Jan 16 13:56:44 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-*.h (FRAME_CHAIN_VALID): On machines which check the relation + of FRAME_SAVED_PC (thisframe) to first_object_file_end (all except + gould), make sure that the pc of the current frame also passes (in + case someone stops in _start). + + * findvar.c (value_of_register): Changed error message in case of + no inferior or core file. + + * infcmd.c (registers_info): Added a check for inferior or core + file; error message if not. + + * main.c (gdb_read_line): Modified to take prompt as argument and + output it to stdout. + * infcmd.c (registers_info, signals_info), main.c (command_loop, + read_command_lines, copying_info), symtab.c (decode_line_2, + output_source_filename, MORE, list_symbols): Changed calling + convention used to call gdb_read_line. + + * infcmd.c, infrun.c, main.c, symtab.c: Changed the name of the + function "read_line" to "gdb_read_line". + * breakpoint.c: Deleted external referenced to function + "read_line" (not needed by code). + +Fri Jan 13 12:22:05 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * i386-dep.c: Include a.out.encap.h if COFF_ENCAPSULATE. + (N_SET_MAGIC): Defined if not defined by include file. + (core_file_command): Used N_SET_MAGIC instead of assignment to + a_magic. + (exec_file_command): Stuck in a HEADER_SEEK_FD. + + * config.gdb: Added i386-dep.c as depfile for i386gas choice. + + * munch: Added -I. to cc to pick up things included by the param + file. + + * stab.gnu.def: Changed name to stab.def (stab.gnu.h needs this name). + * Makefile: Changed name here also. + * dbxread.c: Changed name of gnu-stab.h to stab.gnu.h. + + * gnu-stab.h: Changed name to stab.gnu.h. + * stab.gnu.def: Added as link to binutils. + * Makefile: Put both in in the distribution. + +Thu Jan 12 11:33:49 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c: Made which stab.h is included dependent on + COFF_ENCAPSULATE; either <stab.h> or "gnu-stab.h". + * Makefile: Included gnu-stab.h in the list of files to include in + the distribution. + * gnu-stab.h: Made a link to /gp/gnu/binutils/stab.h + + * Makefile: Included a.out.gnu.h and m-i386gas.h in list of + distribution files. + * m-i386gas.h: Changed to include m-i386.h and fiddle with it + instead of being a whole new file. + * a.out.gnu.h: Made a link to /gp/gnu/binutils/a.out.gnu.h. + + Chris Hanson's changes to gdb for hp Unix. + * Makefile: Modified comments on hpux. + * hp9k320-dep.c: #define'd WOPR & moved inclusion of signal.h + * inflow.c: Moved around declaratiosn of <sys/fcntl.h> and + <sys/ioctl.h> inside of USG depends and deleted all SYSV ifdef's + (use USG instead). + * munch: Modified to accept any number of spaces between the T and + the symbol name. + + Pace's changes to gdb to work with COFF_ENCAPSULATE (robotussin): + * config.gdb: Added i386gas to targets. + * default-dep.c: Include a.out.encap.h if COFF_ENCAPSULATE. + (N_SET_MAGIC): Defined if not defined by include file. + (core_file_command): Used N_SET_MAGIC instead of assignment to a_magic. + (exec_file_command): Stuck in a HEADER_SEEK_FD. + * infrun.c, remote.c: Added an include of a.out.encap.h if + COFF_ENCAPSULATE defined. This is commented out in these two + files, I presume because the definitions aren't used. + * m-i386gas.h: Created. + * dbxread.c: Included defintions for USG. + (READ_FILE_HEADERS): Now uses HEADER_SEEK_FD if it exists. + (symbol_file_command): Deleted use of HEADER_SEEK_FD. + * core.c: Deleted extra definition of COFF_FORMAT. + (N_MAGIC): Defined to be a_magic if not already defined. + (validate_files): USed N_MAGIC instead of reading a_magic. + +Wed Jan 11 12:51:00 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * remote.c: Upped PBUFSIZ. + (getpkt): Added zeroing of c inside loop in case of error retry. + + * dbxread.c (read_dbx_symtab, process_symbol_for_psymtab): Removed + code to not put stuff with debugging symbols in the misc function + list. Had been ifdef'd out. + + * gdb.texinfo: Added the fact that the return value for a function + is printed if you use return. + + * infrun.c (wait_for_inferior): Removed test in "Have we hit + step_resume_breakpoint" for sp values in proper orientation. Was + in there for recursive calls in functions without frame pointers + and it was screwing up calls to alloca. + + * dbxread.c: Added #ifdef COFF_ENCAPSULATE to include + a.out.encap.h. + (symbol_file_command): Do HEADER_SEEK_FD when defined. + * dbxread.c, core.c: Deleted #ifdef ROBOTUSSIN stuff. + * robotussin.h: Deleted local copy (was symlink). + * a.out.encap.h: Created symlink to + /gp/gnu/binutils/a.out.encap.h. + * Makefile: Removed robotussin.h and included a.out.encap.h in + list of files. + + * valprint.c (val_print, print_scalar_formatted): Changed default + precision of printing float value; now 6 for a float and 16 for a + double. + + * findvar.c (value_from_register): Added code to deal with the + case where a value is spread over several registers. Still don't + deal with the case when some registers are saved in memory and + some aren't. + +Tue Jan 10 17:04:04 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * xgdb.c (xgdb_create_window): Removed third arg (XtDepth) to + frameArgs. + + * infrun.c (handle_command): Error if signal number is less or + equal to 0 or greater or equal to NSIG or a signal number is not + provided. + + * command.c (lookup_cmd): Modified to not convert command section + of command line to lower case in place (in case it isn't a + subcommand, but an argument to a command). + +Fri Jan 6 17:57:34 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c: Changed "text area" to "data area" in comments on + N_SETV. + +Wed Jan 4 12:29:54 1989 Randall Smith (randy at gluteus.ai.mit.edu) + + * dbxread.c: Added definitions of gnu symbol types after inclusion + of a.out.h and stab.h. + +Mon Jan 2 20:38:31 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * eval.c (evaluate_subexp): Binary logical operations needed to + know type to determine whether second value should be evaluated. + Modified to discover type before binup_user_defined_p branch. + Also commented "enum noside". + + * Makefile: Changed invocations of munch to be "./munch". + + * gdb.texinfo: Updated to refer to current version of gdb with + January 1989 last update. + + * coffread.c (end_symtab): Zero context stack when finishing + lexical contexts. + (read_coff_symtab): error if context stack 0 in ".ef" else case. + + * m-*.h (FRAME_SAVED_PC): Changed name of argument from "frame" to + "FRAME" to avoid problems with replacement of "->frame" part of + macro. + + * i386-dep.c (i386_get_frame_setup): Added codestream_get() to + move codestream pointer up to the correct location in "subl $X, + %esp" case. + +Sun Jan 1 14:24:35 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * valprint.c (val_print): Rewrote routine to print string pointed + to by char pointer; was producing incorrect results when print_max + was 0. + +Fri Dec 30 12:13:35 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * dbxread.c (read_dbx_symtab, process_symbol_for_psymtab): Put + everything on the misc function list. + + * Checkpointed distribution. + + * Makefile: Added expread.tab.c to the list of things slated for + distribution. + +Thu Dec 29 10:06:41 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * stack.c (set_backtrace_limit_command, backtrace_limit_info, + bactrace_command, _initialize_stack): Removed modifications for + limit on backtrace. Piping the backtrace through an interuptable + "more" emulation is a better way to do it. + +Wed Dec 28 11:43:09 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * stack.c + (set_backtrace_limit_command): Added command to set a limit to the + number of frames for a backtrace to print by default. + (backtrace_limit_info): To print the current limit. + (backtrace_command): To use the limit. + (_initialize_stack): To initialize the limit to its default value + (30), and add the set and info commands onto the appropriate + command lists. + + * gdb.texinfo: Documented changes to "backtrace" and "commands" + commands. + + * stack.c (backtrace_command): Altered so that a negative argument + would show the last few frames on the stack instead of the first + few. + (_initialize_stack): Modified help documentation. + + * breakpoint.c (commands_command): Altered so that "commands" with + no argument would refer to the last breakpoint set. + (_initialize_breakpoint): Modified help documentation. + + * infrun.c (wait_for_inferior): Removed ifdef on Sun4; now you can + single step through compiler generated sub calls and will die if + you next off of the end of a function. + + * sparc-dep.c (single_step): Fixed typo; "break_insn" ==> "sizeof + break_insn". + + * m-sparc.h (INIT_EXTRA_FRAME_INFO): Set the bottom of a stack + frame to be the bottom of the stack frame inner from this, if that + inner one is a leaf node. + + * dbxread.c (read_dbx_symtab): Check to make sure we don't add a + psymtab to it's own dependency list. + + * dbxread.c (read_dbx_symtab): Modified check for duplicate + dependencies to catch them correctly. + +Tue Dec 27 17:02:09 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-*.h (FRAME_SAVED_PC): Modified macro to take frame info + pointer as argument. + * stack.c (frame_info), blockframe.c (get_prev_frame_info), + gld-pinsn.c (findframe), m-*.h (SAVED_PC_AFTER_CALL, + FRAME_CHAIN_VALID, FRAME_NUM_ARGS): Changed usage of macros to + conform to above. + * m-sparc.h (FRAME_SAVED_PC), sparc-dep.c (frame_saved_pc): + Changed frame_saved_pc to have a frame info pointer as an + argument. + + * m-vax.h, m-umax.h, m-npl.h, infrun.c (wait_for_inferior), + blockframe.c (get_prev_frame_info): Modified SAVED_PC_AFTER_CALL + to take a frame info pointer as an argument. + + * blockframe.c (get_prev_frame_info): Altered the use of the + macros FRAME_CHAIN, FRAME_CHAIN_VALID, and FRAME_CHAIN_COMBINE to + use frame info pointers as arguments instead of frame addresses. + * m-vax.h, m-umax.h, m-sun3.h, m-sun3.h, m-sparc.h, m-pn.h, + m-npl.h, m-news.h, m-merlin.h, m-isi.h, m-hp9k320.h, m-i386.h: + Modified definitions of the above macros to suit. + * m-pn.h, m-npl.h, gould-dep.c (findframe): Modified findframe to + use a frame info argument; also fixed internals (wouldn't work + before). + + * m-sparc.h: Cosmetic changes; reordered some macros and made sure + that nothing went over 80 lines. + +Thu Dec 22 11:49:15 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * Version 3.0 released. + + * README: Deleted note about changing -lobstack to obstack.o. + +Wed Dec 21 11:12:47 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-vax.h (SKIP_PROLOGUE): Now recognizes gcc prologue also. + + * blockframe.c (get_prev_frame_info): Added FUNCTION_START_OFFSET + to result of get_pc_function_start. + * infrun.c (wait_for_inferior): Same. + + * gdb.texinfo: Documented new "step" and "next" behavior in + functions without line number information. + +Tue Dec 20 18:00:45 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * infcmd.c (step_1): Changed behavior of "step" or "next" in a + function witout line number information. It now sets the step + range around the function (to single step out of it) using the + misc function vector, warns the user, and continues. + + * symtab.c (find_pc_line): Zero "end" subsection of returned + symtab_and_line if no symtab found. + +Mon Dec 19 17:44:35 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * i386-pinsn.c (OP_REG): Added code from pace to streamline + disassembly and corrected types. + * i386-dep.c + (i386_follow_jump): Code added to follow byte and word offset + branches. + (i386_get_frame_setup): Expanded to deal with more wide ranging + function prologue. + (i386_frame_find_saved_regs, i386_skip_prologue): Changed to use + i386_get_frame_setup. + + +Sun Dec 18 11:15:03 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-sparc.h: Deleted definition of SUN4_COMPILER_BUG; was designed + to avoid something that I consider a bug in our code, not theirs, + and which I fixed earlier. Also deleted definition of + CANNOT_USE_ARBITRARY_FRAME; no longer used anywhere. + FRAME_SPECIFICATION_DYADIC used instead. + + * infrun.c (wait_for_inferior): On the sun 4, if a function + doesn't have a prologue, a next over it single steps into it. + This gets around the problem of a "call .stret4" at the end of + functions returning structures. + * m-sparc.h: Defined SUN4_COMPILER_FEATURE. + + * main.c (copying_info): Seperated the last printf into two + printfs. The 386 compiler will now handle it. + + * i386-pinsn.c, i386-dep.c: Moved print_387_control_word, + print_387_status_word, print_387_status, and i386_float_info to + dep.c Also included reg.h in dep.c. + +Sat Dec 17 15:31:38 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * main.c (source_command): Don't close instream if it's null + (indicating execution of a user-defined command). + (execute_command): Set instream to null before executing + commands and setup clean stuff to put it back on error. + + * inflow.c (terminal_inferior): Went back to not checking the + ioctl returns; there are some systems when this will simply fail. + It seems that, on most of these systems, nothing bad will happen + by that failure. + + * values.c (value_static_field): Fixed dereferencing of null + pointer. + + * i386-dep.c (i386_follow_jump): Modified to deal with + unconditional byte offsets also. + + * dbxread.c (read_type): Fixed typo in function type case of switch. + + * infcmd.c (run_command): Does not prompt to restart if command is + not from a tty. + +Fri Dec 16 15:21:58 1988 Randy Smith (randy at calvin) + + * gdb.texinfo: Added a third option under the "Cannot Insert + Breakpoints" workarounds. + + * printcmd.c (display_command): Don't do the display unless there + is an active inferior; only set it. + + * findvar.c (value_of_register): Added an error check for calling + this when the inferior isn't active and a core file isn't being + read. + + * config.gdb: Added reminder about modifying REGEX in the + makefile for the 386. + + * i386-pinsn.c, i386-dep.c: Moved m-i386.h helper functions over + to i386-dep.c.b + +Thu Dec 15 14:04:25 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * README: Added a couple of notes about compiling gdb with itself. + + * breakpoint.c (set_momentary_breakpoint): Only takes FRAME_FP of + frame if frame is non-zero. + + * printcmd.c (print_scalar_formatted): Implemented /g size for + hexadecimal format on machines without an 8 byte integer type. It + seems to be non-trivial to implement /g for other formats. + (decode_format): Allowed hexadecimal format to make it through /g + fileter. + +Wed Dec 14 13:27:04 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * expread.y: Converted all calls to write_exp_elt from the parser + to calls to one of write_exp_elt_{opcode, sym, longcst, dblcst, + char, type, intern}. Created all of these routines. This gets + around possible problems in passing one of these things in one ear + and getting something different out the other. Eliminated + SUN4_COMPILER_BUG ifdef's; they are now superfluous. + + * symmisc.c (free_all_psymtabs): Reinited partial_symtab_list to 0. + (_initialize_symmisc): Initialized both symtab_list and + partial_symtab_list. + + * dbxread.c (start_psymtab): Didn't allocate anything on + dependency list. + (end_psymtab): Allocate dependency list on psymbol obstack from + local list. + (add_psymtab_dependency): Deleted. + (read_dbx_symtab): Put dependency on local list if it isn't on it + already. + + * symtab.c: Added definition of psymbol_obstack. + * symtab.h: Added declaration of psymbol_obstack. + * symmisc.c (free_all_psymtabs): Added freeing and + reinitionaliztion of psymbol_obstack. + * dbxread.c (free_all_psymbols): Deleted. + (start_psymtab, end_psymtab, + process_symbol_for_psymtab): Changed most allocation + of partial symbol stuff to be off of psymbol_obstack. + + * symmisc.c (free_psymtab, free_all_psymtabs): Deleted + free_psymtab subroutine. + + * symtab.h: Removed num_includes and includes from partial_symtab + structure; no longer needed now that all include files have their + own psymtab. + * dbxread.c (start_psymtab): Eliminated initialization of above. + (end_psymtab): Eliminated finalization of above; get + includes from seperate list. + (read_dbx_symtab): Moved includes from psymtab list to + their own list; included in call to end_psymtab. + * symmisc.c (free_psymtab): Don't free includes. + +Tue Dec 13 14:48:14 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * i386-pinsn.c: Reformatted entire file to correspond to gnu + software indentation conventions. + + * sparc-dep.c (skip_prologue): Added capability of recognizign + stores of input register parameters into stack slots. + + * sparc-dep.c: Added an include of sparc-opcode.h. + * sparc-pinsn.c, sparc-opcode.h: Moved insn_fmt structures and + unions from pinsn.c to opcode.h. + * sparc-pinsn.c, sparc-dep.c (isabranch, skip_prologue): Moved + this function from pinsn.c to dep.c. + + * Makefile: Put in warnings about compiling with gcc (non-ansi + include files) and compiling with shared libs on Sunos 4.0 (can't + debug something that's been compiled that way). + + * sparc-pinsn.c: Put in a completely new file (provided by + Tiemann) to handle floating point disassembly, load and store + instructions, and etc. better. Made the modifications this file + (ChangeLog) list for sparc-pinsn.c again. + + * symtab.c (output_source_filename): Included "more" emulation hack. + + * symtab.c (output_source_filename): Initialized COLUMN to 0. + (sources_info): Modified to not print out a line for + all of the include files within a partial symtab (since + they have pst's of their own now). Also modified to + make a distinction between those pst's read in and + those not. + + * infrun.c: Included void declaration of single_step() if it's + going to be used. + * sparc-dep.c (single_step): Moved function previous to use of it. + + * Makefile: Took removal of expread.tab.c out of make clean entry + and put it into a new "squeakyclean" entry. + +Mon Dec 12 13:21:02 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * sparc-pinsn.c (skip_prologue): Changed a struct insn_fmt to a + union insn_fmt. + + * inflow.c (terminal_inferior): Checked *all* return codes from + ioctl's and fcntl's in routine. + + * inflow.c (terminal_inferior): Added check for sucess of + TIOCSPGRP ioctl call. Just notifies if bad. + + * dbxread.c (symbol_file_command): Close was getting called twice; + once directly and once through cleanup. Killed the direct call. + +Sun Dec 11 19:40:40 1988 & Smith (randy at hobbes.ai.mit.edu) + + * valprint.c (val_print): Deleted spurious printing of "=" from + TYPE_CODE_REF case. + +Sat Dec 10 16:41:07 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * dbxread.c: Changed allocation of psymbols from using malloc and + realloc to using obstacks. This means they aren't realloc'd out + from under the pointers to them. + +Fri Dec 9 10:33:24 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * sparc-dep.c inflow.c core.c expread.y command.c infrun.c + infcmd.c dbxread.c symmisc.c symtab.c printcmd.c valprint.c + values.c source.c stack.c findvar.c breakpoint.c blockframe.c + main.c: Various cleanups inspired by "gcc -Wall" (without checking + for implicit declarations). + + * Makefile: Cleaned up some more. + + * valops.c, m-*.h (FIX_CALL_DUMMY): Modified to take 5 arguments + as per what sparc needs (programming for a superset of needed + args). + + * dbxread.c (process_symbol_for_psymtab): Modified to be slightly + more picky about what it puts on the list of things *not* to be + put on the misc function list. When/if I shift everything over to + being placed on the misc_function_list, this will go away. + + * inferior.h, infrun.c: Added fields to save in inferior_status + structure. + + * maketarfile: Deleted; functionality is in Makefile now. + + * infrun.c (wait_for_inferior): Modified algorithm for determining + whether or not a single-step was through a subroutine call. See + comments at top of file. + + * dbxread.c (read_dbx_symtab): Made sure that the IGNORE_SYMBOL + macro would be checked during initial readin. + + * dbxread.c (read_ofile_symtab): Added macro GCC_COMPILED_FLAG_SYMBOL + into dbxread.c to indicate what string in a local text symbol will + indicate a file compiled with gcc. Defaults to "gcc_compiled.". + +Thu Dec 8 11:46:22 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-sparc.h (FRAME_FIND_SAVED_REGS): Cleaned up a little to take + advantage of the new frame cache system. + + * inferior.h, infrun.c, valops.c, valops.c, infcmd.c: Changed + mechanism to save inferior status over calls to inferior (eg. + call_function); implemented save_inferior_info and + restore_inferior_info. + + * blockframe.c (get_prev_frame): Simplified this by a direct call + to get_prev_frame_info. + + * frame.h, stack.c, printcmd.c, m-sparc.h, sparc-dep.c: Removed + all uses of frame_id_from_addr. There are short routines like it + still in frame_saved_pc (m-sparc.h) and parse_frame_spec + (stack.c). Eventually the one in frame_saved_pc will go away. + + * infcmd.c, sparc-dep.c: Implemented a new mechanism for + re-selecting the selected frame on return from a call. + + * blockframe.c, stack.c, findvar.c, printcmd.c, m-*.h: Changed + all routines and macros that took a "struct frame_info" as an + argument to take a "struct frame_info *". Routines: findarg, + framechain, print_frame_args, FRAME_ARGS_ADDRESS, + FRAME_STRUCT_ARGS_ADDRESS, FRAME_LOCALS_ADDRESS, FRAME_NUM_ARGS, + FRAME_FIND_SAVED_REGS. + + * frame.h, stack.c, printcmd.c, infcmd.c, findvar.c, breakpoint.c, + blockframe.c, xgdb.c, i386-pinsn.c, gld-pinsn.c, m-umax.h, + m-sun2.h, m-sun3.h, m-sparc.h, m-pn.h, m-npl.h, m-news.h, + m-merlin.h, m-isi.h, m-i386.h, m-hp9k320.h: Changed routines to + use "struct frame_info *" internally. + +Wed Dec 7 12:07:54 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * frame.h, blockframe.c, m-sparc.h, sparc-dep.c: Changed all calls + to get_[prev_]frame_cache_item to get_[prev_]frame_info. + + * blockframe.c: Elminated get_frame_cache_item and + get_prev_frame_cache_item; functionality now taken care of by + get_frame_info and get_prev_frame_info. + + * blockframe.c: Put allocation on an obstack and eliminated fancy + reallocation routines, several variables, and various nasty + things. + + * frame.h, stack.c, infrun.c, blockframe.c, sparc-dep.c: Changed + type FRAME to be a typedef to "struct frame_info *". Had to also + change routines that returned frame id's to return the pointer + instead of the cache index. + + * infcmd.c (finish_command): Used proper method of getting from + function symbol to start of function. Was treating a symbol as a + value. + + * blockframe.c, breakpoint.c, findvar.c, infcmd.c, stack.c, + xgdb.c, i386-pinsn.c, frame.h, m-hp9k320.h, m-i386.h, m-isi.h, + m-merlin.h, m-news.h, m-npl.h, m-pn.h, m-sparc.h, m-sun2.h, + m-sun3.h, m-umax.h: Changed get_frame_info and get_prev_frame_info + to return pointers instead of structures. + + * blockframe.c (get_pc_function_start): Modified to go to misc + function table instead of bombing if pc was in a block without a + containing function. + + * coffread.c: Dup'd descriptor passed to read_coff_symtab and + fdopen'd it so that there wouldn't be multiple closes on the same + fd. Also put (fclose, stream) on the cleanup list. + + * printcmd.c, stack.c: Changed print_frame_args to take a + frame_info struct as argument instead of the address of the args + to the frame. + + * m-i386.h (STORE_STRUCT_RETURN): Decremented sp by sizeof object + to store (an address) rather than 1. + + * dbxread.c (read_dbx_symtab): Set first_object_file_end in + read_dbx_symtab (oops). + + * coffread.c (fill_in_vptr_fieldno): Rewrote TYPE_BASECLASS as + necessary. + +Tue Dec 6 13:03:43 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * coffread.c: Added fake support for partial_symtabs to allow + compilation and execution without there use. + * inflow.c: Added a couple of minor USG mods. + * munch: Put in appropriate conditionals so that it would work on + USG systems. + * Makefile: Made regex.* handled same as obstack.*; made sure tar + file included everything I wanted it to include (including + malloc.c). + + * dbxread.c (end_psymtab): Create an entry in the + partial_symtab_list for each subfile of the .o file just read in. + This allows a "list expread.y:10" to work when we haven't read in + expread.o's symbol stuff yet. + + * symtab.h, dbxread.c (psymtab_to_symtab): Recognize pst->ldsymlen + == 0 as indicating a dummy psymtab, only in existence to cause the + dependency list to be read in. + + * dbxread.c (sort_symtab_syms): Elminated reversal of symbols to + make sure that register debug symbol decls always come before + parameter symbols. After mod below, this is not needed. + + * symtab.c (lookup_block_symbol): Take parameter type symbols + (LOC_ARG or LOC_REGPARM) after any other symbols which match. + + * dbxread.c (read_type): When defining a type in terms of some + other type and the other type is supposed to have a pointer back + to this specific kind of type (pointer, reference, or function), + check to see if *that* type has been created yet. If it has, use + it and fill in the appropriate slot with a pointer to it. + +Mon Dec 5 11:25:04 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * symmisc.c: Eliminated existence of free_inclink_symtabs and + init_free_inclink_symtabs; they aren't called from anywhere, and + if they were they could disrupt gdb's data structure badly + (elimination of struct type's which values that stick around past + elimination of inclink symtabs). + + * dbxread.c (symbol_file_command): Fixed a return pathway out of + the routine to do_cleanups before it left. + + * infcmd.c (set_environment_command), gdb.texinfo: Added + capability to set environmental variable values to null. + + * gdb.texinfo: Modified doc on "break" without args slightly. + +Sun Dec 4 17:03:16 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * dbxread.c (symbol_file_command): Added check; if there weren't + any debugging symbols in the file just read, the user is warned. + + * infcmd.c: Commented set_environment_command (a little). + + * createtags: Cleaned up and commented. + + * Makefile: Updated depen_memory and write_inferior_memory in that errno is + checked after each ptrace and returned to the caller. Used in + value_at to detect references to addresses which are out of + bounds. Also core.c (xfer_core_file): return 1 if invalid + address, 0 otherwise. + + * inflow.c, <machine>-infdep.c: removed all calls to ptrace from + inflo, m-sun3.h: Cleaned up dealings with + functions returning structu0 19:19:36 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * symmisc.c: (read_symsegs) Accept only format number 2. Since + the size of the type structure changed when C++ support was added, + format 1 can no longer be used. + + * core.c, m-sunos4.h: (core_file_command) support for SunOS 4.0. + Slight change in the core structure. #ifdef SUNOS4. New file + m-sunos4.h. May want to change config.gdb also. + +Fri Jul 8 19:59:49 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * breakpoint.c: (break_command_1) Allow `break if condition' + rather than parsing `if' as a function name and returning an + error. + +Thu Jul 7 22:22:47 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * C++: valops.c, valprint.c, value.h, values.c: merged code to deal + with C++ expressions. + +Wed Jul 6 03:28:18 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * C++: dbxread.c: (read_dbx_symtab, condense_misc_bunches, + add_file_command) Merged code to read symbol information from + an incrementally linked file. symmisc.c: + (init_free_inclink_symtabs, free_inclink_symtabs) Cleanup + routines. + +Tue Jul 5 02:50:41 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * C++: symtab.c, breakpoint.c, source.c: Merged code to deal with + ambiguous line specifications. In C++ one can have overloaded + function names, so that `list classname::overloadedfuncname' + refers to several different lines, possibly sure currently configured machine + dependent files come first in e at corn-chex.ai.mit.edu) + + * C++: symtab.c: replaced lookup_symtab_1 and lookup_symtab_2 with + a modified lookup_symbol which checks for fields of the current + implied argument `this'. printcmd.c, source.c, symtab.c, + valops.c: Need to change callers once callers are + installed. + +Wed Jun 29 01:26:56 1988 Peter TerMaat (pete at frosted-flakes.ai.mit.edu) + + * C++: eval.c, expprint.c, expread.y, expression.h, valarith.c, + Merged code to deal with evaluation of user-defined operators, + member functions, and virtual functions. + binop_must_be_user_defined tests for user-defined binops, + value_x_binop calls the appropriate operator function. + +Tue Jun 28 02:56:42 1988 Peter TerMaat (pete at frosted-flakes.ai.mit.edu) + + * C++: Makefile: changed the echo: expect 101 shift/reduce conflicts + and 1 reduce/reduce conflict. + + +Local Variables: +mode: indented-text +eval: (auto-fill-mode 1) +left-margin: 8 +fill-column: 74 +version-control: never +End: + + constructors, and flags being defined via public and via + virtual paths. Added fields NEXT_VARIANT, N_BASECLASSES, + and BASECLASSES to this type (tr: Changed types from + having to be derived from a single baseclass to a multiple + base class). + * symtab.h: Added macros to access new fields defined in symseg.h. + Added decl for lookup_basetype_type. + * dbxread.c + (condense_addl_misc_bunches): Function added to condense the misc + function bunches added by reading in a new .o file. + (read_addl_syms): Function added to read in symbols + from a new .o file (incremental linking). + (add_file_command): Command interface function to indicate + incrmental linking of a new .o file; this now calls + read_addl_syms and condense_addl_misc_bunches. + (define_symbol): Modified code to handle types defined from base + types which were not known when the derived class was + output. + (read_struct_type): Modified to better handle description of + struct types as derived types. Possibly derived from + several different base classes. Also added new code to + mark definitions via virtual paths or via public paths. + Killed seperate code to handle classes with destructors + but without constructors and improved marking of classes + as having destructors and constructors. + * infcmd.c: Modified call to val_print (one more argument). + * symtab.c (lookup_member_type): Modified to deal with new + structure in symseg.h. + (lookup_basetype_type): Function added to find or construct a type + ?derived? from the given type. + (decode_line_1): Modified to deal with new type data structures. + Modified to deal with new number of args for + decode_line_2. + (decode_line_2): Changed number of args (?why?). + (init_type): Added inits for new C++ fields from + symseg.h. + *valarith.c + (value_x_binop, value_binop): Added cases for BINOP_MIN & + BINOP_MAX. + * valops.c + (value_struct_elt, check_field, value_struct_elt_for_address): + Changed to deal with multiple possible baseclasses. + (value_of_this): Made SELECTED_FRAME an extern variable. + * valprint.c + (val_print): Added an argument DEREF_REF to dereference references + automatically, instead of printing them like pointers. + Changed number of arguments in recursive calls to itself. + Changed to deal with varibale numbers of base classes. + (value_print): Changed number of arguments to val_print. Print + type of value also if value is a reference. + (type_print_derivation_info): Added function to print out + derivation info a a type. + (type_print_base): Modified to use type_print_derivation_info and + to handle multiple baseclasses. + +Mon Nov 21 10:32:07 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * inflow.c (term_status_command): Add trailing newline to output. + + * sparc-dep.c (do_save_insn, do_restore_insn): Saved + "stop_registers" over the call for the sake of normal_stop and + run_stack_dummy. + + * m-sparc.h (EXTRACT_RETURN_VALUE): Put in parenthesis to force + addition of 8 to the int pointer, not the char pointer. + + * sparc-pinsn.c (print_addr1): Believe that I have gotten the + syntax right for loads and stores as adb does it. + + * symtab.c (list_symbols): Turned search for match on rexegp into + a single loop. + + * dbxread.c (psymtab_to_symtab): Don't read it in if it's already + been read in. + + * dbxread.c (psymtab_to_symtab): Changed error to fatal in + psymtab_to_symtab. + + * expread.y (parse_number): Fixed bug which treated 'l' at end of + number as '0'. + +Fri Nov 18 13:57:33 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * dbxread.c (read_dbx_symtab, process_symbol_for_psymtab): Was + being foolish and using pointers into an array I could realloc. + Converted these pointers into integers. + +Wed Nov 16 11:43:10 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-sparc.h (POP_FRAME): Made the new frame be PC_ADJUST of the + old frame. + + * i386-pinsn.c, m-hp9k320.h, m-isi.h, m-merlin.h, m-news.h, + m-npl.h, m-pn.h, m-sparc.h, m-sun2.h, m-sun3.h, m-umax.h, m-vax.h: + Modified POP_FRAME to use the current frame instead of + read_register (FP_REGNUM) and to flush_cached_frames before + setting the current frame. Also added a call to set the current + frame in those POP_FRAMEs that didn't have it. + + * infrun.c (wait_for_inferior): Moved call to set_current_frame up + to guarrantee that the current frame will always be set when a + POP_FRAME is done. + + * infrun.c (normal_stop): Added something to reset the pc of the + current frame (was incorrect because of DECR_PC_AFTER_BREAK). + + * valprint.c (val_print): Changed to check to see if a string was + out of bounds when being printed and to indicate this if so. + + * convex-dep.c (read_inferior_memory): Changed to return the value + of errno if the call failed (which will be 0 if the call + suceeded). + +Tue Nov 15 10:17:15 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * infrun.c (wait_for_inferior): Two changes: 1) Added code to + not trigger the step breakpoint on recursive calls to functions + without frame info, and 2) Added calls to distinguish recursive + calls within a function without a frame (which next/nexti might + wish to step over) from jumps to the beginning of a function + (which it generally doesn't). + + * m-sparc.h (INIT_EXTRA_FRAME_INFO): Bottom set correctly for leaf + parents. + + * blockframe.c (get_prev_frame_cache_item): Put in mod to check + for a leaf node (by presence or lack of function prologue). If + there is a leaf node, it is assumed that SAVED_PC_AFTER_CALL is + valid. Otherwise, FRAME_SAVED_PC or read_pc is used. + + * blockframe.c, frame.h: Did final deletion of unused routines and + commented problems with getting a pointer into the frame cache in + the frame_info structure comment. + + * blockframe.c, frame.h, stack.c: Killed use of + frame_id_from_frame_info; used frame_id_from_addr instead. + + * blockframe.c, frame.h, stack.c, others (oops): Combined stack + cache and frame info structures. + + * blockframe.c, sparc-dep.c, stack.c: Created the function + create_new_frame and used it in place of bad calls to + frame_id_from_addr. + + * blockframe.c, inflow.c, infrun.c, i386-pinsn.c, m-hp9k320.h, + m-npl.h, m-pn.h, m-sparc.h, m-sun3.h, m-vax.h, default-dep.c, + convex-dep.c, gould-dep.c, hp9k320-dep.c, news-dep.c, sparc-dep.c, + sun3-dep.c, umax-dep.c: Killed use of + set_current_Frame_by_address. Used set_current_frame + (create_new_frame...) instead. + + * frame.h: Killed use of FRAME_FP_ID. + + * infrun.c, blockframe.c: Killed select_frame_by_address. Used + select_frame (get_current_frame (), 0) (which was correct in all + cases that we need to worry about. + +Mon Nov 14 14:19:32 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * frame.h, blockframe.c, stack.c, m-sparc.h, sparc-dep.c: Added + mechanisms to deal with possible specification of frames + dyadically. + +Sun Nov 13 16:03:32 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu) + + * ns32k-opcode.h: Add insns acbw, acbd. + +Sun Nov 13 15:09:58 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * breakpoint.c: Changed breakpoint structure to use the address of + a given frame (constant across inferior runs) as the criteria for + stopping instead of the frame ident (which varies across inferior + calls). + +Fri Nov 11 13:00:22 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * gld-pinsn.c (findframe): Modified to work with the new frame + id's. Actually, it looks as if this routine should be called with + an address anyway. + + * findvar.c (find_saved_register): Altered bactrace loop to work + off of frames and not frame infos. + + * frame.h, blockframe.c, stack.c, sparc-dep.c, m-sparc.h: Changed + FRAME from being the address of the frame to being a simple ident + which is an index into the frame_cache_item list. + * convex-dep.c, default-dep.c, gould-dep.c, hp9k320-dep.c, + i386-pinsn.c, inflow.c, infrun.c, news-dep.c, sparc-dep.c, + sun3-dep.c, umax-dep.c, m-hp9k320.h, m-npl.h, m-pn.h, m-sparc.h, + m-sun3.h, m-vax.h: Changed calls of the form set_current_frame + (read_register (FP_REGNUM)) to set_current_frame_by_address (...). + +Thu Nov 10 16:57:57 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * frame.h, blockframe.c, gld-pinsn.c, sparc-dep.c, stack.c, + infrun.c, findvar.c, m-sparc.h: Changed the FRAME type to be + purely an identifier, using FRAME_FP and FRAME_FP_ID to convert + back and forth between the two. The identifier is *currently* + still the frame pointer value for that frame. + +Wed Nov 9 17:28:14 1988 Chris Hanson (cph at kleph) + + * m-hp9k320.h (FP_REGISTER_ADDR): Redefine this to return + difference between address of given FP register, and beginning of + `struct user' that it occurs in. + + * hp9k320-dep.c (core_file_command): Fix sign error in size + argument to myread. Change buffer argument to pointer; was + copying entire structure. + (fetch_inferior_registers, store_inferior_registers): Replace + occurrences of `FP_REGISTER_ADDR_DIFF' with `FP_REGISTER_ADDR'. + Flush former definition. + +Wed Nov 9 12:11:37 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * xgdb.c: Killed include of initialize.h. + + * Pulled in xgdb.c from the net. + + * Checkpointed distribution (to provide to 3b2 guy). + + * coffread.c, dbxread.c, symmisc.c, symtab.c, symseg.h: Changed + format of table of line number--pc mapping information. Can + handle negative pc's now. + + * command.c: Deleted local copy of savestring; code in utils.c is + identical. + +Tue Nov 8 11:12:16 1988 Randall Smith (randy at plantaris.ai.mit.edu) + + * gdb.texinfo: Added documentation for shell escape. + +Mon Nov 7 12:27:16 1988 Randall Smith (randy at sugar-bombs.ai.mit.edu) + + * command.c: Added commands for shell escape. + + * core.c, dbxread.c: Added ROBOTUSSIN mods. + + * Checkpointed distribution. + + * printcmd.c (x_command): Yanked error if there is no memory to + examine (could be looking at executable straight). + + * sparc-pinsn.c (print_insn): Amount to leftshift sethi imm by is + now 10 (matches adb in output). + + * printcmd.c (x_command): Don't attempt to set $_ & $__ if there + is no last_examine_value (can happen if you did an x/0). + +Fri Nov 4 13:44:49 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * printcmd.c (x_command): Error if there is no memory to examine. + + * gdb.texinfo: Added "cont" to the command index. + + * sparc-dep.c (do_save_insn): Fixed typo in shift amount. + + * m68k-opcode.h: Fixed opcodes for 68881. + + * breakpoint.c, infcmd.c, source.c: Changed defaults in several + places for decode_line_1 to work off of the default_breakpoint_* + values instead of current_source_* values (the current_source_* + values are off by 5 or so because of listing defaults). + + * stack.c (frame_info): ifdef'd out FRAME_SPECIFCATION_DYADIC in + the stack.c module. If I can't do this right, I don't want to do + it at all. Read the comment there for more info. + +Mon Oct 31 16:23:06 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * gdb.texinfo: Added documentation on the "until" command. + +Sat Oct 29 17:47:10 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * breakpoint.c, infcmd.c: Added UNTIL_COMMAND and subroutines of + it. + + * breakpoint.c, infcmd.c, infrun.c: Added new field to breakpoint + structure (silent, indicating a silent breakpoint), and modified + breakpoint_stop_status and things that read it's return value to + understand it. + +Fri Oct 28 17:45:33 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * dbxread.c, symmisc.c: Assorted speedups for readin, including + special casing most common symbols, and doing buffering instead of + calling malloc. + +Thu Oct 27 11:11:15 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * stack.c, sparc-dep.c, m-sparc.h: Modified to allow "info frame" + to take two arguments on the sparc and do the right thing with + them. + + * dbxread.c (read_dbx_symtab, process_symbol_for_psymtab): Put + stuff to put only symbols that didn't have debugging info on the + misc functions list back in. + +Wed Oct 26 10:10:32 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * valprint.c (type_print_varspec_suffix): Added check for + TYPE_LENGTH(TYPE_TARGET_TYPE(type)) > 0 to prevent divide by 0. + + * printcmd.c (print_formatted): Added check for VALUE_REPEATED; + value_print needs to be called for that. + + * infrun.c (wait_for_inferior): Added break when you decide to + stop on a null function prologue rather than continue stepping. + + * m-sun3.h: Added explanatory comment to REGISTER_RAW_SIZE. + + * expread.y (parse_c_1): Initialized paren_depth for each parse. + +Tue Oct 25 14:19:38 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * valprint.c, coffread.c, dbxread.c: Enum constant values in enum + type now accessed through TYPE_FIELD_BITPOS. + + * dbxread.c (process_symbol_for_psymtab): Added code to deal with + possible lack of a ":" in a debugging symbol (do nothing). + + * symtab.c (decode_line_1): Added check in case of all numbers for + complete lack of symbols. + + * source.c (select_source_symtab): Made sure that this wouldn't + bomb on complete lack of symbols. + +Mon Oct 24 12:28:29 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-sparc.h, findvar.c: Ditched REGISTER_SAVED_UNIQUELY and based + code on REGISTER_IN_WINDOW_P and HAVE_REGISTER_WINDOWS. This will + break when we find a register window machine which saves the + window registers within the context of an inferior frame. + + * sparc-dep.c (frame_saved_pc): Put PC_ADJUST return back in for + frame_saved_pc. Seems correct. + + * findvar.c, m-sparc.h: Created the macro REGISTER_SAVED_UNIQUELY + to handle register window issues (ie. that find_saved_register + wasn't checking the selected frame itself for shit). + + * sparc-dep.c (core_file_command): Offset target of o & g register + bcopy by 1 to hit correct registers. + + * m-sparc.h: Changed STACK_END_ADDR. + +Sun Oct 23 19:41:51 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * sparc-dep.c (core_file_command): Added in code to get the i & l + registers from the stack in the corefile, and blew away some wrong + code to get i & l from inferior. + +Fri Oct 21 15:09:19 1988 Randall Smith (randy at apple-gunkies.ai.mit.edu) + + * m-sparc.h (PUSH_DUMMY_FRAME): Saved the value of the RP register + in the location reserved for i7 (in the created frame); this way + the rp value won't get lost. The pc (what we put into the rp in + this routine) gets saved seperately, so we loose no information. + + * sparc-dep.c (do_save_insn & do_restore_insn): Added a wrapper to + preserve the proceed status state variables around each call to + proceed (the current frame was getting munged because this wasn't + being done). + + * m-sparc.h (FRAME_FIND_SAVED_REGS): Fix bug: saved registers + addresses were being computed using absolute registers number, + rather than numbers relative to each group of regs. + + * m-sparc.h (POP_FRAME): Fixed a bug (I hope) in the context + within which saved reg numbers were being interpetted. The + values to be restored were being gotten in the inferior frame, and + the restoring was done in the superior frame. This means that i + registers must be restored into o registers. + + * sparc-dep.c (do_restore_insn): Modified to take a pc as an + argument, instead of a raw_buffer. This matches (at least it + appears to match) usage from POP_FRAME, which is the only place + from which do_restore_insn is called. + + * sparc-dep.c (do_save_insn and do_restore_insn): Added comments. + + * m-sparc.h (FRAME_FIND_SAVED_REGS): Modified my code to find the + save addresses of out registers to use the in regs off the stack + pointer when the current frame is 1 from the innermost. + +Thu Oct 20 13:56:15 1988 & Smith (randy at hobbes.ai.mit.edu) + + * blockframe.c, m-sparc.h: Removed code associated with + GET_PREV_FRAME_FROM_CACHE_ITEM. This code was not needed for the + sparc; you can always find the previous frames fp from the fp of + the current frame (which is the sp of the previous). It's getting + the information associated with a given frame (ie. saved + registers) that's a bitch, because that stuff is saved relative to + the stack pointer rather than the frame pointer. + + * m-sparc.h (GET_PREV_FRAME_FROM_CACHE_ITEM): Modified to return + the frame pointer of the previous frame instead of the stack + pointer of same. + + * blockframe.c (flush_cached_frames): Modified call to + obstack_free to free back to frame_cache instead of back to zero. + This leaves the obstack control structure in finite state (and + still frees the entry allocated at frame_cache). + +Sat Oct 15 16:30:47 1988 & Smith (randy at tartarus.uchicago.edu) + + * valops.c (call_function): Suicide material here. Fixed a typo; + CALL_DUMMY_STACK_ADJUST was spelled CAll_DUMMY_STACK_ADJUST on + line 530 of the file. This cost me three days. I'm giving up + typing for lent. + +Fri Oct 14 15:10:43 1988 & Smith (randy at tartarus.uchicago.edu) + + * m-sparc.h: Corrected a minor mistake in the dummy frame code + that was getting the 5th argument and the first argument from the + same place. + +Tue Oct 11 11:49:33 1988 & Smith (randy at tartarus.uchicago.edu) + + * infrun.c: Made stop_after_trap and stop_after_attach extern + instead of static so that code which used proceed from machine + dependent files could fiddle with them. + + * blockframe.c, frame.h, sparc-dep.c, m-sparc.h: Changed sense of + ->prev and ->next in struct frame_cache_item to fit usage in rest + of gdb (oops). + +Mon Oct 10 15:32:42 1988 Randy Smith (randy at gargoyle.uchicago.edu) + + * m-sparc.h, sparc-dep.c, blockframe.c, frame.h: Wrote + get_frame_cache_item. Modified FRAME_SAVED_PC and frame_saved_pc + to take only one argument and do the correct thing with it. Added + the two macros I recently defined in blockframe.c to m-sparc.h. + Have yet to compile this thing on a sparc, but I've now merged in + everything that I received from tiemann, either exactly, or simply + effectively. + + * source.c: Added code to allocated space to sals.sals in the case + where no line was specified. + + * blockframe.c, infrun.c: Modified to cache stack frames requested + to minimize accesses to subprocess. + +Tue Oct 4 15:10:39 1988 Randall Smith (randy at cream-of-wheat.ai.mit.edu) + + * config.gdb: Added sparc. + +Mon Oct 3 23:01:22 1988 Randall Smith (randy at cream-of-wheat.ai.mit.edu) + + * Makefile, blockframe.c, command.c, core.c, dbxread.c, defs.h, + expread.y, findvar.c, infcmd.c, inflow.c, infrun.c, sparc-pinsn.c, + m-sparc.h, sparc-def.c, printcmd.c, stack.c, symmisc.c, symseg.h, + valops.c, values.c: Did initial merge of sparc port. This will + not compile; have to do stack frame caching and finish port. + + * inflow.c, gdb.texinfo: `tty' now resets the controling terminal. + +Fri Sep 30 11:31:16 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * inferior.h, infcmd.c, infrun.c: Changed the variable + stop_random_signal to stopped_by_random signal to fit in better + with name conventions (variable is not a direction to the + proceed/resume set; it is information from it). + +Thu Sep 29 13:30:46 1988 Randall Smith (randy at cream-of-wheat.ai.mit.edu) + + * infcmd.c (finish_command): Value type of return value is now + whatever the function returns, not the type of the function (fixed + a bug in printing said value). + + * dbxread.c (read_dbx_symtab, process_symbol_for_psymtab): + Put *all* global symbols into misc_functions. This is what was + happening anyway, and we need it for find_pc_misc_function. + + ** This was eventually taken out, but I didn't mark it in the + ChangeLog. Oops. + + * dbxread.c (process_symbol_for_psymtab): Put every debugger + symbol which survives the top case except for constants on the + symchain. This means that all of these *won't* show up in misc + functions (this will be fixed once I make sure it's broken the way + it's supposed to be). + + * dbxread.c: Modified placement of debugger globals onto the hash + list; now we exclude the stuff after the colon and don't skip the + first character (debugger symbols don't have underscores). + + * dbxread.c: Killed debuginfo stuff with ifdef's. + +Wed Sep 28 14:31:51 1988 Randall Smith (randy at cream-of-wheat.ai.mit.edu) + + * symtab.h, dbxread.c: Modified to deal with BINCL, EINCL, and + EXCL symbols produced by the sun loader by adding a list of + pre-requisite partial_symtabs that each partial symtab needs. + + * symtab.h, dbxread.c, symtab.c, symmisc.c: Modified to avoid + doing a qsort on the local (static) psymbols for each file to + speed startup. This feature is not completely debugged, but it's + inclusion has forced the inclusion of another feature (dealing + with EINCL's, BINCL's and EXCL's) and so I'm going to go in and + deal with them. + + * dbxread.c (process_symbol_for_psymtab): Made sure that the class + of the symbol made it into the partial_symbol entry. + +Tue Sep 27 15:10:26 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * dbxread.c: Fixed bug; init_psymbol_list was not being called + with the right number of arguments (1). + + * dbxread.c: Put ifdef's around N_MAIN, N_M2C, and N_SCOPE to + allow compilation on a microvax. + + * config.gdb: Modified so that "config.gdb vax" would work. + + * dbxread.c, symtab.h, symmisc.h, symtab.c, source.c: Put in many + and varied hacks to speed up gdb startup including: A complete + rewrite of read_dbx_symtab, a modification of the partial_symtab + data type, deletion of select_source_symtab from + symbol_file_command, and optimiztion of the call to strcmp in + compare_psymbols. + +Thu Sep 22 11:08:54 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * dbxread.c (psymtab_to_symtab): Removed call to + init_misc_functions. + + * dbxread.c: Fixed enumeration type clash (used enum instead of + integer constant). + + * breakpoint.c: Fixed typo; lack of \ at end of line in middle of + string constant. + + * symseg.h: Fixed typo; lack of semicolon after structure + definition. + + * command.c, breakpoint.c, printcmd.c: Added cmdlist editing + functions to add commands with the abbrev flag set. Changed + help_cmd_list to recognize this flag and modified unset, + undisplay, and enable, disable, and delete breakpoints to have + this flag set. + +Wed Sep 21 13:34:19 1988 Randall Smith (randy at plantaris.ai.mit.edu) + + * breakpoint.c, infcmd.c, gdb.texinfo: Created "unset" as an alias + for delete, and changed "unset-environment" to be the + "environment" subcommand of "delete". + + * gdb.texinfo, valprint.c: Added documentation in the manual for + breaking the set-* commands into subcommands of set. Changed "set + maximum" to "set array-max". + + * main.c, printcmd.c, breakpoint.c: Moved the declaration of + command lists into main and setup a function in main initializing + them to guarrantee that they would be initialized before calling + any of the individual files initialize routines. + + * command.c (lookup_cmd): A null string subcommand is treated as + an unknown subcommand rather than an ambiguous one (eg. "set $x = + 1" will now work). + + * infrun.c (wait_for_inferior): Put in ifdef for Sony News in + check for trap by INNER_THAN macro. + + * eval.c (evaluate_subexp): Put in catch to keep the user from + attempting to call a non function as a function. + +Tue Sep 20 10:35:53 1988 Randall Smith (randy at oatmeal.ai.mit.edu) + + * dbxread.c (read_dbx_symtab): Installed code to keep track of + which global symbols did not have debugger symbols refering to + them, and recording these via record_misc_function. + + * dbxread.c: Killed code to check for extra global symbols in the + debugger symbol table. + + * printcmd.c, breakpoint.c: Modified help entries for several + commands to make sure that abbreviations were clearly marked and + that the right commands showed up in the help listings. + + * main.c, command.c, breakpoint.c, infcmd.c, printcmd.c, + valprint.c, defs.h: Modified help system to allow help on a class + name to show subcommands as well as commands and help on a command + to show *all* subcommands of that command. + +Fri Sep 16 16:51:19 1988 Randall Smith (randy at gluteus.ai.mit.edu) + + * breakpoint.c (_initialize_breakpoint): Made "breakpoints" + subcommands of enable, disable, and delete use class 0 (ie. they + show up when you do a help xxx now). + + * infcmd.c,printcmd,c,main.c,valprint.c: Changed the set-* + commands into subcommands of set. Created "set variable" for use + with variables whose names might conflict with other subcommands. + + * blockframe.c, dbxread.c, coffread.c, expread.y, source.c: + Fixed mostly minor (and one major one in block_for_pc) bugs + involving checking the partial_symtab_list when a scan through the + symtab_list fails. + +Wed Sep 14 12:02:05 1988 Randall Smith (randy at sugar-smacks.ai.mit.edu) + + * breakpoint.c, gdb.texinfo: Added enable breakpoints, disable + breakpoints and delete breakpoints as synonyms for enable, + disable, and delete. This seemed reasonable because of the + immeninent arrival of watchpoints & etc. + + * gdb.texinfo: Added enable display, disable display, and delete + display to manual. + +Tue Sep 13 16:53:56 1988 Randall Smith (randy at sugar-smacks.ai.mit.edu) + + * inferior.h, infrun.c, infcmd.c: Added variable + stop_random_signal to indicate when a proceed had been stopped by + an unexpected signal. Used this to determine (in normal_stop) + whether the current display point should be deleted. + + * valops.c: Fix to value_ind to check for reference before doing a + COERCE_ARRAY. + +Sun Jul 31 11:42:36 1988 Richard Stallman (rms at frosted-flakes.ai.mit.edu) + + * breakpoint.c (_initialize_breakpoint): Clean up doc for commands + that can now apply also to auto-displays. + + * coffread.c (record_line): Corrected a spazz in editing. + Also removed the two lines that assume line-numbers appear + only in increasing order. + +Tue Jul 26 22:19:06 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * expression.h, eval.c, expprint.c, printcmd.c, valarith.c, + valops.c, valprint.c, values.c, m-*.h: Changes for evaluating and + displaying 64-bit `long long' integers. Each machine must define + a LONGEST type, and a BUILTIN_TYPE_LONGEST. + + * symmisc.c: (print_symtab) check the status of the fopen and call + perror_with_name if needed. + +Thu Jul 21 00:56:11 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * Convex: core.c: changes required by Convex's SOFF format were + isolated in convex-dep.c. + +Wed Jul 20 21:26:10 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * coffread.c, core.c, expread.y, i386-pinsn.c, infcmd.c, inflow.c, + infrun.c, m-i386.h, main.c, remote.c, source.c, valops.c: + Improvements for the handling of the i386 and other machines + running USG. (Several of these files just needed extra header files + such as types.h.) utils.c: added bcopy, bcmp, bzero, getwd, list + of signals, and queue routines for USG systems. Added vfork macro + to i386 + + * printcmd.c, breakpoint.c: New commands to enable/disable + auto-displays. Also `delete display displaynumber' works like + `undisplay displaynumber'. + +Tue Jul 19 02:17:18 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * coffread.c: (coff_lookup_type) Wrong portion of type_vector was + being bzero'd after type_vector was reallocated. + + * printcmd.c: (delete_display) Check for a display chain before + attempting to delete a display. + + * core.c, *-dep.c (*-infdep moved to *-dep): machine-dependent + parts of core.c (core_file_command, exec_file_command) moved to + *-dep.c. + +Mon Jul 18 19:45:51 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * dbxread.c: typo in read_struct_type (missing '=') was causing a + C struct to be parsed as a C++ struct, resulting in a `invalid + character' message. + +Sun Jul 17 22:27:32 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * printcmd.c, symtab.c, valops.c, expread.y: When an expression is + read, the innermost block required to evaluate the expression is + saved in the global variable `innermost_block'. This information + is saved in the `block' field of an auto-display so that + expressions with inactive variables can be skipped. `info display' + tells the user which displays are active and which are not. New + fn `contained_in' returns nonzero if one block is contained within + another. + +Fri Jul 15 01:53:14 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * infrun.c, m-i386.h: Use macro TRAPS_EXPECTED to set number of + traps to skip when sh execs the program. Default is 2, m-i386.h + overrides this and sets to 4. + + * coffread.c, infrun.c: minor changes for the i386. May be able + to eliminate them with more general code. + + * default-infdep.c: #ifdef SYSTEMV, include header file types.h. + Also switched the order of signal.h and user.h, since System 5 + requires signal.h to come first. + + * core.c main.c, remote,c, source.c, inflow.c: #ifdef SYSTEMV, + include various header files. Usually types.h and fcntl.h. + + * utils.c: added queue routines needed by the i386 (and other sys + 5 machines). + + * sys5.c, regex.c, regex.h: new files for sys 5 systems. (The + regex files are simply links to /gp/gnu/lib.) + +Thu Jul 14 01:47:14 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * config.gdb, README: Provide a list of known machines when user + enters an invalid machine. New second arg is operating system, + currently only used with `sunos4' or `os4'. Entry for i386 added. + + * news-infdep.c: new file. + + * m-news.h: new version which deals with new bugs in news800's OS. + +Tue Jul 12 19:52:16 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * Makefile, *.c, munch, config.gdb, README: New initialization + scheme uses nm to find functions whose names begin with + `_initialize_'. Files `initialize.h', `firstfile.c', + `lastfile.c', `m-*init.h' no longer needed. + + * eval.c, symtab.c, valarith.c, valops.c, value.h, values.c: Bug + fixes from gdb+ 2.5.4. evaluate_subexp takes a new arg, type + expected. New fn value_virtual_fn_field. + +Mon Jul 11 00:48:49 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * core.c (read_memory): xfer_core_file was being called with an + extra argument (0) by read_memory. + + * core.c (read_memory), *-infdep.c (read_inferior_memory), + valops.c (value_at): read_memory and read_inferior_memory now work + like write_memory and write_inferior_memory in that errno is + checked after each ptrace and returned to the caller. Used in + value_at to detect references to addresses which are out of + bounds. Also core.c (xfer_core_file): return 1 if invalid + address, 0 otherwise. + + * inflow.c, <machine>-infdep.c: removed all calls to ptrace from + inflow.c and put them in machine-dependent files *-infdep.c. + +Sun Jul 10 19:19:36 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * symmisc.c: (read_symsegs) Accept only format number 2. Since + the size of the type structure changed when C++ support was added, + format 1 can no longer be used. + + * core.c, m-sunos4.h: (core_file_command) support for SunOS 4.0. + Slight change in the core structure. #ifdef SUNOS4. New file + m-sunos4.h. May want to change config.gdb also. + +Fri Jul 8 19:59:49 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * breakpoint.c: (break_command_1) Allow `break if condition' + rather than parsing `if' as a function name and returning an + error. + +Thu Jul 7 22:22:47 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * C++: valops.c, valprint.c, value.h, values.c: merged code to deal + with C++ expressions. + +Wed Jul 6 03:28:18 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * C++: dbxread.c: (read_dbx_symtab, condense_misc_bunches, + add_file_command) Merged code to read symbol information from + an incrementally linked file. symmisc.c: + (init_free_inclink_symtabs, free_inclink_symtabs) Cleanup + routines. + +Tue Jul 5 02:50:41 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * C++: symtab.c, breakpoint.c, source.c: Merged code to deal with + ambiguous line specifications. In C++ one can have overloaded + function names, so that `list classname::overloadedfuncname' + refers to several different lines, possibly in different files. + +Fri Jul 1 02:44:20 1988 Peter TerMaat (pete at corn-chex.ai.mit.edu) + + * C++: symtab.c: replaced lookup_symtab_1 and lookup_symtab_2 with + a modified lookup_symbol which checks for fields of the current + implied argument `this'. printcmd.c, source.c, symtab.c, + valops.c: Need to change callers once callers are + installed. + +Wed Jun 29 01:26:56 1988 Peter TerMaat (pete at frosted-flakes.ai.mit.edu) + + * C++: eval.c, expprint.c, expread.y, expression.h, valarith.c, + Merged code to deal with evaluation of user-defined operators, + member functions, and virtual functions. + binop_must_be_user_defined tests for user-defined binops, + value_x_binop calls the appropriate operator function. + +Tue Jun 28 02:56:42 1988 Peter TerMaat (pete at frosted-flakes.ai.mit.edu) + + * C++: Makefile: changed the echo: expect 101 shift/reduce conflicts + and 1 reduce/reduce conflict. + +Local Variables: +mode: indented-text +left-margin: 8 +fill-column: 74 +version-control: never +End: diff --git a/gnu/usr.bin/gdb/Gdbinit b/gnu/usr.bin/gdb/Gdbinit new file mode 100644 index 000000000000..bcacd5dc7e84 --- /dev/null +++ b/gnu/usr.bin/gdb/Gdbinit @@ -0,0 +1,15 @@ +echo Setting up the environment for debugging gdb.\n + +b fatal + +b info_command +commands + silent + return +end + +define rr + run +end + +set prompt (top-gdb) diff --git a/gnu/usr.bin/gdb/Makefile b/gnu/usr.bin/gdb/Makefile new file mode 100644 index 000000000000..550ed07a7575 --- /dev/null +++ b/gnu/usr.bin/gdb/Makefile @@ -0,0 +1,38 @@ +# @(#)Makefile 6.4 (Berkley) 5/6/91 + +PROG= gdb +GDBSRCS= blockframe.c breakpoint.c command.c copying.c core.c \ + cplus-dem.c dbxread.c environ.c eval.c expprint.c \ + expread.y findvar.c infcmd.c inflow.c infrun.c \ + main.c obstack.c printcmd.c regex.c remote.c \ + remote-sl.c source.c stack.c symmisc.c symtab.c \ + utils.c valarith.c valops.c valprint.c values.c \ + version.c +READLINESRCS= funmap.c history.c keymaps.c readline.c +SRCS= $(CONFIGSRCS) $(GDBSRCS) $(READLINESRCS) init.c +CFLAGS+= -I. -I$(.CURDIR) -I$(.CURDIR)/config -I$(.CURDIR)/readline \ + -DHAVE_VPRINTF -DVI_MODE -DKERNELDEBUG -DNEWVM +LDADD= -ltermcap +YFLAGS= +.PATH: $(.CURDIR)/config $(.CURDIR)/readline + +depend: + +.include "config/Makefile.$(MACHINE)" +.include <bsd.prog.mk> + +$(OBJS): param.h + +# +# Generate the constructor +# +init.c: $(CONFIGSRCS) $(GDBSRCS) $(READLINESRCS) + -((cd $(.CURDIR)/config; \ + egrep -h '^_initialize_[^ ]* *\(\)' $(CONFIGSRCS)); \ + (cd $(.CURDIR); egrep -h '^_initialize_[^ ]* *\(\)' $(GDBSRCS)); \ + (cd $(.CURDIR)/readline; \ + egrep -h '^_initialize_[^ ]* *\(\)' $(READLINESRCS))) | \ + (echo 'void initialize_all_files () {'; sed -e 's/$$/;/'; echo '}') \ + > init.c + +CLEANFILES+= init.c param.h diff --git a/gnu/usr.bin/gdb/Makefile.dist b/gnu/usr.bin/gdb/Makefile.dist new file mode 100644 index 000000000000..3cbc91f9786f --- /dev/null +++ b/gnu/usr.bin/gdb/Makefile.dist @@ -0,0 +1,371 @@ +/* This file should be run through the C preprocessor by config.gdb + to produce the Makefile. */ + +/* Define this to xgdb if you want to compile xgdb as well as gdb. */ +XGDB= +/* Place to install binaries. */ +bindir=/usr/local/bin +/* Place to install X binaries. */ +xbindir=$(bindir) + +/* System V: If you compile gdb with a compiler which uses the coff + encapsulation feature (this is a function of the compiler used, NOT + of the m-?.h file selected by config.gdb), you must make sure that + the GNU nm is the one that is used by munch. */ + +/* If you are compiling with GCC, make sure that either 1) You use the + -traditional flag, or 2) You have the fixed include files where GCC + can reach them. Otherwise the ioctl calls in inflow.c and readline.c + will be incorrectly compiled. The "fixincludes" script in the gcc + distribution will fix your include files up. */ +/* CC=gcc -traditional */ +CC=cc + +/* It is also possible that you will need to add -I/usr/include/sys to the + CFLAGS section if your system doesn't have fcntl.h in /usr/include (which + is where it should be according to Posix). */ + +YACC=bison -y -v +/* YACC=yacc */ +SHELL=/bin/sh +MAKE=make + +/* Set this up with gcc if you have gnu ld and the loader will print out + line numbers for undefinded refs. */ +/* CC-LD=gcc -static */ +CC-LD=${CC} + +/* If you are using the GNU C library, uncomment the following line. */ +/* HAVE_VPRINTF_DEFINE = -DHAVE_VPRINTF */ + +/* -I. for "#include <obstack.h>". Possibly regex.h also. */ + +/* M_CFLAGS, if defined, has system-dependent CFLAGS. */ +#if !defined(M_CFLAGS) +#define M_CFLAGS +#endif + +/* CFLAGS for both GDB and readline. */ +GLOBAL_CFLAGS = -g M_CFLAGS +CFLAGS = -I. ${HAVE_VPRINTF_DEFINE} ${GLOBAL_CFLAGS} +/* None of the things in CFLAGS will do any harm, and on some systems + (e.g. SunOS4) it is important to use the M_CFLAGS. */ +LDFLAGS = $(CFLAGS) + +/* + 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" + so that the dependencies work right. Similarly with REGEX and "regex.o". + You must define REGEX and REGEX1 on USG machines. + If your sysyem is missing alloca(), or, more likely, it's there but + it doesn't work, define ALLOCA & ALLOCA1 */ +OBSTACK = obstack.o +OBSTACK1 = obstack.o + +#ifdef M_REGEX +REGEX = M_REGEX +REGEX1 = M_REGEX +#else +REGEX = +REGEX1 = +#endif + +#ifdef M_ALLOCA +ALLOCA = M_ALLOCA +ALLOCA1 = M_ALLOCA +#else +ALLOCA = +ALLOCA1 = +#endif + +/* + define this to be "malloc.o" if you want to use the gnu malloc routine + (useful for debugging memory allocation problems in gdb). Otherwise, leave + it blank. */ +/* GNU_MALLOC = */ +GNU_MALLOC = malloc.o + +/* Flags to be used in compiling malloc.o + Specify range checking for storage allocation. */ +/* MALLOC_FLAGS = ${CFLAGS} */ +MALLOC_FLAGS = ${CFLAGS} -Drcheck -Dbotch=fatal_dump_core -DMSTATS + +/* Define SYSV if compiling on a system V or HP machine. */ +#ifdef M_SYSV +SYSV_DEFINE = -DSYSV +#else +SYSV_DEFINE = +#endif + +/* MUNCH_DEFINE should be -DSYSV if have System V-style nm, + or null if have BSD-style nm. */ +#ifdef M_BSD_NM +MUNCH_DEFINE = +#else +MUNCH_DEFINE = ${SYSV_DEFINE} +#endif + +/* Flags that describe where you can find the termcap library. + You may need to make other arrangements for USG. */ +TERMCAP = -ltermcap + +/* M_CLIBS, if defined, has system-dependent libs + For example, -lPW for System V to get alloca(). */ +#ifndef M_CLIBS +#define M_CLIBS +#endif +CLIBS = ${ADD_FILES} ${TERMCAP} M_CLIBS + +ADD_FILES = ${OBSTACK} ${REGEX} ${ALLOCA} ${GNU_MALLOC} +ADD_DEPS = ${OBSTACK1} ${REGEX1} ${ALLOCA1} ${GNU_MALLOC} + +SFILES = blockframe.c breakpoint.c dbxread.c coffread.c command.c core.c \ + environ.c eval.c expprint.c findvar.c infcmd.c inflow.c infrun.c \ + kdb-start.c main.c printcmd.c \ + remote.c source.c stack.c standalone.c stuff.c symmisc.c symtab.c \ + utils.c valarith.c valops.c valprint.c values.c version.c expread.y \ + xgdb.c + +DEPFILES = umax-dep.c gould-dep.c default-dep.c sun3-dep.c \ + sparc-dep.c hp9k320-dep.c hp300bsd-dep.c news-dep.c i386-dep.c \ + symmetry-dep.c convex-dep.c altos-dep.c isi-dep.c pyr-dep.c + +PINSNS = gld-pinsn.c i386-pinsn.c sparc-pinsn.c vax-pinsn.c m68k-pinsn.c \ + ns32k-pinsn.c convex-pinsn.c pyr-pinsn.c + +HFILES = command.h defs.h environ.h expression.h frame.h getpagesize.h \ + inferior.h symseg.h symtab.h value.h wait.h \ + a.out.encap.h a.out.gnu.h stab.gnu.h + +OPCODES = m68k-opcode.h pn-opcode.h sparc-opcode.h npl-opcode.h vax-opcode.h \ + ns32k-opcode.h convex-opcode.h pyr-opcode.h + +MFILES = m-hp9k320.h m-hp300bsd.h m-i386.h m-i386gas.h \ + m-i386-sv32.h m-i386g-sv32.h m-isi.h m-merlin.h \ + m-altos.h m-news.h m-newsos3.h m-npl.h m-pn.h \ + m-sparc.h m-sun2.h m-sun3.h m-sun2os4.h \ + m-sun3os4.h m-sun4os4.h m-umax.h m-vax.h m-symmetry.h m-convex.h \ + m-pyr.h + +/* This list of files really shouldn't be in this makefile, but I can't think + of any good way to get the readline makefile to tell us what files + to put in our tarfile. */ +READLINE = readline.c history.c funmap.c \ + emacs_keymap.c vi_keymap.c vi_mode.c keymaps.c \ + readline.h history.h keymaps.h chardefs.h \ + inc-readline.texinfo inc-history.texinfo \ + readline.texinfo history.texinfo \ + Makefile ChangeLog + +REMOTE_EXAMPLES = remote-sa.m68k.shar remote-multi.shar + +POSSLIBS = obstack.h obstack.c regex.c regex.h malloc.c alloca.c + +TESTS = testbpt.c testfun.c testrec.c testreg.c testregs.c + +OTHERS = Makefile.dist createtags munch config.gdb ChangeLog README TAGS \ + gdb.texinfo .gdbinit COPYING expread.tab.c stab.def \ + XGDB-README copying.c Projects Convex.notes copying.awk hp-include + +TAGFILES = ${SFILES} ${DEPFILES} ${PINSNS} ${HFILES} ${OPCODES} ${MFILES} \ + ${POSSLIBS} +TARFILES = ${TAGFILES} ${OTHERS} ${REMOTE_EXAMPLES} + +OBS = main.o blockframe.o breakpoint.o findvar.o stack.o source.o \ + values.o eval.o valops.o valarith.o valprint.o printcmd.o \ + symtab.o symmisc.o coffread.o dbxread.o infcmd.o infrun.o remote.o \ + command.o utils.o expread.o expprint.o pinsn.o environ.o version.o \ + copying.o ${READLINEOBS} + +TSOBS = core.o inflow.o dep.o + +NTSOBS = standalone.o + +TSSTART = /lib/crt0.o + +NTSSTART = kdb-start.o + +RL_LIB = readline/libreadline.a + +/* Do some fancy trickery to produce a line like + -DM_MAKEDEFINE="-DM_SYSV -DM_BSD_NM". +*/ +MD=M_MAKEDEFINE + +/* Avoid funny things that Sun's make throws in for us. */ +/* TARGET_ARCH is supposed to get around it putting in the machine type. + If the "things" up there really is plural, we'll need to do something + else as well. */ +/*.c.o: + ${CC} -c ${CFLAGS} $< */ +TARGET_ARCH= + +all: gdb $(XGDB) + +install: gdb $(XGDB) + cp gdb $(bindir)/gdb.new + mv $(bindir)/gdb.new $(bindir)/gdb + -if [ "$(XGDB)" = xgdb ]; then \ + cp xgdb $(xbindir)/xgdb.new; \ + mv $(xbindir)/xgdb.new $(xbindir)xgdb; \ + fi + +gdb : $(OBS) $(TSOBS) ${ADD_DEPS} ${RL_LIB} + rm -f init.c + ./munch ${MUNCH_DEFINE} $(OBS) $(TSOBS) > init.c + ${CC-LD} $(LDFLAGS) -o gdb init.c $(OBS) $(TSOBS) ${RL_LIB} $(CLIBS) + +/* This is useful when debugging GDB, because Unix doesn't let you run GDB + on itself without copying the executable. So "make gdb1" will make + gdb and put a copy in gdb1, and you can run it with "gdb gdb1". */ +gdb1 : gdb + cp gdb gdb1 + +Makefile : Makefile.dist + cp Makefile.dist tmp.c + $(CC) -E >Makefile tmp.c $(MD) "-DM_MAKEDEFINE=$(MD)" + -rm tmp.c +/* This did not work-- -Usparc became "-Usparc" became "-Usparc. + Or something like that. */ +/* $(CC) -E >Makefile tmp.c $(MD) "-DM_MAKEDEFINE=\"$(MD)\"" */ + +xgdb : $(OBS) $(TSOBS) xgdb.o ${ADD_DEPS} ${RL_LIB} + rm -f init.c + ./munch ${MUNCH_DEFINE} $(OBS) $(TSOBS) xgdb.o > init.c + $(CC-LD) $(LDFLAGS) -o xgdb init.c $(OBS) $(TSOBS) xgdb.o \ + -lXaw -lXmu -lXt -lX11 ${RL_LIB} $(CLIBS) + +/* Old (pre R3) xgdb comp. + $(CC-LD) $(LDFLAGS) -o xgdb init.c $(OBS) $(TSOBS) xgdb.o \ + -lXaw -lXt -lX11 $(CLIBS) */ + +kdb : $(NTSSTART) $(OBS) $(NTSOBS) ${ADD_DEPS} ${RL_LIB} + rm -f init.c + ./munch ${MUNCH_DEFINE} $(OBS) $(NTSOBS) > init.c + $(CC) $(LDFLAGS) -c init.c $(CLIBS) + ld -o kdb $(NTSSTART) $(OBS) $(NTSOBS) init.o ${RL_LIB} -lc $(CLIBS) + +/* If it can figure out the appropriate order, createtags will make sure + that the proper m-*, *-dep, *-pinsn, and *-opcode files come first + in the tags list. It will attempt to do the same for dbxread.c and + coffread.c. This makes using M-. on machine dependent routines much + easier. */ + +TAGS: ${TAGFILES} + createtags ${TAGFILES} +tags: TAGS + +gdb.tar: ${TARFILES} + rm -f gdb.tar + mkdir dist-gdb + cd dist-gdb ; for i in ${TARFILES} ; do ln -s ../$$i . ; done + mkdir dist-gdb/readline + cd dist-gdb/readline ; for i in ${READLINE} ; do ln -s ../../readline/$$i . ; done + tar chf gdb.tar dist-gdb + rm -rf dist-gdb + +/* Remove gdb.tar.Z so stupid compress doesn't ask whether we want to + overwrite it. compress -f is not what we want, because we do want + to know if compress would not make it smaller. */ +gdb.tar.Z: gdb.tar + if [ -f gdb.tar.Z ]; then rm -f gdb.tar.Z; else true; fi + compress gdb.tar + +clean: + rm -f ${OBS} ${TSOBS} ${NTSOBS} ${OBSTACK} ${REGEX} ${GNU_MALLOC} + rm -f init.c init.o + rm -f xgdb.o xgdb + rm -f gdb core gdb.tar gdb.tar.Z make.log + rm -f gdb[0-9] + cd readline ; make clean + +distclean: clean expread.tab.c TAGS + rm -f dep.c opcode.h param.h pinsn.c config.status + rm -f y.output yacc.acts yacc.tmp + rm -f ${TESTS} Makefile + +realclean: clean + rm -f expread.tab.c TAGS + rm -f dep.c opcode.h param.h pinsn.c config.status + rm -f Makefile + +xgdb.o : defs.h param.h symtab.h frame.h + +/* Make copying.c from COPYING */ +copying.c : COPYING copying.awk + awk -f copying.awk < COPYING > copying.c + +expread.tab.c : expread.y + @echo 'Expect 4 shift/reduce conflict.' + ${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 + +readline/libreadline.a : force_update + cd readline ; ${MAKE} "SYSV=${SYSV_DEFINE}" \ + "DEBUG_FLAGS=${GLOBAL_CFLAGS}" "CC=${CC}" libreadline.a + +force_update : + +/* Only useful if you are using the gnu malloc routines. */ +malloc.o : malloc.c + ${CC} -c ${MALLOC_FLAGS} malloc.c + +/* dep.o depends on config.status in case someone reconfigures gdb out + from under an already compiled gdb. */ +dep.o : dep.c config.status defs.h param.h frame.h inferior.h obstack.h \ + a.out.encap.h + +/* pinsn.o depends on config.status in case someone reconfigures gdb out + from under an already compiled gdb. */ +pinsn.o : pinsn.c config.status defs.h param.h symtab.h obstack.h symseg.h \ + frame.h opcode.h + +/* The rest of this is a standard dependencies list (hand edited output of + cpp -M). It does not include dependencies of .o files on .c files. */ +/* All files which depend on config.status also depend on param.h in case + someone reconfigures gdb out from under an already compiled gdb. */ +blockframe.o : defs.h param.h config.status symtab.h obstack.h symseg.h frame.h +breakpoint.o : defs.h param.h config.status symtab.h obstack.h symseg.h frame.h +coffread.o : defs.h param.h config.status +command.o : command.h defs.h +core.o : defs.h param.h config.status a.out.encap.h +dbxread.o : param.h config.status defs.h symtab.h obstack.h symseg.h a.out.encap.h \ + stab.gnu.h +environ.o : environ.h +eval.o : defs.h param.h config.status symtab.h obstack.h symseg.h value.h expression.h +expprint.o : defs.h symtab.h obstack.h symseg.h param.h config.status expression.h +findvar.o : defs.h param.h config.status symtab.h obstack.h symseg.h frame.h value.h +infcmd.o : defs.h param.h config.status symtab.h obstack.h symseg.h frame.h inferior.h \ + environ.h value.h +inflow.o : defs.h param.h config.status frame.h inferior.h +infrun.o : defs.h param.h config.status symtab.h obstack.h symseg.h frame.h inferior.h \ + wait.h +kdb-start.o : defs.h param.h config.status +main.o : defs.h command.h param.h config.status +malloc.o : getpagesize.h +obstack.o : obstack.h +printcmd.o : defs.h param.h config.status frame.h symtab.h obstack.h symseg.h value.h \ + expression.h +regex.o : regex.h +remote.o : defs.h param.h config.status frame.h inferior.h wait.h +source.o : defs.h symtab.h obstack.h symseg.h param.h config.status +stack.o : defs.h param.h config.status symtab.h obstack.h symseg.h frame.h +standalone.o : defs.h param.h config.status symtab.h obstack.h symseg.h frame.h \ + inferior.h wait.h +symmisc.o : defs.h symtab.h obstack.h symseg.h obstack.h +symtab.o : defs.h symtab.h obstack.h symseg.h param.h config.status obstack.h +utils.o : defs.h param.h config.status +valarith.o : defs.h param.h config.status symtab.h obstack.h symseg.h value.h expression.h +valops.o : defs.h param.h config.status symtab.h obstack.h symseg.h value.h frame.h \ + inferior.h +valprint.o : defs.h param.h config.status symtab.h obstack.h symseg.h value.h +values.o : defs.h param.h config.status symtab.h obstack.h symseg.h value.h + +robotussin.h : getpagesize.h +symtab.h : obstack.h symseg.h +a.out.encap.h : a.out.gnu.h + diff --git a/gnu/usr.bin/gdb/Projects b/gnu/usr.bin/gdb/Projects new file mode 100644 index 000000000000..f38f6c74e959 --- /dev/null +++ b/gnu/usr.bin/gdb/Projects @@ -0,0 +1,114 @@ + + Suggested projects for aspiring or current GDB hackers + ====================================================== + + (You should probably chat with kingdon@ai.mit.edu to make sure that + no one else is doing the project you chose). + +Add watchpoints (break if a memory location changes). This would +usually have to involve constant single stepping, but occasionally +there is operating system support which gdb should be able to cleanly +use (e.g. on the 80386, there are 4 debug registers. By ptracing an +address into them, you can get a trap on writes or on reads and +writes). + +Rewrite proceed, wait_for_inferior, and normal_stop to clean them up. +Suggestions: + + 1) Make each test in wait_for_inferior a seperate subroutine + call. + 2) Combine wait_for_inferior and normal_stop to clean up + communication via global variables. + 3) See if you can find some way to clean up the global + variables that are used; possibly group them by data flow + and information content? + +Work out some kind of way to allow running the inferior to be done as +a sub-execution of, eg. breakpoint command lists. Currently running +the inferior interupts any command list execution. This would require +some rewriting of wait_for_inferior & friends, and hence should +probably be done in concert with the above. + +Add function arguments to gdb user defined functions. + +Add convenience variables that refer to exec file, symbol file, +selected frame source file, selected frame function, selected frame +line number, etc. + +Add a "suspend" subcommand of the "continue" command to suspend gdb +while continuing execution of the subprocess. Useful when you are +debugging servers and you want to dodge out and initiate a connection +to a server running under gdb. + +Make "handle" understand symbolic signal names. + +Work out and implement a reasonably general mechanism for multi-threaded +processies. There are parts of one implemented in convex-dep.c, if +you want an example. + +A standalone version of gdb on the i386 exists. Anyone who wants to +do some serious working cleaning it up and making it a general +standalone gdb should contact pace@wheaties.ai.mit.edu. + +Add stab information to allow reasonable debugging of inline functions +(possibly they should show up on a stack backtrace? With a note +indicating that they weren't "real"?). + +Implement support for specifying arbitrary locations of stack frames +(in practice, this usually requires specification of both the top and +bottom of the stack frame (fp and sp), since you *must* retrieve the +pc that was saved in the innermost frame). + +Modify the naked "until" command to step until past the current source +line, rather than past the current pc value. This is tricky simply +because the low level routines have no way of specifying a multi-line +step range, and there is no way of saying "don't print stuff when we +stop" from above (otherwise could just call step many times). + +Modify the handling of symbols grouped through BINCL/EINCL stabs to +allocate a partial symtab for each BINCL/EINCL grouping. This will +seriously decrease the size of inter-psymtab dependencies and hence +lessen the amount that needs to be read in when a new source file is +accessed. + +Work out some method of saving breakpoints across the reloading of an +executable. Probably this should be by saving the commands by which +the breakpoints were set and re-executing them (as text locations may +change). + +Do an "x/i $pc" after each stepi or nexti. + +Modify all of the disassemblers to use printf_filtered to get correct +more filtering. + +Modify gdb to work correctly with Pascal. + +Rewrite macros that handle frame chaining and frameless functions. +They should be able to tell the difference between start, main, and a +frameless function called from main. + +Work out what information would need to be included in an executable +by the compiler to allow gdb to debug functions which do not have a +frame pointer. Modify gdb and gcc to do this. + +When `attached' to a program (via either OS support or remote +debugging), gdb should arrange to catch signals which the terminal +might send, as it is unlikely that the program will be able to notice +them. SIGINT and SIGTSTP are obvious examples. + +Enhance the gdb manual with extra examples where needed. + +Arrange for list_command not to use decode_line_1 and thus not require +symbols to be read in simply to read a source file. + +Problem in xgdb; the readline library needs the terminal in CBREAK +mode for command line editing, but this makes it difficult to dispatch +on button presses. Possible solution: use a define to replace getc in +readline.c with a routine that does button dispatches. You should +probably see XGDB-README before you fiddle with XGDB. Also, someone +is implementing a new xgdb; it may not be worth while fiddling with +the old one. + +# Local Variables: +# mode: text +# End: diff --git a/gnu/usr.bin/gdb/README.gnu b/gnu/usr.bin/gdb/README.gnu new file mode 100644 index 000000000000..fa54dec236fd --- /dev/null +++ b/gnu/usr.bin/gdb/README.gnu @@ -0,0 +1,142 @@ +This is GDB, the GNU source-level debugger, presently running under un*x. + +Before compiling GDB, you must tell GDB what kind of machine you are +running on. To do this, type `config.gdb machine', where machine is +something like `vax' or `sun2'. For a list of valid machine types, +type `config.gdb'. + +Normally config.gdb edits the makefile as necessary. If you have to +edit the makefile on a standard machine listed in config.gdb this +should be considered a bug and reported as such. + +Once these files are set up, just `make' will do everything, +producing an executable `gdb' in this directory. + +If you want a new (current to this release) version of the manual, you +will have to use the gdb.texinfo file provided with this distribution. +The gdb.texinfo file requires the texinfo-format-buffer command from +emacs 18.55 or later. + +About languages other than C... + +C++ support has been integrated into gdb. GDB should work with +FORTRAN programs (if you have problem, please send a bug report), but +I am not aware of anyone who is working on getting it to use the +syntax of any language other than C or C++. Pascal programs which use +sets, subranges, file variables, or nested functions will not +currently work. + +About -gg format... + +Currently GDB version 3.x does *not* support GCC's -gg format. This +is because it (in theory) has fast enough startup on dbx debugging +format object files that -gg format is unnecessary (and hence +undesirable, since it wastes space and processing power in gcc). I +would like to hear people's opinions on the amount of time currently +spent in startup; is it fast enough? + +About remote debugging... + +The two files remote-multi.shar and remote-sa.m68k.shar contain two +examples of a remote stub to be used with remote.c. The the -multi +file is a general stub that can probably be running on various +different flavors of unix to allow debugging over a serial line from +one machine to another. The remote-sa.m68k.shar is designed to run +standalone on a 68k type cpu and communicate properley with the +remote.c stub over a serial line. + +About reporting bugs... + +The correct address for reporting bugs found with gdb is +"bug-gdb@prep.ai.mit.edu". Please send all bugs to that address. + +About xgdb... + +xgdb.c was provided to us by the user community; it is not an integral +part of the gdb distribution. The problem of providing visual +debugging support on top of gdb is peripheral to the GNU project and +(at least right now) we can't afford to put time into it. So while we +will be happy to incorporate user fixes to xgdb.c, we do not guarantee +that it will work and we will not fix bugs reported in it. Someone is +working on writing a new XGDB, so improving (e.g. by fixing it so that +it will work, if it doesn't currently) the current one is not worth it. + +For those intersted in auto display of source and the availability of +an editor while debugging I suggest trying gdb-mode in gnu-emacs. +Comments on this mode are welcome. + +About the machine-dependent files... + +m-<machine>.h (param.h is a link to this file). +This file contains macro definitions that express information +about the machine's registers, stack frame format and instructions. + +<machine>-opcode.h (opcode.h is a link to this file). +<machine>-pinsn.c (pinsn.c is a link to this file). +These files contain the information necessary to print instructions +for your cpu type. + +<machine>-dep.c (dep.c is a link to this file). +Those routines which provide a low level interface to ptrace and which +tend to be machine-dependent. (The machine-independent routines are in +`infrun.c' and `inflow.c') + +About writing code for GDB... + +We appreciate having users contribute code that is of general use, but +for it to be included in future GDB releases it must be cleanly +written. We do not want to include changes that will needlessly make future +maintainance difficult. It is not much harder to do things right, and +in the long term it is worth it to the GNU project, and probably to +you individually as well. + +Please code according to the GNU coding standards. If you do not have +a copy, you can request one by sending mail to gnu@prep.ai.mit.edu. + +Please try to avoid making machine-specific changes to +machine-independent files (i.e. all files except "param.h" and +"dep.c". "pinsn.c" and "opcode.h" are processor-specific but not +operating system-dependent). If this is unavoidable, put a hook in +the machine-independent file which calls a (possibly) +machine-dependent macro (for example, the IGNORE_SYMBOL macro can be +used for any symbols which need to be ignored on a specific machine. +Calling IGNORE_SYMBOL in dbxread.c is a lot cleaner than a maze of #if +defined's). The machine-independent code should do whatever "most" +machines want if the macro is not defined in param.h. Using #if +defined can sometimes be OK (e.g. SET_STACK_LIMIT_HUGE) but should be +conditionalized on a specific feature of an operating system (set in +param.h) rather than something like #if defined(vax) or #if +defined(SYSV). + +It is better to replace entire routines which may be system-specific, +rather than put in a whole bunch of hooks which are probably not going +to be helpful for any purpose other than your changes. For example, +if you want to modify dbxread.c to deal with DBX debugging symbols +which are in COFF files rather than BSD a.out files, do something +along the lines of a macro GET_NEXT_SYMBOL, which could have +different definitions for COFF and a.out, rather than trying to put +the necessary changes throughout all the code in dbxread.c that +currently assumes BSD format. + +Please avoid duplicating code. For example, if something needs to be +changed in read_inferior_memory, it is very painful because there is a +copy in every dep.c file. The correct way to do this is to put (in +this case) the standard ptrace interfaces in a separate file ptrace.c, +which is used by all systems which have ptrace. ptrace.c would deal +with variations between systems the same way any system-independent +file would (hooks, #if defined, etc.). + +About debugging gdb with itself... + +You probably want to do a "make TAGS" after you configure your +distribution; this will put the machine dependent routines for your +local machine where they will be accessed first by a M-period . + +Also, make sure that you've compiled gdb with your local cc or taken +appropriate precautions regarding ansification of include files. See +the Makefile for more information. + +The "info" command, when executed without a subcommand in a gdb being +debugged by gdb, will pop you back up to the top level gdb. See +.gdbinit for more details. + diff --git a/gnu/usr.bin/gdb/XGdbinit.samp b/gnu/usr.bin/gdb/XGdbinit.samp new file mode 100644 index 000000000000..a99f10695606 --- /dev/null +++ b/gnu/usr.bin/gdb/XGdbinit.samp @@ -0,0 +1,15 @@ +button "show" push-to-file %S +button "back" pop-file +button "break in" break %S +button "break at" break %l +button delete delete %b%e +button backtrace +button up +button down +button print print %E +button print* print *(%E) +button next +button step +button "do upto" until %l%e +button finish +button continue cont%e diff --git a/gnu/usr.bin/gdb/Xgdb.ad b/gnu/usr.bin/gdb/Xgdb.ad new file mode 100644 index 000000000000..5f9fe9920b49 --- /dev/null +++ b/gnu/usr.bin/gdb/Xgdb.ad @@ -0,0 +1,8 @@ +Xgdb*geometry: 580x874-0+28 +Xgdb*src*scrollVertical: whenneeded +Xgdb*src*scrollHorizontal: whenneeded +Xgdb*src*wrap: never +Xgdb*src*editType: read +Xgdb*frame.buttons.allowResize: true +Xgdb*frame.buttons.skipAdjust: true +Xgdb*frame*showGrip: false diff --git a/gnu/usr.bin/gdb/blockframe.c b/gnu/usr.bin/gdb/blockframe.c new file mode 100644 index 000000000000..236d1cdccfec --- /dev/null +++ b/gnu/usr.bin/gdb/blockframe.c @@ -0,0 +1,622 @@ +/*- + * This code is derived from software copyrighted by the Free Software + * Foundation. + * + * Modified 1991 by Donn Seeley at UUNET Technologies, Inc. + * Modified 1990 by Van Jacobson at Lawrence Berkeley Laboratory. + */ + +#ifndef lint +static char sccsid[] = "@(#)blockframe.c 6.4 (Berkeley) 5/11/91"; +#endif /* not lint */ + +/* Get info from stack frames; + convert between frames, blocks, functions and pc values. + Copyright (C) 1986, 1987, 1988, 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "defs.h" +#include "param.h" +#include "symtab.h" +#include "frame.h" + +#include <obstack.h> + +#if defined(NEWVM) && defined(KERNELDEBUG) +#include <sys/param.h> /* XXX for FRAME_CHAIN_VALID */ +#endif + +/* Start and end of object file containing the entry point. + STARTUP_FILE_END is the first address of the next file. + This file is assumed to be a startup file + and frames with pc's inside it + are treated as nonexistent. + + Setting these variables is necessary so that backtraces do not fly off + the bottom of the stack. */ +CORE_ADDR startup_file_start; +CORE_ADDR startup_file_end; + +/* Is ADDR outside the startup file? */ +int +outside_startup_file (addr) + CORE_ADDR addr; +{ + return !(addr >= startup_file_start && addr < startup_file_end); +} + +/* Address of innermost stack frame (contents of FP register) */ + +static FRAME current_frame; + +struct block *block_for_pc (); +CORE_ADDR get_pc_function_start (); + +/* + * Cache for frame addresses already read by gdb. Valid only while + * inferior is stopped. Control variables for the frame cache should + * be local to this module. + */ +struct obstack frame_cache_obstack; + +/* Return the innermost (currently executing) stack frame. */ + +FRAME +get_current_frame () +{ + /* We assume its address is kept in a general register; + param.h says which register. */ + + return current_frame; +} + +void +set_current_frame (frame) + FRAME frame; +{ + current_frame = frame; +} + +FRAME +create_new_frame (addr, pc) + FRAME_ADDR addr; + CORE_ADDR pc; +{ + struct frame_info *fci; /* Same type as FRAME */ + + fci = (struct frame_info *) + obstack_alloc (&frame_cache_obstack, + sizeof (struct frame_info)); + + /* Arbitrary frame */ + fci->next = (struct frame_info *) 0; + fci->prev = (struct frame_info *) 0; + fci->frame = addr; + fci->next_frame = 0; /* Since arbitrary */ + fci->pc = pc; + +#ifdef INIT_EXTRA_FRAME_INFO + INIT_EXTRA_FRAME_INFO (fci); +#endif + + return fci; +} + +/* Return the frame that called FRAME. + If FRAME is the original frame (it has no caller), return 0. */ + +FRAME +get_prev_frame (frame) + FRAME frame; +{ + /* We're allowed to know that FRAME and "struct frame_info *" are + the same */ + return get_prev_frame_info (frame); +} + +/* Return the frame that FRAME calls (0 if FRAME is the innermost + frame). */ + +FRAME +get_next_frame (frame) + FRAME frame; +{ + /* We're allowed to know that FRAME and "struct frame_info *" are + the same */ + return frame->next; +} + +/* + * Flush the entire frame cache. + */ +void +flush_cached_frames () +{ + /* Since we can't really be sure what the first object allocated was */ + obstack_free (&frame_cache_obstack, 0); + obstack_init (&frame_cache_obstack); + + current_frame = (struct frame_info *) 0; /* Invalidate cache */ +} + +/* Return a structure containing various interesting information + about a specified stack frame. */ +/* How do I justify including this function? Well, the FRAME + identifier format has gone through several changes recently, and + it's not completely inconceivable that it could happen again. If + it does, have this routine around will help */ + +struct frame_info * +get_frame_info (frame) + FRAME frame; +{ + return frame; +} + +/* If a machine allows frameless functions, it should define a macro + FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) in param.h. FI is the struct + frame_info for the frame, and FRAMELESS should be set to nonzero + if it represents a frameless function invocation. */ + +/* Many machines which allow frameless functions can detect them using + this macro. Such machines should define FRAMELESS_FUNCTION_INVOCATION + to just call this macro. */ +#define FRAMELESS_LOOK_FOR_PROLOGUE(FI, FRAMELESS) \ +{ \ + CORE_ADDR func_start, after_prologue; \ + func_start = (get_pc_function_start ((FI)->pc) + \ + FUNCTION_START_OFFSET); \ + if (func_start) \ + { \ + after_prologue = func_start; \ + SKIP_PROLOGUE (after_prologue); \ + (FRAMELESS) = (after_prologue == func_start); \ + } \ + else \ + /* If we can't find the start of the function, we don't really */ \ + /* know whether the function is frameless, but we should be */ \ + /* able to get a reasonable (i.e. best we can do under the */ \ + /* circumstances) backtrace by saying that it isn't. */ \ + (FRAMELESS) = 0; \ +} + +/* Return a structure containing various interesting information + about the frame that called NEXT_FRAME. Returns NULL + if there is no such frame. */ + +struct frame_info * +get_prev_frame_info (next_frame) + FRAME next_frame; +{ + FRAME_ADDR address; + struct frame_info *prev; + int fromleaf = 0; + + /* If the requested entry is in the cache, return it. + Otherwise, figure out what the address should be for the entry + we're about to add to the cache. */ + + if (!next_frame) + { + if (!current_frame) + { + if (!have_inferior_p () && !have_core_file_p ()) + fatal ("get_prev_frame_info: Called before cache primed. \"Shouldn't happen.\""); + else + error ("No inferior or core file."); + } + + return current_frame; + } + + /* If we have the prev one, return it */ + if (next_frame->prev) + return next_frame->prev; + + /* On some machines it is possible to call a function without + setting up a stack frame for it. On these machines, we + define this macro to take two args; a frameinfo pointer + identifying a frame and a variable to set or clear if it is + or isn't leafless. */ +#ifdef FRAMELESS_FUNCTION_INVOCATION + /* Still don't want to worry about this except on the innermost + frame. This macro will set FROMLEAF if NEXT_FRAME is a + frameless function invocation. */ + if (!(next_frame->next)) + { + FRAMELESS_FUNCTION_INVOCATION (next_frame, fromleaf); + if (fromleaf) + address = next_frame->frame; + } +#endif + + if (!fromleaf) + { + /* Two macros defined in param.h specify the machine-dependent + actions to be performed here. + First, get the frame's chain-pointer. + If that is zero, the frame is the outermost frame or a leaf + called by the outermost frame. This means that if start + calls main without a frame, we'll return 0 (which is fine + anyway). + + Nope; there's a problem. This also returns when the current + routine is a leaf of main. This is unacceptable. We move + this to after the ffi test; I'd rather have backtraces from + start go curfluy than have an abort called from main not show + main. */ + address = FRAME_CHAIN (next_frame); + if (!FRAME_CHAIN_VALID (address, next_frame)) + return 0; + /* If this frame is a leaf, this will be superceeded by the + code below. */ + address = FRAME_CHAIN_COMBINE (address, next_frame); + } + if (address == 0) + return 0; + + prev = (struct frame_info *) + obstack_alloc (&frame_cache_obstack, + sizeof (struct frame_info)); + + if (next_frame) + next_frame->prev = prev; + prev->next = next_frame; + prev->prev = (struct frame_info *) 0; + prev->frame = address; + prev->next_frame = prev->next ? prev->next->frame : 0; + +#ifdef INIT_EXTRA_FRAME_INFO + INIT_EXTRA_FRAME_INFO(prev); +#endif + + /* This entry is in the frame queue now, which is good since + FRAME_SAVED_PC may use that queue to figure out it's value + (see m-sparc.h). We want the pc saved in the inferior frame. */ + prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (next_frame) : + next_frame ? FRAME_SAVED_PC (next_frame) : read_pc ()); + + return prev; +} + +CORE_ADDR +get_frame_pc (frame) + FRAME frame; +{ + struct frame_info *fi; + fi = get_frame_info (frame); + return fi->pc; +} + +/* Find the addresses in which registers are saved in FRAME. */ + +void +get_frame_saved_regs (frame_info_addr, saved_regs_addr) + struct frame_info *frame_info_addr; + struct frame_saved_regs *saved_regs_addr; +{ + FRAME_FIND_SAVED_REGS (frame_info_addr, *saved_regs_addr); +} + +/* Return the innermost lexical block in execution + in a specified stack frame. The frame address is assumed valid. */ + +struct block * +get_frame_block (frame) + FRAME frame; +{ + struct frame_info *fi; + CORE_ADDR pc; + + fi = get_frame_info (frame); + + pc = fi->pc; + if (fi->next_frame != 0) + /* We are not in the innermost frame. We need to subtract one to + get the correct block, in case the call instruction was the + last instruction of the block. If there are any machines on + which the saved pc does not point to after the call insn, we + probably want to make fi->pc point after the call insn anyway. */ + --pc; + return block_for_pc (pc); +} + +struct block * +get_current_block () +{ + return block_for_pc (read_pc ()); +} + +CORE_ADDR +get_pc_function_start (pc) + CORE_ADDR pc; +{ + register struct block *bl = block_for_pc (pc); + register struct symbol *symbol; + if (bl == 0 || (symbol = block_function (bl)) == 0) + { + register int misc_index = find_pc_misc_function (pc); + if (misc_index >= 0) + return misc_function_vector[misc_index].address; + return 0; + } + bl = SYMBOL_BLOCK_VALUE (symbol); + return BLOCK_START (bl); +} + +/* Return the symbol for the function executing in frame FRAME. */ + +struct symbol * +get_frame_function (frame) + FRAME frame; +{ + register struct block *bl = get_frame_block (frame); + if (bl == 0) + return 0; + return block_function (bl); +} + +/* Return the innermost lexical block containing the specified pc value, + or 0 if there is none. */ + +extern struct symtab *psymtab_to_symtab (); + +struct block * +block_for_pc (pc) + register CORE_ADDR pc; +{ + register struct block *b; + register int bot, top, half; + register struct symtab *s; + register struct partial_symtab *ps; + struct blockvector *bl; + + /* First search all symtabs for one whose file contains our pc */ + + for (s = symtab_list; s; s = s->next) + { + bl = BLOCKVECTOR (s); + b = BLOCKVECTOR_BLOCK (bl, 0); + if (BLOCK_START (b) <= pc + && BLOCK_END (b) > pc) + break; + } + + if (s == 0) + for (ps = partial_symtab_list; ps; ps = ps->next) + { + if (ps->textlow <= pc + && ps->texthigh > pc) + { + if (ps->readin) + fatal ("Internal error: pc found in readin psymtab and not in any symtab."); + s = psymtab_to_symtab (ps); + bl = BLOCKVECTOR (s); + b = BLOCKVECTOR_BLOCK (bl, 0); + break; + } + } + + if (s == 0) + return 0; + + /* Then search that symtab for the smallest block that wins. */ + /* Use binary search to find the last block that starts before PC. */ + + bot = 0; + top = BLOCKVECTOR_NBLOCKS (bl); + + while (top - bot > 1) + { + half = (top - bot + 1) >> 1; + b = BLOCKVECTOR_BLOCK (bl, bot + half); + if (BLOCK_START (b) <= pc) + bot += half; + else + top = bot + half; + } + + /* Now search backward for a block that ends after PC. */ + + while (bot >= 0) + { + b = BLOCKVECTOR_BLOCK (bl, bot); + if (BLOCK_END (b) > pc) + return b; + bot--; + } + + return 0; +} + +/* Return the function containing pc value PC. + Returns 0 if function is not known. */ + +struct symbol * +find_pc_function (pc) + CORE_ADDR pc; +{ + register struct block *b = block_for_pc (pc); + if (b == 0) + return 0; + return block_function (b); +} + +/* Finds the "function" (text symbol) that is smaller than PC + but greatest of all of the potential text symbols. Sets + *NAME and/or *ADDRESS conditionally if that pointer is non-zero. + Returns 0 if it couldn't find anything, 1 if it did. On a zero + return, *NAME and *ADDRESS are always set to zero. On a 1 return, + *NAME and *ADDRESS contain real information. */ + +int +find_pc_partial_function (pc, name, address) + CORE_ADDR pc; + char **name; + CORE_ADDR *address; +{ + struct partial_symtab *pst = find_pc_psymtab (pc); + struct symbol *f; + int miscfunc; + struct partial_symbol *psb; + + if (pst) + { + if (pst->readin) + { + /* The information we want has already been read in. + We can go to the already readin symbols and we'll get + the best possible answer. */ + f = find_pc_function (pc); + if (!f) + { + return_error: + /* No availible symbol. */ + if (name != 0) + *name = 0; + if (address != 0) + *address = 0; + return 0; + } + + if (name) + *name = SYMBOL_NAME (f); + if (address) + *address = BLOCK_START (SYMBOL_BLOCK_VALUE (f)); + return 1; + } + + /* Get the information from a combination of the pst + (static symbols), and the misc function vector (extern + symbols). */ + miscfunc = find_pc_misc_function (pc); + psb = find_pc_psymbol (pst, pc); + + if (!psb && miscfunc == -1) + { + goto return_error; + } + if (!psb + || (miscfunc != -1 + && (SYMBOL_VALUE(psb) + < misc_function_vector[miscfunc].address))) + { + if (address) + *address = misc_function_vector[miscfunc].address; + if (name) + *name = misc_function_vector[miscfunc].name; + return 1; + } + else + { + if (address) + *address = SYMBOL_VALUE (psb); + if (name) + *name = SYMBOL_NAME (psb); + return 1; + } + } + else + /* Must be in the misc function stuff. */ + { + miscfunc = find_pc_misc_function (pc); + if (miscfunc == -1) + goto return_error; + if (address) + *address = misc_function_vector[miscfunc].address; + if (name) + *name = misc_function_vector[miscfunc].name; + return 1; + } +} + +/* Find the misc function whose address is the largest + while being less than PC. Return its index in misc_function_vector. + Returns -1 if PC is not in suitable range. */ + +int +find_pc_misc_function (pc) + register CORE_ADDR pc; +{ + register int lo = 0; + register int hi = misc_function_count-1; + register int new; + register int distance; + + /* Note that the last thing in the vector is always _etext. */ + /* Actually, "end", now that non-functions + go on the misc_function_vector. */ + + /* 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) + return -1; + + /* Note that the following search will not return hi if + pc == misc_function_vector[hi].address. If "end" points to the + first unused location, this is correct and the above test + simply needs to be changed to + "pc >= misc_function_vector[hi].address". */ + do { + new = (lo + hi) >> 1; + distance = misc_function_vector[new].address - pc; + if (distance == 0) + return new; /* an exact match */ + else if (distance > 0) + hi = new; + else + lo = new; + } while (hi-lo != 1); + + /* if here, we had no exact match, so return the lower choice */ + return lo; +} + +/* Return the innermost stack frame executing inside of the specified block, + or zero if there is no such frame. */ + +FRAME +block_innermost_frame (block) + struct block *block; +{ + struct frame_info *fi; + register FRAME frame; + register CORE_ADDR start = BLOCK_START (block); + register CORE_ADDR end = BLOCK_END (block); + + frame = 0; + while (1) + { + frame = get_prev_frame (frame); + if (frame == 0) + return 0; + fi = get_frame_info (frame); + if (fi->pc >= start && fi->pc < end) + return frame; + } +} + +void +_initialize_blockframe () +{ + obstack_init (&frame_cache_obstack); +} diff --git a/gnu/usr.bin/gdb/breakpoint.c b/gnu/usr.bin/gdb/breakpoint.c new file mode 100644 index 000000000000..b515ed3f874f --- /dev/null +++ b/gnu/usr.bin/gdb/breakpoint.c @@ -0,0 +1,1383 @@ +/*- + * This code is derived from software copyrighted by the Free Software + * Foundation. + * + * Modified 1991 by Donn Seeley at UUNET Technologies, Inc. + * Modified 1990 by Van Jacobson at Lawrence Berkeley Laboratory. + */ + +#ifndef lint +static char sccsid[] = "@(#)breakpoint.c 6.3 (Berkeley) 5/8/91"; +#endif /* not lint */ + +/* Everything about breakpoints, for GDB. + Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <stdio.h> +#include "defs.h" +#include "param.h" +#include "symtab.h" +#include "frame.h" + +/* This is the sequence of bytes we insert for a breakpoint. */ + +static char break_insn[] = BREAKPOINT; + +/* States of enablement of breakpoint. + `temporary' means disable when hit. + `delete' means delete when hit. */ + +enum enable { disabled, enabled, temporary, delete}; + +/* Not that the ->silent field is not currently used by any commands + (though the code is in there if it was to be and set_raw_breakpoint + does set it to 0). I implemented it because I thought it would be + useful for a hack I had to put in; I'm going to leave it in because + I can see how there might be times when it would indeed be useful */ + +struct breakpoint +{ + struct breakpoint *next; + /* Number assigned to distinguish breakpoints. */ + int number; + /* Address to break at. */ + CORE_ADDR address; + /* Line number of this address. Redundant. */ + int line_number; + /* Symtab of file of this address. Redundant. */ + struct symtab *symtab; + /* Zero means disabled; remember the info but don't break here. */ + enum enable enable; + /* Non-zero means a silent breakpoint (don't print frame info + if we stop here). */ + unsigned char silent; + /* Number of stops at this breakpoint that should + be continued automatically before really stopping. */ + int ignore_count; + /* "Real" contents of byte where breakpoint has been inserted. + Valid only when breakpoints are in the program. */ + char shadow_contents[sizeof break_insn]; + /* Nonzero if this breakpoint is now inserted. */ + char inserted; + /* Nonzero if this is not the first breakpoint in the list + for the given address. */ + char duplicate; + /* Chain of command lines to execute when this breakpoint is hit. */ + struct command_line *commands; + /* Stack depth (address of frame). If nonzero, break only if fp + equals this. */ + FRAME_ADDR frame; + /* Conditional. Break only if this expression's value is nonzero. */ + struct expression *cond; +}; + +#define ALL_BREAKPOINTS(b) for (b = breakpoint_chain; b; b = b->next) + +/* Chain of all breakpoints defined. */ + +struct breakpoint *breakpoint_chain; + +/* Number of last breakpoint made. */ + +static int breakpoint_count; + +/* Default address, symtab and line to put a breakpoint at + for "break" command with no arg. + if default_breakpoint_valid is zero, the other three are + not valid, and "break" with no arg is an error. + + This set by print_stack_frame, which calls set_default_breakpoint. */ + +int default_breakpoint_valid; +CORE_ADDR default_breakpoint_address; +struct symtab *default_breakpoint_symtab; +int default_breakpoint_line; + +/* Remaining commands (not yet executed) + of last breakpoint hit. */ + +struct command_line *breakpoint_commands; + +static void delete_breakpoint (); +void clear_momentary_breakpoints (); +void breakpoint_auto_delete (); + +/* Flag indicating extra verbosity for xgdb. */ +extern int xgdb_verbose; + +/* condition N EXP -- set break condition of breakpoint N to EXP. */ + +static void +condition_command (arg, from_tty) + char *arg; + int from_tty; +{ + register struct breakpoint *b; + register char *p; + register int bnum; + register struct expression *expr; + + if (arg == 0) + error_no_arg ("breakpoint number"); + + p = arg; + while (*p >= '0' && *p <= '9') p++; + if (p == arg) + /* There is no number here. (e.g. "cond a == b"). */ + error_no_arg ("breakpoint number"); + bnum = atoi (arg); + + ALL_BREAKPOINTS (b) + if (b->number == bnum) + { + if (b->cond) + { + free (b->cond); + b->cond = 0; /* parse_c_1 can leave this unchanged. */ + } + if (*p == 0) + { + b->cond = 0; + if (from_tty) + printf ("Breakpoint %d now unconditional.\n", bnum); + } + else + { + if (*p != ' ' && *p != '\t') + error ("Arguments must be an integer (breakpoint number) and an expression."); + + /* Find start of expression */ + while (*p == ' ' || *p == '\t') p++; + + arg = p; + b->cond = (struct expression *) parse_c_1 (&arg, block_for_pc (b->address), 0); + if (*arg) + error ("Junk at end of expression"); + } + return; + } + + error ("No breakpoint number %d.", bnum); +} + +static void +commands_command (arg, from_tty) + char *arg; + int from_tty; +{ + register struct breakpoint *b; + register char *p, *p1; + register int bnum; + struct command_line *l; + + /* If we allowed this, we would have problems with when to + free the storage, if we change the commands currently + being read from. */ + + if (breakpoint_commands) + error ("Can't use the \"commands\" command among a breakpoint's commands."); + + /* Allow commands by itself to refer to the last breakpoint. */ + if (arg == 0) + bnum = breakpoint_count; + else + { + p = arg; + if (! (*p >= '0' && *p <= '9')) + error ("Argument must be integer (a breakpoint number)."); + + while (*p >= '0' && *p <= '9') p++; + if (*p) + error ("Unexpected extra arguments following breakpoint number."); + + bnum = atoi (arg); + } + + ALL_BREAKPOINTS (b) + if (b->number == bnum) + { + if (from_tty && input_from_terminal_p ()) + { + 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 (from_tty); + free_command_lines (b->commands); + b->commands = l; + return; + } + error ("No breakpoint number %d.", bnum); +} + +/* Called from command loop to execute the commands + associated with the breakpoint we just stopped at. */ + +void +do_breakpoint_commands () +{ + struct command_line *cmd; + + while (cmd = breakpoint_commands) + { + breakpoint_commands = 0; + execute_command_lines(cmd); + /* If command was "cont", breakpoint_commands is now 0, + of if we stopped at yet another breakpoint which has commands, + it is now the commands for the new breakpoint. */ + } + clear_momentary_breakpoints (); +} + +/* Used when the program is proceeded, to eliminate any remaining + commands attached to the previous breakpoint we stopped at. */ + +void +clear_breakpoint_commands () +{ + breakpoint_commands = 0; + breakpoint_auto_delete (0); +} + +/* Functions to get and set the current list of pending + breakpoint commands. These are used by run_stack_dummy + to preserve the commands around a function call. */ + +struct command_line * +get_breakpoint_commands () +{ + return breakpoint_commands; +} + +void +set_breakpoint_commands (cmds) + struct command_line *cmds; +{ + breakpoint_commands = cmds; +} + +/* insert_breakpoints is used when starting or continuing the program. + remove_breakpoints is used when the program stops. + Both return zero if successful, + or an `errno' value if could not write the inferior. */ + +int +insert_breakpoints () +{ + register struct breakpoint *b; + int val; + +#ifdef BREAKPOINT_DEBUG + printf ("Inserting breakpoints.\n"); +#endif /* BREAKPOINT_DEBUG */ + + ALL_BREAKPOINTS (b) + if (b->enable != disabled && ! b->inserted && ! b->duplicate) + { + read_memory (b->address, b->shadow_contents, sizeof break_insn); + val = write_memory (b->address, break_insn, sizeof break_insn); + if (val) + return val; +#ifdef BREAKPOINT_DEBUG + printf ("Inserted breakpoint at 0x%x, shadow 0x%x, 0x%x.\n", + b->address, b->shadow_contents[0], b->shadow_contents[1]); +#endif /* BREAKPOINT_DEBUG */ + b->inserted = 1; + } + return 0; +} + +int +remove_breakpoints () +{ + register struct breakpoint *b; + int val; + +#ifdef BREAKPOINT_DEBUG + printf ("Removing breakpoints.\n"); +#endif /* BREAKPOINT_DEBUG */ + + ALL_BREAKPOINTS (b) + if (b->inserted) + { + val = write_memory (b->address, b->shadow_contents, sizeof break_insn); + if (val) + return val; + b->inserted = 0; +#ifdef BREAKPOINT_DEBUG + printf ("Removed breakpoint at 0x%x, shadow 0x%x, 0x%x.\n", + b->address, b->shadow_contents[0], b->shadow_contents[1]); +#endif /* BREAKPOINT_DEBUG */ + } + + return 0; +} + +/* Clear the "inserted" flag in all breakpoints. + This is done when the inferior is loaded. */ + +void +mark_breakpoints_out () +{ + register struct breakpoint *b; + + ALL_BREAKPOINTS (b) + b->inserted = 0; +} + +/* breakpoint_here_p (PC) returns 1 if an enabled breakpoint exists at PC. + When continuing from a location with a breakpoint, + we actually single step once before calling insert_breakpoints. */ + +int +breakpoint_here_p (pc) + CORE_ADDR pc; +{ + register struct breakpoint *b; + + ALL_BREAKPOINTS (b) + if (b->enable != disabled && b->address == pc) + return 1; + + 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, + or -3 if hit a breakpoint number -3 (delete when program stops), + or else the number of the breakpoint, + with 0x1000000 added (or subtracted, for a negative return value) for + a silent breakpoint. */ + +int +breakpoint_stop_status (pc, frame_address) + CORE_ADDR pc; + FRAME_ADDR frame_address; +{ + register struct breakpoint *b; + register int cont = 0; + + /* Get the address where the breakpoint would have been. */ + pc -= DECR_PC_AFTER_BREAK; + + ALL_BREAKPOINTS (b) + if (b->enable != disabled && b->address == pc) + { + if (b->frame && b->frame != frame_address) + cont = -1; + else + { + int value_zero; + if (b->cond) + { + /* Need to select the frame, with all that implies + so that the conditions will have the right context. */ + select_frame (get_current_frame (), 0); + value_zero + = catch_errors (breakpoint_cond_eval, b->cond, + "Error occurred in testing breakpoint condition."); + free_all_values (); + } + if (b->cond && value_zero) + { + cont = -1; + } + else if (b->ignore_count > 0) + { + b->ignore_count--; + cont = -1; + } + else + { + if (b->enable == temporary) + b->enable = disabled; + breakpoint_commands = b->commands; + if (b->silent + || (breakpoint_commands + && !strcmp ("silent", breakpoint_commands->line))) + { + if (breakpoint_commands) + breakpoint_commands = breakpoint_commands->next; + return (b->number > 0 ? + 0x1000000 + b->number : + b->number - 0x1000000); + } + return b->number; + } + } + } + + return cont; +} + +static void +breakpoint_1 (bnum) + int bnum; +{ + register struct breakpoint *b; + register struct command_line *l; + register struct symbol *sym; + CORE_ADDR last_addr = (CORE_ADDR)-1; + + ALL_BREAKPOINTS (b) + if (bnum == -1 || bnum == b->number) + { + printf_filtered ("#%-3d %c 0x%08x", b->number, + "nyod"[(int) b->enable], + b->address); + last_addr = b->address; + if (b->symtab) + { + sym = find_pc_function (b->address); + if (sym) + { + fputs_filtered (" in ", stdout); + fputs_demangled (SYMBOL_NAME (sym), stdout, 1); + fputs_filtered (" (", stdout); + } + fputs_filtered (b->symtab->filename, stdout); + printf_filtered (" line %d", b->line_number); + if (sym) fputs_filtered(")", stdout); + } + else + print_address_symbolic (b->address, stdout); + + printf_filtered ("\n"); + + if (b->ignore_count) + printf_filtered ("\tignore next %d hits\n", b->ignore_count); + if (b->frame) + printf_filtered ("\tstop only in stack frame at 0x%x\n", b->frame); + if (b->cond) + { + printf_filtered ("\tbreak only if "); + print_expression (b->cond, stdout); + printf_filtered ("\n"); + } + if (l = b->commands) + while (l) + { + printf_filtered ("\t%s\n", l->line); + l = l->next; + } + } + + /* Compare against (CORE_ADDR)-1 in case some compiler decides + that a comparison of an unsigned with -1 is always false. */ + if (last_addr != (CORE_ADDR)-1) + set_next_address (last_addr); +} + +static void +breakpoints_info (bnum_exp) + char *bnum_exp; +{ + int bnum = -1; + + if (bnum_exp) + bnum = parse_and_eval_address (bnum_exp); + else if (breakpoint_chain == 0) + printf_filtered ("No breakpoints.\n"); + else + printf_filtered ("Breakpoints:\n\ +Num Enb Address Where\n"); + + breakpoint_1 (bnum); +} + +/* Print a message describing any breakpoints set at PC. */ + +static void +describe_other_breakpoints (pc) + register CORE_ADDR pc; +{ + register int others = 0; + register struct breakpoint *b; + + ALL_BREAKPOINTS (b) + if (b->address == pc) + others++; + if (others > 0) + { + printf ("Note: breakpoint%s ", (others > 1) ? "s" : ""); + ALL_BREAKPOINTS (b) + if (b->address == pc) + { + others--; + printf ("%d%s%s ", + b->number, + (b->enable == disabled) ? " (disabled)" : "", + (others > 1) ? "," : ((others == 1) ? " and" : "")); + } + printf ("also set at pc 0x%x.\n", pc); + } +} + +/* Set the default place to put a breakpoint + for the `break' command with no arguments. */ + +void +set_default_breakpoint (valid, addr, symtab, line) + int valid; + CORE_ADDR addr; + struct symtab *symtab; + int line; +{ + default_breakpoint_valid = valid; + default_breakpoint_address = addr; + default_breakpoint_symtab = symtab; + default_breakpoint_line = line; +} + +/* Rescan breakpoints at address ADDRESS, + marking the first one as "first" and any others as "duplicates". + This is so that the bpt instruction is only inserted once. */ + +static void +check_duplicates (address) + CORE_ADDR address; +{ + register struct breakpoint *b; + register int count = 0; + + ALL_BREAKPOINTS (b) + if (b->enable != disabled && b->address == address) + { + count++; + b->duplicate = count > 1; + } +} + +/* Low level routine to set a breakpoint. + Takes as args the three things that every breakpoint must have. + Returns the breakpoint object so caller can set other things. + Does not set the breakpoint number! + Does not print anything. */ + +static struct breakpoint * +set_raw_breakpoint (sal) + struct symtab_and_line sal; +{ + register struct breakpoint *b, *b1; + + b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint)); + bzero (b, sizeof *b); + b->address = sal.pc; + b->symtab = sal.symtab; + b->line_number = sal.line; + b->enable = enabled; + b->next = 0; + b->silent = 0; + + /* Add this breakpoint to the end of the chain + so that a list of breakpoints will come out in order + of increasing numbers. */ + + b1 = breakpoint_chain; + if (b1 == 0) + breakpoint_chain = b; + else + { + while (b1->next) + b1 = b1->next; + b1->next = b; + } + + check_duplicates (sal.pc); + + return b; +} + +/* Set a breakpoint that will evaporate an end of command + at address specified by SAL. + Restrict it to frame FRAME if FRAME is nonzero. */ + +void +set_momentary_breakpoint (sal, frame) + struct symtab_and_line sal; + FRAME frame; +{ + register struct breakpoint *b; + b = set_raw_breakpoint (sal); + b->number = -3; + b->enable = delete; + b->frame = (frame ? FRAME_FP (frame) : 0); +} + +void +clear_momentary_breakpoints () +{ + register struct breakpoint *b; + ALL_BREAKPOINTS (b) + if (b->number == -3) + { + delete_breakpoint (b); + break; + } +} + +/* Set a breakpoint from a symtab and line. + If TEMPFLAG is nonzero, it is a temporary breakpoint. + Print the same confirmation messages that the breakpoint command prints. */ + +void +set_breakpoint (s, line, tempflag) + struct symtab *s; + int line; + int tempflag; +{ + register struct breakpoint *b; + struct symtab_and_line sal; + + sal.symtab = s; + sal.line = line; + sal.pc = find_line_pc (sal.symtab, sal.line); + if (sal.pc == 0) + error ("No line %d in file \"%s\".\n", sal.line, sal.symtab->filename); + else + { + describe_other_breakpoints (sal.pc); + + b = set_raw_breakpoint (sal); + b->number = ++breakpoint_count; + b->cond = 0; + 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"); + } +} + +/* Set a breakpoint according to ARG (function, linenum or *address) + and make it temporary if TEMPFLAG is nonzero. */ + +static void +break_command_1 (arg, tempflag, from_tty) + char *arg; + 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; + CORE_ADDR pc; + + sals.sals = NULL; + sals.nelts = 0; + + sal.line = sal.pc = sal.end = 0; + sal.symtab = 0; + + /* If no arg given, or if first arg is 'if ', use the default breakpoint. */ + + if (!arg || (arg[0] == 'i' && arg[1] == 'f' + && (arg[2] == ' ' || arg[2] == '\t'))) + { + 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."); + } + else + /* Force almost all breakpoints to be in terms of the + current_source_symtab (which is decode_line_1's default). This + should produce the results we want almost all of the time while + leaving default_breakpoint_* alone. */ + if (default_breakpoint_valid + && (!current_source_symtab + || (arg && (*arg == '+' || *arg == '-')))) + sals = decode_line_1 (&arg, 1, default_breakpoint_symtab, + default_breakpoint_line); + else + sals = decode_line_1 (&arg, 1, 0, 0); + + if (! sals.nelts) + return; + + save_arg = arg; + for (i = 0; i < sals.nelts; i++) + { + 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; + + while (arg && *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; + } + + for (i = 0; i < sals.nelts; i++) + { + sal = sals.sals[i]; + + 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; + + 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"); + } + + if (sals.nelts > 1) + { + printf ("Multiple breakpoints were set.\n"); + printf ("Use the \"delete\" command to delete unwanted breakpoints.\n"); + } + free (sals.sals); +} + +static void +break_command (arg, from_tty) + char *arg; + int from_tty; +{ + break_command_1 (arg, 0, from_tty); +} + +static void +tbreak_command (arg, from_tty) + char *arg; + int from_tty; +{ + break_command_1 (arg, 1, from_tty); +} + +/* + * Helper routine for the until_command routine in infcmd.c. Here + * because it uses the mechanisms of breakpoints. + */ +void +until_break_command (arg, from_tty) + char *arg; + int from_tty; +{ + struct symtabs_and_lines sals; + struct symtab_and_line sal; + FRAME prev_frame = get_prev_frame (selected_frame); + + clear_proceed_status (); + + /* Set a breakpoint where the user wants it and at return from + this function */ + + if (default_breakpoint_valid) + sals = decode_line_1 (&arg, 1, default_breakpoint_symtab, + default_breakpoint_line); + else + sals = decode_line_1 (&arg, 1, 0, 0); + + if (sals.nelts != 1) + error ("Couldn't get information on specified line."); + + sal = sals.sals[0]; + free (sals.sals); /* malloc'd, so freed */ + + if (*arg) + error ("Junk at end of arguments."); + + if (sal.pc == 0 && sal.symtab != 0) + 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); + + set_momentary_breakpoint (sal, selected_frame); + + /* Keep within the current frame */ + + if (prev_frame) + { + struct frame_info *fi; + + fi = get_frame_info (prev_frame); + sal = find_pc_line (fi->pc, 0); + sal.pc = fi->pc; + set_momentary_breakpoint (sal, prev_frame); + } + + proceed (-1, -1, 0); +} + +static void +clear_command (arg, from_tty) + char *arg; + 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); + } + 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. */ + sal = sals.sals[i]; + found = (struct breakpoint *) 0; + while (breakpoint_chain + && (sal.pc ? breakpoint_chain->address == sal.pc + : (breakpoint_chain->symtab == sal.symtab + && breakpoint_chain->line_number == sal.line))) + { + b1 = breakpoint_chain; + breakpoint_chain = b1->next; + b1->next = found; + found = b1; + } + + ALL_BREAKPOINTS (b) + while (b->next + && (sal.pc ? b->next->address == sal.pc + : (b->next->symtab == sal.symtab + && b->next->line_number == sal.line))) + { + b1 = b->next; + b->next = b1->next; + b1->next = found; + found = b1; + } + + if (found == 0) + error ("No breakpoint at %s.", arg); + + if (found->next) from_tty = 1; /* Always report if deleted more than one */ + if (from_tty) printf ("Deleted breakpoint%s ", found->next ? "s" : ""); + while (found) + { + if (from_tty) printf ("%d ", found->number); + b1 = found->next; + delete_breakpoint (found); + found = b1; + } + if (from_tty) putchar ('\n'); + } + free (sals.sals); +} + +/* Delete breakpoint number BNUM if it is a `delete' breakpoint. + This is called after breakpoint BNUM has been hit. + Also delete any breakpoint numbered -3 unless there are breakpoint + commands to be executed. */ + +void +breakpoint_auto_delete (bnum) + int bnum; +{ + register struct breakpoint *b; + if (bnum != 0) + ALL_BREAKPOINTS (b) + if (b->number == bnum) + { + if (b->enable == delete) + delete_breakpoint (b); + break; + } + if (breakpoint_commands == 0) + clear_momentary_breakpoints (); +} + +static void +delete_breakpoint (bpt) + struct breakpoint *bpt; +{ + register struct breakpoint *b; + + if (bpt->inserted) + write_memory (bpt->address, bpt->shadow_contents, sizeof break_insn); + + if (breakpoint_chain == bpt) + breakpoint_chain = bpt->next; + + ALL_BREAKPOINTS (b) + if (b->next == bpt) + { + b->next = bpt->next; + break; + } + + check_duplicates (bpt->address); + + free_command_lines (bpt->commands); + if (bpt->cond) + free (bpt->cond); + + if (xgdb_verbose && bpt->number >=0) + printf ("breakpoint #%d deleted\n", bpt->number); + + free (bpt); +} + +static void map_breakpoint_numbers (); + +static void +delete_command (arg, from_tty) + char *arg; + int from_tty; +{ + register struct breakpoint *b, *b1; + + if (arg == 0) + { + /* Ask user only if there are some breakpoints to delete. */ + if (!from_tty + || breakpoint_chain && query ("Delete all breakpoints? ")) + { + /* No arg; clear all breakpoints. */ + while (breakpoint_chain) + delete_breakpoint (breakpoint_chain); + } + } + else + map_breakpoint_numbers (arg, delete_breakpoint); +} + +/* Delete all breakpoints. + Done when new symtabs are loaded, since the break condition expressions + may become invalid, and the breakpoints are probably wrong anyway. */ + +void +clear_breakpoints () +{ + delete_command (0, 0); +} + +/* Set ignore-count of breakpoint number BPTNUM to COUNT. + If from_tty is nonzero, it prints a message to that effect, + which ends with a period (no newline). */ + +void +set_ignore_count (bptnum, count, from_tty) + int bptnum, count, from_tty; +{ + register struct breakpoint *b; + + if (count < 0) + count = 0; + + ALL_BREAKPOINTS (b) + if (b->number == bptnum) + { + b->ignore_count = count; + if (!from_tty) + return; + else if (count == 0) + printf ("Will stop next time breakpoint %d is reached.", bptnum); + else if (count == 1) + printf ("Will ignore next crossing of breakpoint %d.", bptnum); + else + printf ("Will ignore next %d crossings of breakpoint %d.", + count, bptnum); + return; + } + + error ("No breakpoint number %d.", bptnum); +} + +/* Clear the ignore counts of all breakpoints. */ +void +breakpoint_clear_ignore_counts () +{ + struct breakpoint *b; + + ALL_BREAKPOINTS (b) + b->ignore_count = 0; +} + +/* Command to set ignore-count of breakpoint N to COUNT. */ + +static void +ignore_command (args, from_tty) + char *args; + int from_tty; +{ + register char *p = args; + register int num; + + if (p == 0) + error_no_arg ("a breakpoint number"); + + while (*p >= '0' && *p <= '9') p++; + if (*p && *p != ' ' && *p != '\t') + error ("First argument must be a breakpoint number."); + + num = atoi (args); + + if (*p == 0) + error ("Second argument (specified ignore-count) is missing."); + + set_ignore_count (num, parse_and_eval_address (p), from_tty); + printf ("\n"); +} + +/* Call FUNCTION on each of the breakpoints + whose numbers are given in ARGS. */ + +static void +map_breakpoint_numbers (args, function) + char *args; + void (*function) (); +{ + register char *p = args; + register char *p1; + register int num; + register struct breakpoint *b; + + if (p == 0) + error_no_arg ("one or more breakpoint numbers"); + + while (*p) + { + p1 = p; + while (*p1 >= '0' && *p1 <= '9') p1++; + if (*p1 && *p1 != ' ' && *p1 != '\t') + error ("Arguments must be breakpoint numbers."); + + num = atoi (p); + + ALL_BREAKPOINTS (b) + if (b->number == num) + { + function (b); + goto win; + } + printf ("No breakpoint number %d.\n", num); + win: + p = p1; + while (*p == ' ' || *p == '\t') p++; + } +} + +static void +enable_breakpoint (bpt) + struct breakpoint *bpt; +{ + bpt->enable = enabled; + + if (xgdb_verbose && bpt->number >= 0) + printf ("breakpoint #%d enabled\n", bpt->number); + + check_duplicates (bpt->address); +} + +static void +enable_command (args) + char *args; +{ + struct breakpoint *bpt; + if (args == 0) + ALL_BREAKPOINTS (bpt) + enable_breakpoint (bpt); + else + map_breakpoint_numbers (args, enable_breakpoint); +} + +static void +disable_breakpoint (bpt) + struct breakpoint *bpt; +{ + bpt->enable = disabled; + + if (xgdb_verbose && bpt->number >= 0) + printf ("breakpoint #%d disabled\n", bpt->number); + + check_duplicates (bpt->address); +} + +static void +disable_command (args) + char *args; +{ + register struct breakpoint *bpt; + if (args == 0) + ALL_BREAKPOINTS (bpt) + disable_breakpoint (bpt); + else + map_breakpoint_numbers (args, disable_breakpoint); +} + +static void +enable_once_breakpoint (bpt) + struct breakpoint *bpt; +{ + bpt->enable = temporary; + + check_duplicates (bpt->address); +} + +static void +enable_once_command (args) + char *args; +{ + map_breakpoint_numbers (args, enable_once_breakpoint); +} + +static void +enable_delete_breakpoint (bpt) + struct breakpoint *bpt; +{ + bpt->enable = delete; + + check_duplicates (bpt->address); +} + +static void +enable_delete_command (args) + char *args; +{ + map_breakpoint_numbers (args, enable_delete_breakpoint); +} + +/* + * Use default_breakpoint_'s, or nothing if they aren't valid. + */ +struct symtabs_and_lines +decode_line_spec_1 (string, funfirstline) + char *string; + int funfirstline; +{ + struct symtabs_and_lines sals; + if (string == 0) + error ("Empty line specification."); + if (default_breakpoint_valid) + sals = decode_line_1 (&string, funfirstline, + default_breakpoint_symtab, default_breakpoint_line); + else + sals = decode_line_1 (&string, funfirstline, 0, 0); + if (*string) + error ("Junk at end of line specification: %s", string); + return sals; +} + + +/* Chain containing all defined enable commands. */ + +extern struct cmd_list_element + *enablelist, *disablelist, + *deletelist, *enablebreaklist; + +extern struct cmd_list_element *cmdlist; + +void +_initialize_breakpoint () +{ + breakpoint_chain = 0; + breakpoint_count = 0; + + add_com ("ignore", class_breakpoint, ignore_command, + "Set ignore-count of breakpoint number N to COUNT."); + + add_com ("commands", class_breakpoint, commands_command, + "Set commands to be executed when a breakpoint is hit.\n\ +Give breakpoint number as argument after \"commands\".\n\ +With no argument, the targeted breakpoint is the last one set.\n\ +The commands themselves follow starting on the next line.\n\ +Type a line containing \"end\" to indicate the end of them.\n\ +Give \"silent\" as the first line to make the breakpoint silent;\n\ +then no output is printed when it is hit, except what the commands print."); + + add_com ("condition", class_breakpoint, condition_command, + "Specify breakpoint number N to break only if COND is true.\n\ +N is an integer; COND is a C expression to be evaluated whenever\n\ +breakpoint N is reached. Actually break only when COND is nonzero."); + + add_com ("tbreak", class_breakpoint, tbreak_command, + "Set a temporary breakpoint. Args like \"break\" command.\n\ +Like \"break\" except the breakpoint is only enabled temporarily,\n\ +so it will be disabled when hit. Equivalent to \"break\" followed\n\ +by using \"enable once\" on the breakpoint number."); + + add_prefix_cmd ("enable", class_breakpoint, enable_command, + "Enable some breakpoints or auto-display expressions.\n\ +Give breakpoint numbers (separated by spaces) as arguments.\n\ +With no subcommand, breakpoints are enabled until you command otherwise.\n\ +This is used to cancel the effect of the \"disable\" command.\n\ +With a subcommand you can enable temporarily.\n\ +\n\ +The \"display\" subcommand applies to auto-displays instead of breakpoints.", + &enablelist, "enable ", 1, &cmdlist); + + add_abbrev_prefix_cmd ("breakpoints", class_breakpoint, enable_command, + "Enable some breakpoints or auto-display expressions.\n\ +Give breakpoint numbers (separated by spaces) as arguments.\n\ +With no subcommand, breakpoints are enabled until you command otherwise.\n\ +This is used to cancel the effect of the \"disable\" command.\n\ +May be abbreviates to simply \"enable\".\n\ +With a subcommand you can enable temporarily.", + &enablebreaklist, "enable breakpoints ", 1, &enablelist); + + add_cmd ("once", no_class, enable_once_command, + "Enable breakpoints for one hit. Give breakpoint numbers.\n\ +If a breakpoint is hit while enabled in this fashion, it becomes disabled.\n\ +See the \"tbreak\" command which sets a breakpoint and enables it once.", + &enablebreaklist); + + add_cmd ("delete", no_class, enable_delete_command, + "Enable breakpoints and delete when hit. Give breakpoint numbers.\n\ +If a breakpoint is hit while enabled in this fashion, it is deleted.", + &enablebreaklist); + + add_cmd ("delete", no_class, enable_delete_command, + "Enable breakpoints and delete when hit. Give breakpoint numbers.\n\ +If a breakpoint is hit while enabled in this fashion, it is deleted.", + &enablelist); + + add_cmd ("once", no_class, enable_once_command, + "Enable breakpoints for one hit. Give breakpoint numbers.\n\ +If a breakpoint is hit while enabled in this fashion, it becomes disabled.\n\ +See the \"tbreak\" command which sets a breakpoint and enables it once.", + &enablelist); + + add_prefix_cmd ("disable", class_breakpoint, disable_command, + "Disable some breakpoints or auto-display expressions.\n\ +Arguments are breakpoint numbers with spaces in between.\n\ +To disable all breakpoints, give no argument.\n\ +A disabled breakpoint is not forgotten, but has no effect until reenabled.\n\ +\n\ +The \"display\" subcommand applies to auto-displays instead of breakpoints.", + &disablelist, "disable ", 1, &cmdlist); + add_com_alias ("dis", "disable", class_breakpoint, 1); + add_com_alias ("disa", "disable", class_breakpoint, 1); + + add_abbrev_cmd ("breakpoints", class_breakpoint, disable_command, + "Disable some breakpoints or auto-display expressions.\n\ +Arguments are breakpoint numbers with spaces in between.\n\ +To disable all breakpoints, give no argument.\n\ +A disabled breakpoint is not forgotten, but has no effect until reenabled.\n\ +This command may be abbreviated \"disable\".", + &disablelist); + + add_prefix_cmd ("delete", class_breakpoint, delete_command, + "Delete some breakpoints or auto-display expressions.\n\ +Arguments are breakpoint numbers with spaces in between.\n\ +To delete all breakpoints, give no argument.\n\ +\n\ +Also a prefix command for deletion of other GDB objects.\n\ +The \"unset\" command is also an alias for \"delete\".", + &deletelist, "delete ", 1, &cmdlist); + add_com_alias ("d", "delete", class_breakpoint, 1); + add_com_alias ("unset", "delete", class_alias, 1); + + add_cmd ("breakpoints", class_alias, delete_command, + "Delete some breakpoints or auto-display expressions.\n\ +Arguments are breakpoint numbers with spaces in between.\n\ +To delete all breakpoints, give no argument.\n\ +This command may be abbreviated \"delete\".", + &deletelist); + + add_com ("clear", class_breakpoint, clear_command, + "Clear breakpoint at specified line or function.\n\ +Argument may be line number, function name, or \"*\" and an address.\n\ +If line number is specified, all breakpoints in that line are cleared.\n\ +If function is specified, breakpoints at beginning of function are cleared.\n\ +If an address is specified, breakpoints at that address are cleared.\n\n\ +With no argument, clears all breakpoints in the line that the selected frame\n\ +is executing in.\n\ +\n\ +See also the \"delete\" command which clears breakpoints by number."); + + add_com ("break", class_breakpoint, break_command, + "Set breakpoint at specified line or function.\n\ +Argument may be line number, function name, or \"*\" and an address.\n\ +If line number is specified, break at start of code for that line.\n\ +If function is specified, break at start of code for that function.\n\ +If an address is specified, break at that exact address.\n\ +With no arg, uses current execution address of selected stack frame.\n\ +This is useful for breaking on return to a stack frame.\n\ +\n\ +Multiple breakpoints at one place are permitted, and useful if conditional.\n\ +\n\ +Do \"help breakpoints\" for info on other commands dealing with breakpoints."); + add_com_alias ("b", "break", class_run, 1); + add_com_alias ("br", "break", class_run, 1); + add_com_alias ("bre", "break", class_run, 1); + add_com_alias ("brea", "break", class_run, 1); + + add_info ("breakpoints", breakpoints_info, + "Status of all breakpoints, or breakpoint number NUMBER.\n\ +Second column is \"y\" for enabled breakpoint, \"n\" for disabled,\n\ +\"o\" for enabled once (disable when hit), \"d\" for enable but delete when hit.\n\ +Then come the address and the file/line number.\n\n\ +Convenience variable \"$_\" and default examine address for \"x\"\n\ +are set to the address of the last breakpoint listed."); +} + diff --git a/gnu/usr.bin/gdb/command.c b/gnu/usr.bin/gdb/command.c new file mode 100644 index 000000000000..79daea490383 --- /dev/null +++ b/gnu/usr.bin/gdb/command.c @@ -0,0 +1,856 @@ +/* Library for reading command lines and decoding commands. + Copyright (C) 1986, 1989 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "command.h" +#include "defs.h" +#include <stdio.h> +#include <ctype.h> + +extern char *xmalloc (); + +/* Add element named NAME to command list *LIST. + FUN should be the function to execute the command; + it will get a character string as argument, with leading + and trailing blanks already eliminated. + + DOC is a documentation string for the command. + Its first line should be a complete sentence. + It should start with ? for a command that is an abbreviation + or with * for a command that most users don't need to know about. */ + +struct cmd_list_element * +add_cmd (name, class, fun, doc, list) + char *name; + int class; + void (*fun) (); + char *doc; + struct cmd_list_element **list; +{ + register struct cmd_list_element *c + = (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element)); + + delete_cmd (name, list); + c->next = *list; + c->name = savestring (name, strlen (name)); + c->class = class; + c->function = fun; + c->doc = doc; + c->prefixlist = 0; + c->allow_unknown = 0; + c->abbrev_flag = 0; + c->aux = 0; + *list = c; + return c; +} + +/* Same as above, except that the abbrev_flag is set. */ + +struct cmd_list_element * +add_abbrev_cmd (name, class, fun, doc, list) + char *name; + int class; + void (*fun) (); + char *doc; + struct cmd_list_element **list; +{ + register struct cmd_list_element *c + = (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element)); + + delete_cmd (name, list); + c->next = *list; + c->name = savestring (name, strlen (name)); + c->class = class; + c->function = fun; + c->doc = doc; + c->prefixlist = 0; + c->allow_unknown = 0; + c->abbrev_flag = 1; + c->aux = 0; + *list = c; + return c; +} + +struct cmd_list_element * +add_alias_cmd (name, oldname, class, abbrev_flag, list) + char *name; + char *oldname; + int class; + int abbrev_flag; + struct cmd_list_element **list; +{ + /* Must do this since lookup_cmd tries to side-effect its first arg */ + char *copied_name; + register struct cmd_list_element *old; + register struct cmd_list_element *c; + copied_name = (char *) alloca (strlen (oldname) + 1); + strcpy (copied_name, oldname); + old = lookup_cmd (&copied_name, *list, 0, 1, 1); + + if (old == 0) + { + delete_cmd (name, list); + return 0; + } + + c = add_cmd (name, class, old->function, old->doc, list); + c->prefixlist = old->prefixlist; + c->prefixname = old->prefixname; + c->allow_unknown = old->allow_unknown; + c->abbrev_flag = abbrev_flag; + c->aux = old->aux; + return c; +} + +/* Like add_cmd but adds an element for a command prefix: + a name that should be followed by a subcommand to be looked up + in another command list. PREFIXLIST should be the address + of the variable containing that list. */ + +struct cmd_list_element * +add_prefix_cmd (name, class, fun, doc, prefixlist, prefixname, + allow_unknown, list) + char *name; + int class; + void (*fun) (); + char *doc; + struct cmd_list_element **prefixlist; + char *prefixname; + int allow_unknown; + struct cmd_list_element **list; +{ + register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list); + c->prefixlist = prefixlist; + c->prefixname = prefixname; + c->allow_unknown = allow_unknown; + return c; +} + +/* Like add_prefix_cmd butsets the abbrev_flag on the new command. */ + +struct cmd_list_element * +add_abbrev_prefix_cmd (name, class, fun, doc, prefixlist, prefixname, + allow_unknown, list) + char *name; + int class; + void (*fun) (); + char *doc; + struct cmd_list_element **prefixlist; + char *prefixname; + int allow_unknown; + struct cmd_list_element **list; +{ + register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list); + c->prefixlist = prefixlist; + c->prefixname = prefixname; + c->allow_unknown = allow_unknown; + c->abbrev_flag = 1; + return c; +} + +/* Remove the command named NAME from the command list. */ + +void +delete_cmd (name, list) + char *name; + struct cmd_list_element **list; +{ + register struct cmd_list_element *c; + + while (*list && !strcmp ((*list)->name, name)) + { + *list = (*list)->next; + } + + if (*list) + for (c = *list; c->next;) + { + if (!strcmp (c->next->name, name)) + c->next = c->next->next; + else + c = c->next; + } +} + +void help_cmd (), help_list (), help_cmd_list (); + +/* This command really has to deal with two things: + * 1) I want documentation on *this string* (usually called by + * "help commandname"). + * 2) I want documentation on *this list* (usually called by + * giving a command that requires subcommands. Also called by saying + * just "help".) + * + * I am going to split this into two seperate comamnds, help_cmd and + * help_list. + */ + +void +help_cmd (command, stream) + char *command; + FILE *stream; +{ + struct cmd_list_element *c; + extern struct cmd_list_element *cmdlist; + + if (!command) + { + help_list (cmdlist, "", -2, stream); + return; + } + + c = lookup_cmd (&command, cmdlist, "", 0, 0); + + if (c == 0) + return; + + /* There are three cases here. + If c->prefixlist is nonzer, we have a prefix command. + Print its documentation, then list its subcommands. + + If c->function is nonzero, we really have a command. + Print its documentation and return. + + If c->function is zero, we have a class name. + Print its documentation (as if it were a command) + and then set class to he number of this class + so that the commands in the class will be listed. */ + + fputs_filtered (c->doc, stream); + fputs_filtered ("\n", stream); + + if (c->prefixlist == 0 && c->function != 0) + return; + fprintf_filtered (stream, "\n"); + + /* If this is a prefix command, print it's subcommands */ + if (c->prefixlist) + help_list (*c->prefixlist, c->prefixname, -1, stream); + + /* If this is a class name, print all of the commands in the class */ + if (c->function == 0) + help_list (cmdlist, "", c->class, stream); +} + +/* + * Get a specific kind of help on a command list. + * + * LIST is the list. + * CMDTYPE is the prefix to use in the title string. + * CLASS is the class with which to list the nodes of this list (see + * documentation for help_cmd_list below), As usual, -1 for + * everything, -2 for just classes, and non-negative for only things + * in a specific class. + * and STREAM is the output stream on which to print things. + * If you call this routine with a class >= 0, it recurses. + */ +void +help_list (list, cmdtype, class, stream) + struct cmd_list_element *list; + char *cmdtype; + int class; + FILE *stream; +{ + int len; + char *cmdtype1, *cmdtype2; + + /* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub" */ + len = strlen (cmdtype); + cmdtype1 = (char *) alloca (len + 1); + cmdtype1[0] = 0; + cmdtype2 = (char *) alloca (len + 4); + cmdtype2[0] = 0; + if (len) + { + cmdtype1[0] = ' '; + strncpy (cmdtype1 + 1, cmdtype, len - 1); + cmdtype1[len] = 0; + strncpy (cmdtype2, cmdtype, len - 1); + strcpy (cmdtype2 + len - 1, " sub"); + } + + if (class == -2) + fprintf_filtered (stream, "List of classes of %scommands:\n\n", cmdtype2); + else + fprintf_filtered (stream, "List of %scommands:\n\n", cmdtype2); + + help_cmd_list (list, class, cmdtype, (class >= 0), stream); + + if (class == -2) + fprintf_filtered (stream, "\n\ +Type \"help%s\" followed by a class name for a list of commands in that class.", + cmdtype1); + + fprintf_filtered (stream, "\n\ +Type \"help%s\" followed by %scommand name for full documentation.\n\ +Command name abbreviations are allowed if unambiguous.\n", + cmdtype1, cmdtype2); +} + + +/* + * Implement a help command on command list LIST. + * RECURSE should be non-zero if this should be done recursively on + * all sublists of LIST. + * PREFIX is the prefix to print before each command name. + * STREAM is the stream upon which the output should be written. + * CLASS should be: + * A non-negative class number to list only commands in that + * class. + * -1 to list all commands in list. + * -2 to list all classes in list. + * + * Note that RECURSE will be active on *all* sublists, not just the + * ones seclected by the criteria above (ie. the selection mechanism + * is at the low level, not the high-level). + */ +void +help_cmd_list (list, class, prefix, recurse, stream) + struct cmd_list_element *list; + int class; + char *prefix; + int recurse; + FILE *stream; +{ + register struct cmd_list_element *c; + register char *p; + static char *line_buffer = 0; + static int line_size; + + if (!line_buffer) + { + line_size = 80; + line_buffer = (char *) xmalloc (line_size); + } + + for (c = list; c; c = c->next) + { + if (c->abbrev_flag == 0 && + (class == -1 + || (class == -2 && c->function == 0) + || (class == c->class && c->function != 0))) + { + fprintf_filtered (stream, "%s%s -- ", prefix, c->name); + /* Print just the first line */ + p = c->doc; + while (*p && *p != '\n') p++; + if (p - c->doc > line_size - 1) + { + line_size = p - c->doc + 1; + free (line_buffer); + line_buffer = (char *) xmalloc (line_size); + } + strncpy (line_buffer, c->doc, p - c->doc); + line_buffer[p - c->doc] = '\0'; + fputs_filtered (line_buffer, stream); + fputs_filtered ("\n", stream); + } + if (recurse + && c->prefixlist != 0 + && c->abbrev_flag == 0) + help_cmd_list (*c->prefixlist, class, c->prefixname, 1, stream); + } +} + +/* This routine takes a line of TEXT and a CLIST in which to + start the lookup. When it returns it will have incremented the text + pointer past the section of text it matched, set *RESULT_LIST to + the list in which the last word was matched, and will return the + cmd list element which the text matches. It will return 0 if no + match at all was possible. It will return -1 if ambigous matches are + possible; in this case *RESULT_LIST will be set to the list in which + there are ambiguous choices (and text will be set to the ambiguous + text string). + + It does no error reporting whatsoever; control will always return + to the superior routine. + + In the case of an ambiguous return (-1), *RESULT_LIST will be set to + point at the prefix_command (ie. the best match) *or* (special + case) will be 0 if no prefix command was ever found. For example, + in the case of "info a", "info" matches without ambiguity, but "a" + could be "args" or "address", so *RESULT_LIST is set to + the cmd_list_element for "info". So in this case + result list should not be interpeted as a pointer to the beginning + of a list; it simply points to a specific command. + + This routine does *not* modify the text pointed to by TEXT. + + If INGNORE_HELP_CLASSES is nonzero, ignore any command list + elements which are actually help classes rather than commands (i.e. + the function field of the struct cmd_list_element is 0). */ + +struct cmd_list_element * +lookup_cmd_1 (text, clist, result_list, ignore_help_classes) + char **text; + struct cmd_list_element *clist, **result_list; + int ignore_help_classes; +{ + char *p, *command; + int len, tmp, nfound; + struct cmd_list_element *found, *c; + + while (**text == ' ' || **text == '\t') + (*text)++; + + /* Treating underscores as part of command words is important + so that "set args_foo()" doesn't get interpreted as + "set args _foo()". */ + for (p = *text; + *p && (isalnum(*p) || *p == '-' || *p == '_'); + p++) + ; + + /* If nothing but whitespace, return 0. */ + if (p == *text) + return 0; + + len = p - *text; + + /* *text and p now bracket the first command word to lookup (and + it's length is len). We copy this into a local temporary, + converting to lower case as we go. */ + + command = (char *) alloca (len + 1); + for (tmp = 0; tmp < len; tmp++) + { + char x = (*text)[tmp]; + command[tmp] = (x >= 'A' && x <= 'Z') ? x - 'A' + 'a' : x; + } + command[len] = '\0'; + + /* Look it up. */ + found = 0; + nfound = 0; + for (c = clist; c; c = c->next) + if (!strncmp (command, c->name, len) + && (!ignore_help_classes || c->function)) + { + found = c; + nfound++; + if (c->name[len] == '\0') + { + nfound = 1; + break; + } + } + + /* If nothing matches, we have a simple failure. */ + if (nfound == 0) + return 0; + + if (nfound > 1) + { + *result_list = 0; /* Will be modified in calling routine + if we know what the prefix command is. + */ + return (struct cmd_list_element *) -1; /* Ambiguous. */ + } + + /* We've matched something on this list. Move text pointer forward. */ + + *text = p; + if (found->prefixlist) + { + c = lookup_cmd_1 (text, *found->prefixlist, result_list, + ignore_help_classes); + if (!c) + { + /* Didn't find anything; this is as far as we got. */ + *result_list = clist; + return found; + } + else if (c == (struct cmd_list_element *) -1) + { + /* We've gotten this far properley, but the next step + is ambiguous. We need to set the result list to the best + we've found (if an inferior hasn't already set it). */ + if (!*result_list) + /* This used to say *result_list = *found->prefixlist + If that was correct, need to modify the documentation + at the top of this function to clarify what is supposed + to be going on. */ + *result_list = found; + return c; + } + else + { + /* We matched! */ + return c; + } + } + else + { + *result_list = clist; + return found; + } +} + +/* Look up the contents of *LINE as a command in the command list LIST. + LIST is a chain of struct cmd_list_element's. + If it is found, return the struct cmd_list_element for that command + and update *LINE to point after the command name, at the first argument. + If not found, call error if ALLOW_UNKNOWN is zero + otherwise (or if error returns) return zero. + Call error if specified command is ambiguous, + unless ALLOW_UNKNOWN is negative. + CMDTYPE precedes the word "command" in the error message. + + If INGNORE_HELP_CLASSES is nonzero, ignore any command list + elements which are actually help classes rather than commands (i.e. + the function field of the struct cmd_list_element is 0). */ + +struct cmd_list_element * +lookup_cmd (line, list, cmdtype, allow_unknown, ignore_help_classes) + char **line; + struct cmd_list_element *list; + char *cmdtype; + int allow_unknown; + int ignore_help_classes; +{ + struct cmd_list_element *last_list = 0; + struct cmd_list_element *c = + lookup_cmd_1 (line, list, &last_list, ignore_help_classes); + char *ptr = (*line) + strlen (*line) - 1; + + /* Clear off trailing whitespace. */ + while (ptr >= *line && (*ptr == ' ' || *ptr == '\t')) + ptr--; + *(ptr + 1) = '\0'; + + if (!c) + { + if (!allow_unknown) + { + if (!*line) + error ("Lack of needed %scommand", cmdtype); + else + { + char *p = *line, *q; + + while (isalnum(*p) || *p == '-') + p++; + + q = (char *) alloca (p - *line + 1); + strncpy (q, *line, p - *line); + q[p-*line] = '\0'; + + error ("Undefined %scommand: \"%s\".", cmdtype, q); + } + } + else + return 0; + } + else if (c == (struct cmd_list_element *) -1) + { + /* Ambigous. Local values should be off prefixlist or called + values. */ + int local_allow_unknown = (last_list ? last_list->allow_unknown : + allow_unknown); + char *local_cmdtype = last_list ? last_list->prefixname : cmdtype; + struct cmd_list_element *local_list = + (last_list ? *(last_list->prefixlist) : list); + + if (local_allow_unknown < 0) + { + if (last_list) + return last_list; /* Found something. */ + else + return 0; /* Found nothing. */ + } + else + { + /* Report as error. */ + int amb_len; + char ambbuf[100]; + + for (amb_len = 0; + ((*line)[amb_len] && (*line)[amb_len] != ' ' + && (*line)[amb_len] != '\t'); + amb_len++) + ; + + ambbuf[0] = 0; + for (c = local_list; c; c = c->next) + if (!strncmp (*line, c->name, amb_len)) + { + if (strlen (ambbuf) + strlen (c->name) + 6 < sizeof ambbuf) + { + if (strlen (ambbuf)) + strcat (ambbuf, ", "); + strcat (ambbuf, c->name); + } + else + { + strcat (ambbuf, ".."); + break; + } + } + error ("Ambiguous %scommand \"%s\": %s.", local_cmdtype, + *line, ambbuf); + } + } + else + { + /* We've got something. It may still not be what the caller + wants (if this command *needs* a subcommand). */ + while (**line == ' ' || **line == '\t') + (*line)++; + + if (c->prefixlist && **line && !c->allow_unknown) + error ("Undefined %scommand: \"%s\".", c->prefixname, *line); + + /* Seems to be what he wants. Return it. */ + return c; + } +} + +#if 0 +/* Look up the contents of *LINE as a command in the command list LIST. + LIST is a chain of struct cmd_list_element's. + If it is found, return the struct cmd_list_element for that command + and update *LINE to point after the command name, at the first argument. + If not found, call error if ALLOW_UNKNOWN is zero + otherwise (or if error returns) return zero. + Call error if specified command is ambiguous, + unless ALLOW_UNKNOWN is negative. + CMDTYPE precedes the word "command" in the error message. */ + +struct cmd_list_element * +lookup_cmd (line, list, cmdtype, allow_unknown) + char **line; + struct cmd_list_element *list; + char *cmdtype; + int allow_unknown; +{ + register char *p; + register struct cmd_list_element *c, *found; + int nfound; + char ambbuf[100]; + char *processed_cmd; + int i, cmd_len; + + /* Skip leading whitespace. */ + + while (**line == ' ' || **line == '\t') + (*line)++; + + /* Clear out trailing whitespace. */ + + p = *line + strlen (*line); + while (p != *line && (p[-1] == ' ' || p[-1] == '\t')) + p--; + *p = 0; + + /* Find end of command name. */ + + p = *line; + while (*p == '-' + || (*p >= 'a' && *p <= 'z') + || (*p >= 'A' && *p <= 'Z') + || (*p >= '0' && *p <= '9')) + p++; + + /* Look up the command name. + If exact match, keep that. + Otherwise, take command abbreviated, if unique. Note that (in my + opinion) a null string does *not* indicate ambiguity; simply the + end of the argument. */ + + if (p == *line) + { + if (!allow_unknown) + error ("Lack of needed %scommand", cmdtype); + return 0; + } + + /* Copy over to a local buffer, converting to lowercase on the way. + This is in case the command being parsed is a subcommand which + doesn't match anything, and that's ok. We want the original + untouched for the routine of the original command. */ + + processed_cmd = (char *) alloca (p - *line + 1); + for (cmd_len = 0; cmd_len < p - *line; cmd_len++) + { + char x = (*line)[cmd_len]; + if (x >= 'A' && x <= 'Z') + processed_cmd[cmd_len] = x - 'A' + 'a'; + else + processed_cmd[cmd_len] = x; + } + processed_cmd[cmd_len] = '\0'; + + /* Check all possibilities in the current command list. */ + found = 0; + nfound = 0; + for (c = list; c; c = c->next) + { + if (!strncmp (processed_cmd, c->name, cmd_len)) + { + found = c; + nfound++; + if (c->name[cmd_len] == 0) + { + nfound = 1; + break; + } + } + } + + /* Report error for undefined command name. */ + + if (nfound != 1) + { + if (nfound > 1 && allow_unknown >= 0) + { + ambbuf[0] = 0; + for (c = list; c; c = c->next) + if (!strncmp (processed_cmd, c->name, cmd_len)) + { + if (strlen (ambbuf) + strlen (c->name) + 6 < sizeof ambbuf) + { + if (strlen (ambbuf)) + strcat (ambbuf, ", "); + strcat (ambbuf, c->name); + } + else + { + strcat (ambbuf, ".."); + break; + } + } + error ("Ambiguous %scommand \"%s\": %s.", cmdtype, + processed_cmd, ambbuf); + } + else if (!allow_unknown) + error ("Undefined %scommand: \"%s\".", cmdtype, processed_cmd); + return 0; + } + + /* Skip whitespace before the argument. */ + + while (*p == ' ' || *p == '\t') p++; + *line = p; + + if (found->prefixlist && *p) + { + c = lookup_cmd (line, *found->prefixlist, found->prefixname, + found->allow_unknown); + if (c) + return c; + } + + return found; +} +#endif + +/* Helper function for SYMBOL_COMPLETION_FUNCTION. */ + +/* Return a vector of char pointers which point to the different + possible completions in LIST of TEXT. */ + +char ** +complete_on_cmdlist (list, text) + struct cmd_list_element *list; + char *text; +{ + struct cmd_list_element *ptr; + char **matchlist; + int sizeof_matchlist; + int matches; + int textlen = strlen (text); + + sizeof_matchlist = 10; + matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *)); + matches = 0; + + for (ptr = list; ptr; ptr = ptr->next) + if (!strncmp (ptr->name, text, textlen) + && !ptr->abbrev_flag + && (ptr->function + || ptr->prefixlist)) + { + if (matches == sizeof_matchlist) + { + sizeof_matchlist *= 2; + matchlist = (char **) xrealloc (matchlist, + (sizeof_matchlist + * sizeof (char *))); + } + + matchlist[matches] = (char *) + xmalloc (strlen (ptr->name) + 1); + strcpy (matchlist[matches++], ptr->name); + } + + if (matches == 0) + { + free (matchlist); + matchlist = 0; + } + else + { + matchlist = (char **) xrealloc (matchlist, ((matches + 1) + * sizeof (char *))); + matchlist[matches] = (char *) 0; + } + + return matchlist; +} + +static void +shell_escape (arg, from_tty) + char *arg; + int from_tty; +{ + int rc, status, pid; + char *p, *user_shell; + extern char *rindex (); + + if ((user_shell = (char *) getenv ("SHELL")) == NULL) + user_shell = "/bin/sh"; + + /* Get the name of the shell for arg0 */ + if ((p = rindex (user_shell, '/')) == NULL) + p = user_shell; + else + p++; /* Get past '/' */ + + if ((pid = fork()) == 0) + { + if (!arg) + execl (user_shell, p, 0); + else + execl (user_shell, p, "-c", arg, 0); + + fprintf (stderr, "Exec of shell failed\n"); + exit (0); + } + + if (pid != -1) + while ((rc = wait (&status)) != pid && rc != -1) + ; + else + error ("Fork failed"); +} + +void +_initialize_command () +{ + add_com ("shell", class_support, shell_escape, + "Execute the rest of the line as a shell command. \n\ +With no arguments, run an inferior shell."); +} diff --git a/gnu/usr.bin/gdb/command.h b/gnu/usr.bin/gdb/command.h new file mode 100644 index 000000000000..fe28aef817ae --- /dev/null +++ b/gnu/usr.bin/gdb/command.h @@ -0,0 +1,77 @@ +/* Header file for command-reading library command.c. + Copyright (C) 1986, 1989 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This structure records one command'd definition. */ + +struct cmd_list_element + { + /* Points to next command in this list. */ + struct cmd_list_element *next; + + /* Name of this command. */ + char *name; + + /* Command class; class values are chosen by application program. */ + int class; + + /* Function definition of this command. + Zero for command class names and for help topics that + are not really commands. */ + void (*function) (); + + /* Documentation of this command (or help topic). + First line is brief documentation; remaining lines form, with it, + the full documentation. First line should end with a period. + Entire string should also end with a period, not a newline. */ + char *doc; + + /* Auxiliary information. + It is up to the calling program to decide what this means. */ + char *aux; + + /* Nonzero identifies a prefix command. For them, the address + of the variable containing the list of subcommands. */ + struct cmd_list_element **prefixlist; + + /* For prefix commands only: + String containing prefix commands to get here: this one + plus any others needed to get to it. Should end in a space. + It is used before the word "command" in describing the + commands reached through this prefix. */ + char *prefixname; + + /* For prefix commands only: + nonzero means do not get an error if subcommand is not + recognized; call the prefix's own function in that case. */ + char allow_unknown; + + /* Nonzero says this is an abbreviation, and should not + be mentioned in lists of commands. + This allows "br<tab>" to complete to "break", which it + otherwise wouldn't. */ + char abbrev_flag; + }; + +/* Forward-declarations of the entry-points of command.c. */ + +extern struct cmd_list_element *add_cmd (); +extern struct cmd_list_element *add_alias_cmd (); +extern struct cmd_list_element *add_prefix_cmd (); +extern struct cmd_list_element *lookup_cmd (), *lookup_cmd_1 (); +extern char **complete_on_cmdlist (); +extern void delete_cmd (); +extern void help_cmd (); diff --git a/gnu/usr.bin/gdb/config/Makefile.i386 b/gnu/usr.bin/gdb/config/Makefile.i386 new file mode 100644 index 000000000000..cc52aa3b13d4 --- /dev/null +++ b/gnu/usr.bin/gdb/config/Makefile.i386 @@ -0,0 +1,6 @@ +# @(#)Makefile.i386 6.2 (Berkeley) 3/21/91 + +CONFIGSRCS= i386bsd-dep.c i386-pinsn.c + +param.h: + ln -s $(.CURDIR)/config/m-i386bsd.h param.h diff --git a/gnu/usr.bin/gdb/config/default-dep.c b/gnu/usr.bin/gdb/config/default-dep.c new file mode 100644 index 000000000000..13fe7b95a49e --- /dev/null +++ b/gnu/usr.bin/gdb/config/default-dep.c @@ -0,0 +1,585 @@ +/*- + * This code is derived from software copyrighted by the Free Software + * Foundation. + * + * Modified 1991 by Donn Seeley at UUNET Technologies, Inc. + */ + +#ifndef lint +static char sccsid[] = "@(#)default-dep.c 6.3 (Berkeley) 5/8/91"; +#endif /* not lint */ + +/* Low level interface to ptrace, for GDB when running under Unix. + Copyright (C) 1988, 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <stdio.h> +#include "defs.h" +#include "param.h" +#include "frame.h" +#include "inferior.h" + +#ifdef USG +#include <sys/types.h> +#endif + +#include <sys/param.h> +#include <sys/dir.h> +#include <signal.h> +#include <sys/ioctl.h> +/* #include <fcntl.h> Can we live without this? */ + +#ifdef COFF_ENCAPSULATE +#include "a.out.encap.h" +#else +#include <a.out.h> +#endif +#ifndef N_SET_MAGIC +#define N_SET_MAGIC(exec, val) ((exec).a_magic = (val)) +#endif + +#include <sys/user.h> /* After a.out.h */ +#include <sys/file.h> +#include <sys/stat.h> + +extern int errno; + +/* This function simply calls ptrace with the given arguments. + It exists so that all calls to ptrace are isolated in this + machine-dependent file. */ +int +call_ptrace (request, pid, arg3, arg4) + int request, pid, arg3, arg4; +{ + return ptrace (request, pid, arg3, arg4); +} + +kill_inferior () +{ + if (remote_debugging) + return; + if (inferior_pid == 0) + return; + ptrace (8, inferior_pid, 0, 0); + wait (0); + 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); +} + +/* Resume execution of the inferior process. + If STEP is nonzero, single-step it. + If SIGNAL is nonzero, give it that signal. */ + +void +resume (step, signal) + int step; + int signal; +{ + errno = 0; + if (remote_debugging) + remote_resume (step, signal); + else + { + ptrace (step ? 9 : 7, inferior_pid, 1, signal); + if (errno) + perror_with_name ("ptrace"); + } +} + +void +fetch_inferior_registers () +{ + register int regno; + register unsigned int regaddr; + char buf[MAX_REGISTER_RAW_SIZE]; + register int i; + + struct user u; + unsigned int offset = (char *) &u.u_ar0 - (char *) &u; + offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; + + for (regno = 0; regno < NUM_REGS; regno++) + { + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0); + regaddr += sizeof (int); + } + supply_register (regno, buf); + } +} + +/* 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) + int regno; +{ + register unsigned int regaddr; + char buf[80]; + + struct user u; + unsigned int offset = (char *) &u.u_ar0 - (char *) &u; + offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; + + if (regno >= 0) + { + regaddr = register_addr (regno, offset); + errno = 0; + ptrace (6, inferior_pid, regaddr, read_register (regno)); + if (errno != 0) + { + sprintf (buf, "writing register number %d", regno); + perror_with_name (buf); + } + } + 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) + { + sprintf (buf, "writing all regs, number %d", regno); + perror_with_name (buf); + } + } +} + +/* Copy LEN bytes from inferior's memory starting at MEMADDR + to debugger memory starting at MYADDR. + On failure (cannot read from inferior, usually because address is out + of bounds) returns the value of errno. */ + +int +read_inferior_memory (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & - sizeof (int); + /* Round ending address up; get number of longwords that makes. */ + register int count + = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); + /* Allocate buffer of that many longwords. */ + register int *buffer = (int *) alloca (count * sizeof (int)); + extern int errno; + + /* Read all the longwords */ + for (i = 0; i < count; i++, addr += sizeof (int)) + { + errno = 0; +#if 0 + /* This is now done by read_memory, because when this function did it, + reading a byte or short int hardware port read whole longs, causing + serious side effects + such as bus errors and unexpected hardware operation. This would + also be a problem with ptrace if the inferior process could read + or write hardware registers, but that's not usually the case. */ + if (remote_debugging) + buffer[i] = remote_fetch_word (addr); + else +#endif + buffer[i] = ptrace (1, inferior_pid, addr, 0); + if (errno) + return errno; + } + + /* Copy appropriate bytes out of the buffer. */ + bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len); + return 0; +} + +/* Copy LEN bytes of data from debugger memory at MYADDR + to inferior's memory at MEMADDR. + On failure (cannot write the inferior) + returns the value of errno. */ + +int +write_inferior_memory (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & - sizeof (int); + /* Round ending address up; get number of longwords that makes. */ + register int count + = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); + /* Allocate buffer of that many longwords. */ + register int *buffer = (int *) alloca (count * sizeof (int)); + extern int errno; + + /* Fill start and end extra bytes of buffer with existing memory data. */ + + if (remote_debugging) + return (remote_write_inferior_memory(memaddr, myaddr, len)); + + buffer[0] = ptrace (1, inferior_pid, addr, 0); + + if (count > 1) + buffer[count - 1] = ptrace (1, inferior_pid, + addr + (count - 1) * sizeof (int), 0); + + /* Copy data to be written over corresponding part of buffer */ + + bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len); + + /* Write the entire buffer. */ + + for (i = 0; i < count; i++, addr += sizeof (int)) + { + errno = 0; + ptrace (4, inferior_pid, addr, buffer[i]); + if (errno) + return errno; + } + + return 0; +} + +/* Work with core dump and executable files, for GDB. + This code would be in core.c if it weren't machine-dependent. */ + +#ifndef N_TXTADDR +#define N_TXTADDR(hdr) 0 +#endif /* no N_TXTADDR */ + +#ifndef N_DATADDR +#define N_DATADDR(hdr) hdr.a_text +#endif /* no N_DATADDR */ + +/* Make COFF and non-COFF names for things a little more compatible + to reduce conditionals later. */ + +#ifdef COFF_FORMAT +#define a_magic magic +#endif + +#ifndef COFF_FORMAT +#ifndef AOUTHDR +#define AOUTHDR struct exec +#endif +#endif + +extern char *sys_siglist[]; + + +/* Hook for `exec_file_command' command to call. */ + +extern void (*exec_file_display_hook) (); + +/* File names of core file and executable file. */ + +extern char *corefile; +extern char *execfile; + +/* Descriptors on which core file and executable file are open. + Note that the execchan is closed when an inferior is created + and reopened if the inferior dies or is killed. */ + +extern int corechan; +extern int execchan; + +/* Last modification time of executable file. + Also used in source.c to compare against mtime of a source file. */ + +extern int exec_mtime; + +/* Virtual addresses of bounds of the two areas of memory in the core file. */ + +extern CORE_ADDR data_start; +extern CORE_ADDR data_end; +extern CORE_ADDR stack_start; +extern CORE_ADDR stack_end; + +/* Virtual addresses of bounds of two areas of memory in the exec file. + Note that the data area in the exec file is used only when there is no core file. */ + +extern CORE_ADDR text_start; +extern CORE_ADDR text_end; + +extern CORE_ADDR exec_data_start; +extern CORE_ADDR exec_data_end; + +/* Address in executable file of start of text area data. */ + +extern int text_offset; + +/* Address in executable file of start of data area data. */ + +extern int exec_data_offset; + +/* Address in core file of start of data area data. */ + +extern int data_offset; + +/* Address in core file of start of stack area data. */ + +extern int stack_offset; + +#ifdef COFF_FORMAT +/* various coff data structures */ + +extern FILHDR file_hdr; +extern SCNHDR text_hdr; +extern SCNHDR data_hdr; + +#endif /* not COFF_FORMAT */ + +/* a.out header saved in core file. */ + +extern AOUTHDR core_aouthdr; + +/* a.out header of exec file. */ + +extern AOUTHDR exec_aouthdr; + +extern void validate_files (); + +core_file_command (filename, from_tty) + char *filename; + int from_tty; +{ + int val; + extern char registers[]; + + /* Discard all vestiges of any previous core file + and mark data and stack spaces as empty. */ + + if (corefile) + free (corefile); + corefile = 0; + + if (corechan >= 0) + close (corechan); + corechan = -1; + + data_start = 0; + data_end = 0; + stack_start = STACK_END_ADDR; + stack_end = STACK_END_ADDR; + + /* Now, if a new core file was specified, open it and digest it. */ + + if (filename) + { + filename = tilde_expand (filename); + make_cleanup (free, filename); + + if (have_inferior_p ()) + error ("To look at a core file, you must kill the inferior with \"kill\"."); + corechan = open (filename, O_RDONLY, 0); + if (corechan < 0) + perror_with_name (filename); + /* 4.2-style (and perhaps also sysV-style) core dump file. */ + { + struct user u; + + unsigned int reg_offset; + + val = myread (corechan, &u, sizeof u); + if (val < 0) + perror_with_name ("Not a core file: reading upage"); + if (val != sizeof u) + error ("Not a core file: could only read %d bytes", val); + + /* We are depending on exec_file_command having been called + previously to set exec_data_start. Since the executable + and the core file share the same text segment, the address + of the data segment will be the same in both. */ + data_start = exec_data_start; + + data_end = data_start + NBPG * u.u_dsize; + stack_start = stack_end - NBPG * u.u_ssize; + data_offset = NBPG * UPAGES; + stack_offset = NBPG * (UPAGES + u.u_dsize); + + /* Some machines put an absolute address in here and some put + the offset in the upage of the regs. */ + reg_offset = (int) u.u_ar0; + if (reg_offset > NBPG * UPAGES) + reg_offset -= KERNEL_U_ADDR; + + /* I don't know where to find this info. + So, for now, mark it as not available. */ + N_SET_MAGIC (core_aouthdr, 0); + + /* Read the register values out of the core file and store + them where `read_register' will find them. */ + + { + register int regno; + + for (regno = 0; regno < NUM_REGS; regno++) + { + char buf[MAX_REGISTER_RAW_SIZE]; + + val = lseek (corechan, register_addr (regno, reg_offset), 0); + if (val < 0 + || (val = myread (corechan, buf, sizeof buf)) < 0) + { + char * buffer = (char *) alloca (strlen (reg_names[regno]) + + 30); + strcpy (buffer, "Reading register "); + strcat (buffer, reg_names[regno]); + + perror_with_name (buffer); + } + + supply_register (regno, buf); + } + } + } + if (filename[0] == '/') + corefile = savestring (filename, strlen (filename)); + else + { + corefile = concat (current_directory, "/", filename); + } + + set_current_frame ( create_new_frame (read_register (FP_REGNUM), + read_pc ())); + select_frame (get_current_frame (), 0); + validate_files (); + } + else if (from_tty) + printf ("No core file now.\n"); +} + +exec_file_command (filename, from_tty) + char *filename; + int from_tty; +{ + int val; + + /* Eliminate all traces of old exec file. + Mark text segment as empty. */ + + if (execfile) + free (execfile); + execfile = 0; + data_start = 0; + data_end -= exec_data_start; + text_start = 0; + text_end = 0; + exec_data_start = 0; + exec_data_end = 0; + if (execchan >= 0) + close (execchan); + execchan = -1; + + /* Now open and digest the file the user requested, if any. */ + + if (filename) + { + filename = tilde_expand (filename); + make_cleanup (free, filename); + + execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0, + &execfile); + if (execchan < 0) + perror_with_name (filename); + +#ifdef COFF_FORMAT + { + int aout_hdrsize; + int num_sections; + + if (read_file_hdr (execchan, &file_hdr) < 0) + error ("\"%s\": not in executable format.", execfile); + + aout_hdrsize = file_hdr.f_opthdr; + num_sections = file_hdr.f_nscns; + + if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0) + error ("\"%s\": can't read optional aouthdr", execfile); + + if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections, + aout_hdrsize) < 0) + error ("\"%s\": can't read text section header", execfile); + + if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections, + aout_hdrsize) < 0) + error ("\"%s\": can't read data section header", execfile); + + text_start = exec_aouthdr.text_start; + text_end = text_start + exec_aouthdr.tsize; + text_offset = text_hdr.s_scnptr; + exec_data_start = exec_aouthdr.data_start; + exec_data_end = exec_data_start + exec_aouthdr.dsize; + exec_data_offset = data_hdr.s_scnptr; + data_start = exec_data_start; + data_end += exec_data_start; + exec_mtime = file_hdr.f_timdat; + } +#else /* not COFF_FORMAT */ + { + struct stat st_exec; + +#ifdef HEADER_SEEK_FD + HEADER_SEEK_FD (execchan); +#endif + + val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR)); + + if (val < 0) + perror_with_name (filename); + + text_start = N_TXTADDR (exec_aouthdr); + exec_data_start = N_DATADDR (exec_aouthdr); + + text_offset = N_TXTOFF (exec_aouthdr); + exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text; + + 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; + + if (fstat (execchan, &st_exec) < 0) + perror_with_name (filename); + exec_mtime = st_exec.st_mtime; + } +#endif /* not COFF_FORMAT */ + + validate_files (); + } + else if (from_tty) + printf ("No exec file now.\n"); + + /* Tell display code (if any) about the changed file name. */ + if (exec_file_display_hook) + (*exec_file_display_hook) (filename); +} diff --git a/gnu/usr.bin/gdb/config/i386-dep.c b/gnu/usr.bin/gdb/config/i386-dep.c new file mode 100644 index 000000000000..c4630d0c07ac --- /dev/null +++ b/gnu/usr.bin/gdb/config/i386-dep.c @@ -0,0 +1,1275 @@ +/* Low level interface to ptrace, for GDB when running on the Intel 386. + Copyright (C) 1988, 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <stdio.h> +#include "defs.h" +#include "param.h" +#include "frame.h" +#include "inferior.h" + +#ifdef USG +#include <sys/types.h> +#endif + +#include <sys/param.h> +#include <sys/dir.h> +#include <signal.h> +#include <sys/user.h> +#include <sys/ioctl.h> +#include <fcntl.h> + +#ifdef COFF_ENCAPSULATE +#include "a.out.encap.h" +#else +#include <a.out.h> +#endif + +#ifndef N_SET_MAGIC +#ifdef COFF_FORMAT +#define N_SET_MAGIC(exec, val) ((exec).magic = (val)) +#else +#define N_SET_MAGIC(exec, val) ((exec).a_magic = (val)) +#endif +#endif + +#include <sys/file.h> +#include <sys/stat.h> + +#include <sys/reg.h> + +extern int errno; + +/* This function simply calls ptrace with the given arguments. + It exists so that all calls to ptrace are isolated in this + machine-dependent file. */ +int +call_ptrace (request, pid, arg3, arg4) + int request, pid, arg3, arg4; +{ + return ptrace (request, pid, arg3, arg4); +} + +kill_inferior () +{ + if (remote_debugging) + return; + if (inferior_pid == 0) + return; + ptrace (8, inferior_pid, 0, 0); + wait (0); + 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); +} + +/* Resume execution of the inferior process. + If STEP is nonzero, single-step it. + If SIGNAL is nonzero, give it that signal. */ + +void +resume (step, signal) + int step; + int signal; +{ + errno = 0; + if (remote_debugging) + remote_resume (step, signal); + else + { + ptrace (step ? 9 : 7, inferior_pid, 1, signal); + if (errno) + perror_with_name ("ptrace"); + } +} + +void +fetch_inferior_registers () +{ + register int regno; + register unsigned int regaddr; + char buf[MAX_REGISTER_RAW_SIZE]; + register int i; + + struct user u; + unsigned int offset = (char *) &u.u_ar0 - (char *) &u; + offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; + + for (regno = 0; regno < NUM_REGS; regno++) + { + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0); + regaddr += sizeof (int); + } + supply_register (regno, buf); + } +} + +/* 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) + int regno; +{ + register unsigned int regaddr; + char buf[80]; + + struct user u; + unsigned int offset = (char *) &u.u_ar0 - (char *) &u; + offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; + + if (regno >= 0) + { + regaddr = register_addr (regno, offset); + errno = 0; + ptrace (6, inferior_pid, regaddr, read_register (regno)); + if (errno != 0) + { + sprintf (buf, "writing register number %d", regno); + perror_with_name (buf); + } + } + 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) + { + sprintf (buf, "writing register number %d", regno); + perror_with_name (buf); + } + } +} + +/* Copy LEN bytes from inferior's memory starting at MEMADDR + to debugger memory starting at MYADDR. + On failure (cannot read from inferior, usually because address is out + of bounds) returns the value of errno. */ + +int +read_inferior_memory (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & - sizeof (int); + /* Round ending address up; get number of longwords that makes. */ + register int count + = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); + /* Allocate buffer of that many longwords. */ + register int *buffer = (int *) alloca (count * sizeof (int)); + extern int errno; + + /* Read all the longwords */ + for (i = 0; i < count; i++, addr += sizeof (int)) + { + errno = 0; + if (remote_debugging) + buffer[i] = remote_fetch_word (addr); + else + buffer[i] = ptrace (1, inferior_pid, addr, 0); + if (errno) + return errno; + } + + /* Copy appropriate bytes out of the buffer. */ + bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len); + return 0; +} + +/* Copy LEN bytes of data from debugger memory at MYADDR + to inferior's memory at MEMADDR. + On failure (cannot write the inferior) + returns the value of errno. */ + +int +write_inferior_memory (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & - sizeof (int); + /* Round ending address up; get number of longwords that makes. */ + register int count + = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); + /* Allocate buffer of that many longwords. */ + register int *buffer = (int *) alloca (count * sizeof (int)); + extern int errno; + + /* Fill start and end extra bytes of buffer with existing memory data. */ + + if (remote_debugging) + buffer[0] = remote_fetch_word (addr); + else + buffer[0] = ptrace (1, inferior_pid, addr, 0); + + if (count > 1) + { + if (remote_debugging) + buffer[count - 1] + = remote_fetch_word (addr + (count - 1) * sizeof (int)); + else + buffer[count - 1] + = ptrace (1, inferior_pid, + addr + (count - 1) * sizeof (int), 0); + } + + /* Copy data to be written over corresponding part of buffer */ + + bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len); + + /* Write the entire buffer. */ + + for (i = 0; i < count; i++, addr += sizeof (int)) + { + errno = 0; + if (remote_debugging) + remote_store_word (addr, buffer[i]); + else + ptrace (4, inferior_pid, addr, buffer[i]); + if (errno) + return errno; + } + + return 0; +} + +/* Work with core dump and executable files, for GDB. + This code would be in core.c if it weren't machine-dependent. */ + +#ifndef N_TXTADDR +#define N_TXTADDR(hdr) 0 +#endif /* no N_TXTADDR */ + +#ifndef N_DATADDR +#define N_DATADDR(hdr) hdr.a_text +#endif /* no N_DATADDR */ + +/* Make COFF and non-COFF names for things a little more compatible + to reduce conditionals later. */ + +#ifndef COFF_FORMAT +#ifndef AOUTHDR +#define AOUTHDR struct exec +#endif +#endif + +extern char *sys_siglist[]; + + +/* Hook for `exec_file_command' command to call. */ + +extern void (*exec_file_display_hook) (); + +/* File names of core file and executable file. */ + +extern char *corefile; +extern char *execfile; + +/* Descriptors on which core file and executable file are open. + Note that the execchan is closed when an inferior is created + and reopened if the inferior dies or is killed. */ + +extern int corechan; +extern int execchan; + +/* Last modification time of executable file. + Also used in source.c to compare against mtime of a source file. */ + +extern int exec_mtime; + +/* Virtual addresses of bounds of the two areas of memory in the core file. */ + +extern CORE_ADDR data_start; +extern CORE_ADDR data_end; +extern CORE_ADDR stack_start; +extern CORE_ADDR stack_end; + +/* Virtual addresses of bounds of two areas of memory in the exec file. + Note that the data area in the exec file is used only when there is no core file. */ + +extern CORE_ADDR text_start; +extern CORE_ADDR text_end; + +extern CORE_ADDR exec_data_start; +extern CORE_ADDR exec_data_end; + +/* Address in executable file of start of text area data. */ + +extern int text_offset; + +/* Address in executable file of start of data area data. */ + +extern int exec_data_offset; + +/* Address in core file of start of data area data. */ + +extern int data_offset; + +/* Address in core file of start of stack area data. */ + +extern int stack_offset; + +#ifdef COFF_FORMAT +/* various coff data structures */ + +extern FILHDR file_hdr; +extern SCNHDR text_hdr; +extern SCNHDR data_hdr; + +#endif /* not COFF_FORMAT */ + +/* a.out header saved in core file. */ + +extern AOUTHDR core_aouthdr; + +/* a.out header of exec file. */ + +extern AOUTHDR exec_aouthdr; + +extern void validate_files (); + +core_file_command (filename, from_tty) + char *filename; + int from_tty; +{ + int val; + extern char registers[]; + + /* Discard all vestiges of any previous core file + and mark data and stack spaces as empty. */ + + if (corefile) + free (corefile); + corefile = 0; + + if (corechan >= 0) + close (corechan); + corechan = -1; + + data_start = 0; + data_end = 0; + stack_start = STACK_END_ADDR; + stack_end = STACK_END_ADDR; + + /* Now, if a new core file was specified, open it and digest it. */ + + if (filename) + { + filename = tilde_expand (filename); + make_cleanup (free, filename); + + if (have_inferior_p ()) + error ("To look at a core file, you must kill the inferior with \"kill\"."); + corechan = open (filename, O_RDONLY, 0); + if (corechan < 0) + perror_with_name (filename); + /* 4.2-style (and perhaps also sysV-style) core dump file. */ + { + struct user u; + + int reg_offset; + + val = myread (corechan, &u, sizeof u); + if (val < 0) + perror_with_name (filename); + data_start = exec_data_start; + + data_end = data_start + NBPG * u.u_dsize; + stack_start = stack_end - NBPG * u.u_ssize; + data_offset = NBPG * UPAGES; + stack_offset = NBPG * (UPAGES + u.u_dsize); + reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR; + + /* I don't know where to find this info. + So, for now, mark it as not available. */ +/* N_SET_MAGIC (core_aouthdr, 0); */ + bzero ((char *) &core_aouthdr, sizeof core_aouthdr); + + /* Read the register values out of the core file and store + them where `read_register' will find them. */ + + { + register int regno; + + for (regno = 0; regno < NUM_REGS; regno++) + { + char buf[MAX_REGISTER_RAW_SIZE]; + + val = lseek (corechan, register_addr (regno, reg_offset), 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); + } + } + } + if (filename[0] == '/') + corefile = savestring (filename, strlen (filename)); + else + { + corefile = concat (current_directory, "/", filename); + } + + set_current_frame ( create_new_frame (read_register (FP_REGNUM), + read_pc ())); + select_frame (get_current_frame (), 0); + validate_files (); + } + else if (from_tty) + printf ("No core file now.\n"); +} + +exec_file_command (filename, from_tty) + char *filename; + int from_tty; +{ + int val; + + /* Eliminate all traces of old exec file. + Mark text segment as empty. */ + + if (execfile) + free (execfile); + execfile = 0; + data_start = 0; + data_end -= exec_data_start; + text_start = 0; + text_end = 0; + exec_data_start = 0; + exec_data_end = 0; + if (execchan >= 0) + close (execchan); + execchan = -1; + + /* Now open and digest the file the user requested, if any. */ + + if (filename) + { + filename = tilde_expand (filename); + make_cleanup (free, filename); + + execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0, + &execfile); + if (execchan < 0) + perror_with_name (filename); + +#ifdef COFF_FORMAT + { + int aout_hdrsize; + int num_sections; + + if (read_file_hdr (execchan, &file_hdr) < 0) + error ("\"%s\": not in executable format.", execfile); + + aout_hdrsize = file_hdr.f_opthdr; + num_sections = file_hdr.f_nscns; + + if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0) + error ("\"%s\": can't read optional aouthdr", execfile); + + if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections, + aout_hdrsize) < 0) + error ("\"%s\": can't read text section header", execfile); + + if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections, + aout_hdrsize) < 0) + error ("\"%s\": can't read data section header", execfile); + + text_start = exec_aouthdr.text_start; + text_end = text_start + exec_aouthdr.tsize; + text_offset = text_hdr.s_scnptr; + exec_data_start = exec_aouthdr.data_start; + exec_data_end = exec_data_start + exec_aouthdr.dsize; + exec_data_offset = data_hdr.s_scnptr; + data_start = exec_data_start; + data_end += exec_data_start; + exec_mtime = file_hdr.f_timdat; + } +#else /* not COFF_FORMAT */ + { + struct stat st_exec; + +#ifdef HEADER_SEEK_FD + HEADER_SEEK_FD (execchan); +#endif + + val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR)); + + if (val < 0) + perror_with_name (filename); + + text_start = N_TXTADDR (exec_aouthdr); + exec_data_start = N_DATADDR (exec_aouthdr); + + text_offset = N_TXTOFF (exec_aouthdr); + exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text; + + 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; + + fstat (execchan, &st_exec); + exec_mtime = st_exec.st_mtime; + } +#endif /* not COFF_FORMAT */ + + validate_files (); + } + else if (from_tty) + printf ("No exec file now.\n"); + + /* Tell display code (if any) about the changed file name. */ + if (exec_file_display_hook) + (*exec_file_display_hook) (filename); +} + +/* helper functions for m-i386.h */ + +/* stdio style buffering to minimize calls to ptrace */ +static CORE_ADDR codestream_next_addr; +static CORE_ADDR codestream_addr; +static unsigned char codestream_buf[sizeof (int)]; +static int codestream_off; +static int codestream_cnt; + +#define codestream_tell() (codestream_addr + codestream_off) +#define codestream_peek() (codestream_cnt == 0 ? \ + codestream_fill(1): codestream_buf[codestream_off]) +#define codestream_get() (codestream_cnt-- == 0 ? \ + codestream_fill(0) : codestream_buf[codestream_off++]) + +static unsigned char +codestream_fill (peek_flag) +{ + codestream_addr = codestream_next_addr; + codestream_next_addr += sizeof (int); + codestream_off = 0; + codestream_cnt = sizeof (int); + read_memory (codestream_addr, + (unsigned char *)codestream_buf, + sizeof (int)); + + if (peek_flag) + return (codestream_peek()); + else + return (codestream_get()); +} + +static void +codestream_seek (place) +{ + codestream_next_addr = place & -sizeof (int); + codestream_cnt = 0; + codestream_fill (1); + while (codestream_tell() != place) + codestream_get (); +} + +static void +codestream_read (buf, count) + unsigned char *buf; +{ + unsigned char *p; + int i; + p = buf; + for (i = 0; i < count; i++) + *p++ = codestream_get (); +} + +/* next instruction is a jump, move to target */ +static +i386_follow_jump () +{ + int long_delta; + short short_delta; + char byte_delta; + int data16; + int pos; + + pos = codestream_tell (); + + data16 = 0; + if (codestream_peek () == 0x66) + { + codestream_get (); + data16 = 1; + } + + switch (codestream_get ()) + { + case 0xe9: + /* relative jump: if data16 == 0, disp32, else disp16 */ + if (data16) + { + codestream_read ((unsigned char *)&short_delta, 2); + pos += short_delta + 3; /* include size of jmp inst */ + } + else + { + codestream_read ((unsigned char *)&long_delta, 4); + pos += long_delta + 5; + } + break; + case 0xeb: + /* relative jump, disp8 (ignore data16) */ + codestream_read ((unsigned char *)&byte_delta, 1); + pos += byte_delta + 2; + break; + } + codestream_seek (pos + data16); +} + +/* + * find & return amound a local space allocated, and advance codestream to + * first register push (if any) + * + * if entry sequence doesn't make sense, return -1, and leave + * codestream pointer random + */ +static long +i386_get_frame_setup (pc) +{ + unsigned char op; + + codestream_seek (pc); + + i386_follow_jump (); + + op = codestream_get (); + + if (op == 0x58) /* popl %eax */ + { + /* + * this function must start with + * + * popl %eax 0x58 + * xchgl %eax, (%esp) 0x87 0x04 0x24 + * or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00 + * + * (the system 5 compiler puts out the second xchg + * inst, and the assembler doesn't try to optimize it, + * so the 'sib' form gets generated) + * + * this sequence is used to get the address of the return + * buffer for a function that returns a structure + */ + int pos; + unsigned char buf[4]; + static unsigned char proto1[3] = { 0x87,0x04,0x24 }; + static unsigned char proto2[4] = { 0x87,0x44,0x24,0x00 }; + pos = codestream_tell (); + codestream_read (buf, 4); + if (bcmp (buf, proto1, 3) == 0) + pos += 3; + else if (bcmp (buf, proto2, 4) == 0) + pos += 4; + + codestream_seek (pos); + op = codestream_get (); /* update next opcode */ + } + + if (op == 0x55) /* pushl %esp */ + { + /* check for movl %esp, %ebp - can be written two ways */ + switch (codestream_get ()) + { + case 0x8b: + if (codestream_get () != 0xec) + return (-1); + break; + case 0x89: + if (codestream_get () != 0xe5) + return (-1); + break; + default: + return (-1); + } + /* check for stack adjustment + * + * subl $XXX, %esp + * + * note: you can't subtract a 16 bit immediate + * from a 32 bit reg, so we don't have to worry + * about a data16 prefix + */ + op = codestream_peek (); + if (op == 0x83) + { + /* subl with 8 bit immed */ + codestream_get (); + if (codestream_get () != 0xec) + return (-1); + /* subl with signed byte immediate + * (though it wouldn't make sense to be negative) + */ + return (codestream_get()); + } + else if (op == 0x81) + { + /* subl with 32 bit immed */ + int locals; + codestream_get(); + if (codestream_get () != 0xec) + return (-1); + /* subl with 32 bit immediate */ + codestream_read ((unsigned char *)&locals, 4); + return (locals); + } + else + { + return (0); + } + } + else if (op == 0xc8) + { + /* enter instruction: arg is 16 bit unsigned immed */ + unsigned short slocals; + codestream_read ((unsigned char *)&slocals, 2); + codestream_get (); /* flush final byte of enter instruction */ + return (slocals); + } + return (-1); +} + +/* Return number of args passed to a frame. + Can return -1, meaning no way to tell. */ + +/* on the 386, the instruction following the call could be: + * popl %ecx - one arg + * addl $imm, %esp - imm/4 args; imm may be 8 or 32 bits + * anything else - zero args + */ + +int +i386_frame_num_args (fi) + struct frame_info fi; +{ + int retpc; + unsigned char op; + struct frame_info *pfi; + + pfi = get_prev_frame_info ((fi)); + if (pfi == 0) + { + /* Note: this can happen if we are looking at the frame for + main, because FRAME_CHAIN_VALID won't let us go into + start. If we have debugging symbols, that's not really + a big deal; it just means it will only show as many arguments + to main as are declared. */ + return -1; + } + else + { + retpc = pfi->pc; + op = read_memory_integer (retpc, 1); + if (op == 0x59) + /* pop %ecx */ + return 1; + else if (op == 0x83) + { + op = read_memory_integer (retpc+1, 1); + if (op == 0xc4) + /* addl $<signed imm 8 bits>, %esp */ + return (read_memory_integer (retpc+2,1)&0xff)/4; + else + return 0; + } + else if (op == 0x81) + { /* add with 32 bit immediate */ + op = read_memory_integer (retpc+1, 1); + if (op == 0xc4) + /* addl $<imm 32>, %esp */ + return read_memory_integer (retpc+2, 4) / 4; + else + return 0; + } + else + { + return 0; + } + } +} + +/* + * parse the first few instructions of the function to see + * what registers were stored. + * + * We handle these cases: + * + * The startup sequence can be at the start of the function, + * or the function can start with a branch to startup code at the end. + * + * %ebp can be set up with either the 'enter' instruction, or + * 'pushl %ebp, movl %esp, %ebp' (enter is too slow to be useful, + * but was once used in the sys5 compiler) + * + * Local space is allocated just below the saved %ebp by either the + * 'enter' instruction, or by 'subl $<size>, %esp'. 'enter' has + * a 16 bit unsigned argument for space to allocate, and the + * 'addl' instruction could have either a signed byte, or + * 32 bit immediate. + * + * Next, the registers used by this function are pushed. In + * the sys5 compiler they will always be in the order: %edi, %esi, %ebx + * (and sometimes a harmless bug causes it to also save but not restore %eax); + * however, the code below is willing to see the pushes in any order, + * and will handle up to 8 of them. + * + * If the setup sequence is at the end of the function, then the + * next instruction will be a branch back to the start. + */ + +i386_frame_find_saved_regs (fip, fsrp) + struct frame_info *fip; + struct frame_saved_regs *fsrp; +{ + unsigned long locals; + unsigned char *p; + unsigned char op; + CORE_ADDR dummy_bottom; + CORE_ADDR adr; + int i; + + bzero (fsrp, sizeof *fsrp); + + /* if frame is the end of a dummy, compute where the + * beginning would be + */ + dummy_bottom = fip->frame - 4 - NUM_REGS*4 - CALL_DUMMY_LENGTH; + + /* check if the PC is in the stack, in a dummy frame */ + if (dummy_bottom <= fip->pc && fip->pc <= fip->frame) + { + /* all regs were saved by push_call_dummy () */ + adr = fip->frame - 4; + for (i = 0; i < NUM_REGS; i++) + { + fsrp->regs[i] = adr; + adr -= 4; + } + return; + } + + locals = i386_get_frame_setup (get_pc_function_start (fip->pc)); + + if (locals >= 0) + { + adr = fip->frame - 4 - locals; + for (i = 0; i < 8; i++) + { + op = codestream_get (); + if (op < 0x50 || op > 0x57) + break; + fsrp->regs[op - 0x50] = adr; + adr -= 4; + } + } + + fsrp->regs[PC_REGNUM] = fip->frame + 4; + fsrp->regs[FP_REGNUM] = fip->frame; +} + +/* return pc of first real instruction */ +i386_skip_prologue (pc) +{ + unsigned char op; + int i; + + if (i386_get_frame_setup (pc) < 0) + return (pc); + + /* found valid frame setup - codestream now points to + * start of push instructions for saving registers + */ + + /* skip over register saves */ + for (i = 0; i < 8; i++) + { + op = codestream_peek (); + /* break if not pushl inst */ + if (op < 0x50 || op > 0x57) + break; + codestream_get (); + } + + i386_follow_jump (); + + return (codestream_tell ()); +} + +i386_push_dummy_frame () +{ + CORE_ADDR sp = read_register (SP_REGNUM); + 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 < NUM_REGS; regnum++) + sp = push_word (sp, read_register (regnum)); + write_register (SP_REGNUM, sp); +} + +i386_pop_frame () +{ + FRAME frame = get_current_frame (); + CORE_ADDR fp; + int regnum; + struct frame_saved_regs fsr; + struct frame_info *fi; + + fi = get_frame_info (frame); + fp = fi->frame; + get_frame_saved_regs (fi, &fsr); + for (regnum = 0; regnum < NUM_REGS; regnum++) + { + CORE_ADDR adr; + adr = fsr.regs[regnum]; + if (adr) + write_register (regnum, read_memory_integer (adr, 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); + flush_cached_frames (); + set_current_frame ( create_new_frame (read_register (FP_REGNUM), + read_pc ())); +} + +/* this table must line up with REGISTER_NAMES in m-i386.h */ +/* symbols like 'EAX' come from <sys/reg.h> */ +static int regmap[] = +{ + EAX, ECX, EDX, EBX, + UESP, EBP, ESI, EDI, + EIP, EFL, CS, SS, + DS, ES, FS, GS, +}; + +/* blockend is the value of u.u_ar0, and points to the + * place where GS is stored + */ +i386_register_u_addr (blockend, regnum) +{ +#if 0 + /* this will be needed if fp registers are reinstated */ + /* for now, you can look at them with 'info float' + * sys5 wont let you change them with ptrace anyway + */ + if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM) + { + int ubase, fpstate; + struct user u; + ubase = blockend + 4 * (SS + 1) - KSTKSZ; + fpstate = ubase + ((char *)&u.u_fpstate - (char *)&u); + return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM)); + } + else +#endif + return (blockend + 4 * regmap[regnum]); + +} + +i387_to_double (from, to) + char *from; + char *to; +{ + long *lp; + /* push extended mode on 387 stack, then pop in double mode + * + * first, set exception masks so no error is generated - + * number will be rounded to inf or 0, if necessary + */ + asm ("pushl %eax"); /* grab a stack slot */ + asm ("fstcw (%esp)"); /* get 387 control word */ + asm ("movl (%esp),%eax"); /* save old value */ + asm ("orl $0x3f,%eax"); /* mask all exceptions */ + asm ("pushl %eax"); + asm ("fldcw (%esp)"); /* load new value into 387 */ + + asm ("movl 8(%ebp),%eax"); + asm ("fldt (%eax)"); /* push extended number on 387 stack */ + asm ("fwait"); + asm ("movl 12(%ebp),%eax"); + asm ("fstpl (%eax)"); /* pop double */ + asm ("fwait"); + + asm ("popl %eax"); /* flush modified control word */ + asm ("fnclex"); /* clear exceptions */ + asm ("fldcw (%esp)"); /* restore original control word */ + asm ("popl %eax"); /* flush saved copy */ +} + +double_to_i387 (from, to) + char *from; + char *to; +{ + /* push double mode on 387 stack, then pop in extended mode + * no errors are possible because every 64-bit pattern + * can be converted to an extended + */ + asm ("movl 8(%ebp),%eax"); + asm ("fldl (%eax)"); + asm ("fwait"); + asm ("movl 12(%ebp),%eax"); + asm ("fstpt (%eax)"); + asm ("fwait"); +} + +struct env387 +{ + unsigned short control; + unsigned short r0; + unsigned short status; + unsigned short r1; + unsigned short tag; + unsigned short r2; + unsigned long eip; + unsigned short code_seg; + unsigned short opcode; + unsigned long operand; + unsigned short operand_seg; + unsigned short r3; + unsigned char regs[8][10]; +}; + +static +print_387_control_word (control) +unsigned short control; +{ + printf ("control 0x%04x: ", control); + printf ("compute to "); + switch ((control >> 8) & 3) + { + case 0: printf ("24 bits; "); break; + case 1: printf ("(bad); "); break; + case 2: printf ("53 bits; "); break; + case 3: printf ("64 bits; "); break; + } + printf ("round "); + switch ((control >> 10) & 3) + { + case 0: printf ("NEAREST; "); break; + case 1: printf ("DOWN; "); break; + case 2: printf ("UP; "); break; + case 3: printf ("CHOP; "); break; + } + if (control & 0x3f) + { + printf ("mask:"); + if (control & 0x0001) printf (" INVALID"); + if (control & 0x0002) printf (" DENORM"); + if (control & 0x0004) printf (" DIVZ"); + if (control & 0x0008) printf (" OVERF"); + if (control & 0x0010) printf (" UNDERF"); + if (control & 0x0020) printf (" LOS"); + printf (";"); + } + printf ("\n"); + if (control & 0xe080) printf ("warning: reserved bits on 0x%x\n", + control & 0xe080); +} + +static +print_387_status_word (status) + unsigned short status; +{ + printf ("status 0x%04x: ", status); + if (status & 0xff) + { + printf ("exceptions:"); + if (status & 0x0001) printf (" INVALID"); + if (status & 0x0002) printf (" DENORM"); + if (status & 0x0004) printf (" DIVZ"); + if (status & 0x0008) printf (" OVERF"); + if (status & 0x0010) printf (" UNDERF"); + if (status & 0x0020) printf (" LOS"); + if (status & 0x0040) printf (" FPSTACK"); + printf ("; "); + } + printf ("flags: %d%d%d%d; ", + (status & 0x4000) != 0, + (status & 0x0400) != 0, + (status & 0x0200) != 0, + (status & 0x0100) != 0); + + printf ("top %d\n", (status >> 11) & 7); +} + +static +print_387_status (status, ep) + unsigned short status; + struct env387 *ep; +{ + int i; + int bothstatus; + int top; + int fpreg; + unsigned char *p; + + bothstatus = ((status != 0) && (ep->status != 0)); + if (status != 0) + { + if (bothstatus) + printf ("u: "); + print_387_status_word (status); + } + + if (ep->status != 0) + { + if (bothstatus) + printf ("e: "); + print_387_status_word (ep->status); + } + + print_387_control_word (ep->control); + printf ("last exception: "); + printf ("opcode 0x%x; ", ep->opcode); + printf ("pc 0x%x:0x%x; ", ep->code_seg, ep->eip); + printf ("operand 0x%x:0x%x\n", ep->operand_seg, ep->operand); + + top = (ep->status >> 11) & 7; + + printf ("regno tag msb lsb value\n"); + for (fpreg = 7; fpreg >= 0; fpreg--) + { + double val; + + printf ("%s %d: ", fpreg == top ? "=>" : " ", fpreg); + + switch ((ep->tag >> (fpreg * 2)) & 3) + { + case 0: printf ("valid "); break; + case 1: printf ("zero "); break; + case 2: printf ("trap "); break; + case 3: printf ("empty "); break; + } + for (i = 9; i >= 0; i--) + printf ("%02x", ep->regs[fpreg][i]); + + i387_to_double (ep->regs[fpreg], (char *)&val); + printf (" %g\n", val); + } + if (ep->r0) + printf ("warning: reserved0 is 0x%x\n", ep->r0); + if (ep->r1) + printf ("warning: reserved1 is 0x%x\n", ep->r1); + if (ep->r2) + printf ("warning: reserved2 is 0x%x\n", ep->r2); + if (ep->r3) + printf ("warning: reserved3 is 0x%x\n", ep->r3); +} + +#ifndef U_FPSTATE +#define U_FPSTATE(u) u.u_fpstate +#endif + +i386_float_info () +{ + struct user u; /* just for address computations */ + int i; + /* fpstate defined in <sys/user.h> */ + struct fpstate *fpstatep; + char buf[sizeof (struct fpstate) + 2 * sizeof (int)]; + unsigned int uaddr; + char fpvalid; + unsigned int rounded_addr; + unsigned int rounded_size; + extern int corechan; + int skip; + + uaddr = (char *)&u.u_fpvalid - (char *)&u; + if (have_inferior_p()) + { + unsigned int data; + unsigned int mask; + + rounded_addr = uaddr & -sizeof (int); + data = ptrace (3, inferior_pid, rounded_addr, 0); + mask = 0xff << ((uaddr - rounded_addr) * 8); + + fpvalid = ((data & mask) != 0); + } + else + { + if (lseek (corechan, uaddr, 0) < 0) + perror ("seek on core file"); + if (myread (corechan, &fpvalid, 1) < 0) + perror ("read on core file"); + + } + + if (fpvalid == 0) + { + printf ("no floating point status saved\n"); + return; + } + + uaddr = (char *)&U_FPSTATE(u) - (char *)&u; + if (have_inferior_p ()) + { + int *ip; + + rounded_addr = uaddr & -sizeof (int); + rounded_size = (((uaddr + sizeof (struct fpstate)) - uaddr) + + sizeof (int) - 1) / sizeof (int); + skip = uaddr - rounded_addr; + + ip = (int *)buf; + for (i = 0; i < rounded_size; i++) + { + *ip++ = ptrace (3, inferior_pid, rounded_addr, 0); + rounded_addr += sizeof (int); + } + } + else + { + if (lseek (corechan, uaddr, 0) < 0) + perror_with_name ("seek on core file"); + if (myread (corechan, buf, sizeof (struct fpstate)) < 0) + perror_with_name ("read from core file"); + skip = 0; + } + + fpstatep = (struct fpstate *)(buf + skip); + print_387_status (fpstatep->status, (struct env387 *)fpstatep->state); +} + diff --git a/gnu/usr.bin/gdb/config/i386-pinsn.c b/gnu/usr.bin/gdb/config/i386-pinsn.c new file mode 100644 index 000000000000..649baaf56bf6 --- /dev/null +++ b/gnu/usr.bin/gdb/config/i386-pinsn.c @@ -0,0 +1,1812 @@ +/* Print i386 instructions for GDB, the GNU debugger. + Copyright (C) 1988, 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu) + * July 1988 + */ + +/* + * The main tables describing the instructions is essentially a copy + * of the "Opcode Map" chapter (Appendix A) of the Intel 80386 + * Programmers Manual. Usually, there is a capital letter, followed + * by a small letter. The capital letter tell the addressing mode, + * and the small letter tells about the operand size. Refer to + * the Intel manual for details. + */ + +#include <stdio.h> +#include <ctype.h> + +#define Eb OP_E, b_mode +#define indirEb OP_indirE, b_mode +#define Gb OP_G, b_mode +#define Ev OP_E, v_mode +#define indirEv OP_indirE, v_mode +#define Ew OP_E, w_mode +#define Ma OP_E, v_mode +#define M OP_E, 0 +#define Mp OP_E, 0 /* ? */ +#define Gv OP_G, v_mode +#define Gw OP_G, w_mode +#define Rw OP_rm, w_mode +#define Rd OP_rm, d_mode +#define Ib OP_I, b_mode +#define sIb OP_sI, b_mode /* sign extened byte */ +#define Iv OP_I, v_mode +#define Iw OP_I, w_mode +#define Jb OP_J, b_mode +#define Jv OP_J, v_mode +#define ONE OP_ONE, 0 +#define Cd OP_C, d_mode +#define Dd OP_D, d_mode +#define Td OP_T, d_mode + +#define eAX OP_REG, eAX_reg +#define eBX OP_REG, eBX_reg +#define eCX OP_REG, eCX_reg +#define eDX OP_REG, eDX_reg +#define eSP OP_REG, eSP_reg +#define eBP OP_REG, eBP_reg +#define eSI OP_REG, eSI_reg +#define eDI OP_REG, eDI_reg +#define AL OP_REG, al_reg +#define CL OP_REG, cl_reg +#define DL OP_REG, dl_reg +#define BL OP_REG, bl_reg +#define AH OP_REG, ah_reg +#define CH OP_REG, ch_reg +#define DH OP_REG, dh_reg +#define BH OP_REG, bh_reg +#define AX OP_REG, ax_reg +#define DX OP_REG, dx_reg +#define indirDX OP_REG, indir_dx_reg + +#define Sw OP_SEG, w_mode +#define Ap OP_DIR, lptr +#define Av OP_DIR, v_mode +#define Ob OP_OFF, b_mode +#define Ov OP_OFF, v_mode +#define Xb OP_DSSI, b_mode +#define Xv OP_DSSI, v_mode +#define Yb OP_ESDI, b_mode +#define Yv OP_ESDI, v_mode + +#define es OP_REG, es_reg +#define ss OP_REG, ss_reg +#define cs OP_REG, cs_reg +#define ds OP_REG, ds_reg +#define fs OP_REG, fs_reg +#define gs OP_REG, gs_reg + +int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG(); +int OP_J(), OP_SEG(); +int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C(); +int OP_D(), OP_T(), OP_rm(); + + +#define b_mode 1 +#define v_mode 2 +#define w_mode 3 +#define d_mode 4 + +#define es_reg 100 +#define cs_reg 101 +#define ss_reg 102 +#define ds_reg 103 +#define fs_reg 104 +#define gs_reg 105 +#define eAX_reg 107 +#define eCX_reg 108 +#define eDX_reg 109 +#define eBX_reg 110 +#define eSP_reg 111 +#define eBP_reg 112 +#define eSI_reg 113 +#define eDI_reg 114 + +#define lptr 115 + +#define al_reg 116 +#define cl_reg 117 +#define dl_reg 118 +#define bl_reg 119 +#define ah_reg 120 +#define ch_reg 121 +#define dh_reg 122 +#define bh_reg 123 + +#define ax_reg 124 +#define cx_reg 125 +#define dx_reg 126 +#define bx_reg 127 +#define sp_reg 128 +#define bp_reg 129 +#define si_reg 130 +#define di_reg 131 + +#define indir_dx_reg 150 + +#define GRP1b NULL, NULL, 0 +#define GRP1S NULL, NULL, 1 +#define GRP1Ss NULL, NULL, 2 +#define GRP2b NULL, NULL, 3 +#define GRP2S NULL, NULL, 4 +#define GRP2b_one NULL, NULL, 5 +#define GRP2S_one NULL, NULL, 6 +#define GRP2b_cl NULL, NULL, 7 +#define GRP2S_cl NULL, NULL, 8 +#define GRP3b NULL, NULL, 9 +#define GRP3S NULL, NULL, 10 +#define GRP4 NULL, NULL, 11 +#define GRP5 NULL, NULL, 12 +#define GRP6 NULL, NULL, 13 +#define GRP7 NULL, NULL, 14 +#define GRP8 NULL, NULL, 15 + +#define FLOATCODE 50 +#define FLOAT NULL, NULL, FLOATCODE + +struct dis386 { + char *name; + int (*op1)(); + int bytemode1; + int (*op2)(); + int bytemode2; + int (*op3)(); + int bytemode3; +}; + +struct dis386 dis386[] = { + /* 00 */ + { "addb", Eb, Gb }, + { "addS", Ev, Gv }, + { "addb", Gb, Eb }, + { "addS", Gv, Ev }, + { "addb", AL, Ib }, + { "addS", eAX, Iv }, + { "pushl", es }, + { "popl", es }, + /* 08 */ + { "orb", Eb, Gb }, + { "orS", Ev, Gv }, + { "orb", Gb, Eb }, + { "orS", Gv, Ev }, + { "orb", AL, Ib }, + { "orS", eAX, Iv }, + { "pushl", cs }, + { "(bad)" }, /* 0x0f extended opcode escape */ + /* 10 */ + { "adcb", Eb, Gb }, + { "adcS", Ev, Gv }, + { "adcb", Gb, Eb }, + { "adcS", Gv, Ev }, + { "adcb", AL, Ib }, + { "adcS", eAX, Iv }, + { "pushl", ss }, + { "popl", ss }, + /* 18 */ + { "sbbb", Eb, Gb }, + { "sbbS", Ev, Gv }, + { "sbbb", Gb, Eb }, + { "sbbS", Gv, Ev }, + { "sbbb", AL, Ib }, + { "sbbS", eAX, Iv }, + { "pushl", ds }, + { "popl", ds }, + /* 20 */ + { "andb", Eb, Gb }, + { "andS", Ev, Gv }, + { "andb", Gb, Eb }, + { "andS", Gv, Ev }, + { "andb", AL, Ib }, + { "andS", eAX, Iv }, + { "(bad)" }, /* SEG ES prefix */ + { "daa" }, + /* 28 */ + { "subb", Eb, Gb }, + { "subS", Ev, Gv }, + { "subb", Gb, Eb }, + { "subS", Gv, Ev }, + { "subb", AL, Ib }, + { "subS", eAX, Iv }, + { "(bad)" }, /* SEG CS prefix */ + { "das" }, + /* 30 */ + { "xorb", Eb, Gb }, + { "xorS", Ev, Gv }, + { "xorb", Gb, Eb }, + { "xorS", Gv, Ev }, + { "xorb", AL, Ib }, + { "xorS", eAX, Iv }, + { "(bad)" }, /* SEG SS prefix */ + { "aaa" }, + /* 38 */ + { "cmpb", Eb, Gb }, + { "cmpS", Ev, Gv }, + { "cmpb", Gb, Eb }, + { "cmpS", Gv, Ev }, + { "cmpb", AL, Ib }, + { "cmpS", eAX, Iv }, + { "(bad)" }, /* SEG DS prefix */ + { "aas" }, + /* 40 */ + { "incS", eAX }, + { "incS", eCX }, + { "incS", eDX }, + { "incS", eBX }, + { "incS", eSP }, + { "incS", eBP }, + { "incS", eSI }, + { "incS", eDI }, + /* 48 */ + { "decS", eAX }, + { "decS", eCX }, + { "decS", eDX }, + { "decS", eBX }, + { "decS", eSP }, + { "decS", eBP }, + { "decS", eSI }, + { "decS", eDI }, + /* 50 */ + { "pushS", eAX }, + { "pushS", eCX }, + { "pushS", eDX }, + { "pushS", eBX }, + { "pushS", eSP }, + { "pushS", eBP }, + { "pushS", eSI }, + { "pushS", eDI }, + /* 58 */ + { "popS", eAX }, + { "popS", eCX }, + { "popS", eDX }, + { "popS", eBX }, + { "popS", eSP }, + { "popS", eBP }, + { "popS", eSI }, + { "popS", eDI }, + /* 60 */ + { "pusha" }, + { "popa" }, + { "boundS", Gv, Ma }, + { "arpl", Ew, Gw }, + { "(bad)" }, /* seg fs */ + { "(bad)" }, /* seg gs */ + { "(bad)" }, /* op size prefix */ + { "(bad)" }, /* adr size prefix */ + /* 68 */ + { "pushS", Iv }, /* 386 book wrong */ + { "imulS", Gv, Ev, Iv }, + { "pushl", sIb }, /* push of byte really pushes 4 bytes */ + { "imulS", Gv, Ev, Ib }, + { "insb", Yb, indirDX }, + { "insS", Yv, indirDX }, + { "outsb", indirDX, Xb }, + { "outsS", indirDX, Xv }, + /* 70 */ + { "jo", Jb }, + { "jno", Jb }, + { "jb", Jb }, + { "jae", Jb }, + { "je", Jb }, + { "jne", Jb }, + { "jbe", Jb }, + { "ja", Jb }, + /* 78 */ + { "js", Jb }, + { "jns", Jb }, + { "jp", Jb }, + { "jnp", Jb }, + { "jl", Jb }, + { "jnl", Jb }, + { "jle", Jb }, + { "jg", Jb }, + /* 80 */ + { GRP1b }, + { GRP1S }, + { "(bad)" }, + { GRP1Ss }, + { "testb", Eb, Gb }, + { "testS", Ev, Gv }, + { "xchgb", Eb, Gb }, + { "xchgS", Ev, Gv }, + /* 88 */ + { "movb", Eb, Gb }, + { "movS", Ev, Gv }, + { "movb", Gb, Eb }, + { "movS", Gv, Ev }, + { "movw", Ew, Sw }, + { "leaS", Gv, M }, + { "movw", Sw, Ew }, + { "popS", Ev }, + /* 90 */ + { "nop" }, + { "xchgS", eCX, eAX }, + { "xchgS", eDX, eAX }, + { "xchgS", eBX, eAX }, + { "xchgS", eSP, eAX }, + { "xchgS", eBP, eAX }, + { "xchgS", eSI, eAX }, + { "xchgS", eDI, eAX }, + /* 98 */ + { "cwtl" }, + { "cltd" }, + { "lcall", Ap }, + { "(bad)" }, /* fwait */ + { "pushf" }, + { "popf" }, + { "sahf" }, + { "lahf" }, + /* a0 */ + { "movb", AL, Ob }, + { "movS", eAX, Ov }, + { "movb", Ob, AL }, + { "movS", Ov, eAX }, + { "movsb", Yb, Xb }, + { "movsS", Yv, Xv }, + { "cmpsb", Yb, Xb }, + { "cmpsS", Yv, Xv }, + /* a8 */ + { "testb", AL, Ib }, + { "testS", eAX, Iv }, + { "stosb", Yb, AL }, + { "stosS", Yv, eAX }, + { "lodsb", AL, Xb }, + { "lodsS", eAX, Xv }, + { "scasb", AL, Xb }, + { "scasS", eAX, Xv }, + /* b0 */ + { "movb", AL, Ib }, + { "movb", CL, Ib }, + { "movb", DL, Ib }, + { "movb", BL, Ib }, + { "movb", AH, Ib }, + { "movb", CH, Ib }, + { "movb", DH, Ib }, + { "movb", BH, Ib }, + /* b8 */ + { "movS", eAX, Iv }, + { "movS", eCX, Iv }, + { "movS", eDX, Iv }, + { "movS", eBX, Iv }, + { "movS", eSP, Iv }, + { "movS", eBP, Iv }, + { "movS", eSI, Iv }, + { "movS", eDI, Iv }, + /* c0 */ + { GRP2b }, + { GRP2S }, + { "ret", Iw }, + { "ret" }, + { "lesS", Gv, Mp }, + { "ldsS", Gv, Mp }, + { "movb", Eb, Ib }, + { "movS", Ev, Iv }, + /* c8 */ + { "enter", Iw, Ib }, + { "leave" }, + { "lret", Iw }, + { "lret" }, + { "int3" }, + { "int", Ib }, + { "into" }, + { "iret" }, + /* d0 */ + { GRP2b_one }, + { GRP2S_one }, + { GRP2b_cl }, + { GRP2S_cl }, + { "aam", Ib }, + { "aad", Ib }, + { "(bad)" }, + { "xlat" }, + /* d8 */ + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + /* e0 */ + { "loopne", Jb }, + { "loope", Jb }, + { "loop", Jb }, + { "jCcxz", Jb }, + { "inb", AL, Ib }, + { "inS", eAX, Ib }, + { "outb", Ib, AL }, + { "outS", Ib, eAX }, + /* e8 */ + { "call", Av }, + { "jmp", Jv }, + { "ljmp", Ap }, + { "jmp", Jb }, + { "inb", AL, indirDX }, + { "inS", eAX, indirDX }, + { "outb", indirDX, AL }, + { "outS", indirDX, eAX }, + /* f0 */ + { "(bad)" }, /* lock prefix */ + { "(bad)" }, + { "(bad)" }, /* repne */ + { "(bad)" }, /* repz */ + { "hlt" }, + { "cmc" }, + { GRP3b }, + { GRP3S }, + /* f8 */ + { "clc" }, + { "stc" }, + { "cli" }, + { "sti" }, + { "cld" }, + { "std" }, + { GRP4 }, + { GRP5 }, +}; + +struct dis386 dis386_twobyte[] = { + /* 00 */ + { GRP6 }, + { GRP7 }, + { "larS", Gv, Ew }, + { "lslS", Gv, Ew }, + { "(bad)" }, + { "(bad)" }, + { "clts" }, + { "(bad)" }, + /* 08 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 10 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 18 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 20 */ + /* these are all backward in appendix A of the intel book */ + { "movl", Rd, Cd }, + { "movl", Rd, Dd }, + { "movl", Cd, Rd }, + { "movl", Dd, Rd }, + { "movl", Rd, Td }, + { "(bad)" }, + { "movl", Td, Rd }, + { "(bad)" }, + /* 28 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 30 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 38 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 40 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 48 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 50 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 58 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 60 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 68 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 70 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 78 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* 80 */ + { "jo", Jv }, + { "jno", Jv }, + { "jb", Jv }, + { "jae", Jv }, + { "je", Jv }, + { "jne", Jv }, + { "jbe", Jv }, + { "ja", Jv }, + /* 88 */ + { "js", Jv }, + { "jns", Jv }, + { "jp", Jv }, + { "jnp", Jv }, + { "jl", Jv }, + { "jge", Jv }, + { "jle", Jv }, + { "jg", Jv }, + /* 90 */ + { "seto", Eb }, + { "setno", Eb }, + { "setb", Eb }, + { "setae", Eb }, + { "sete", Eb }, + { "setne", Eb }, + { "setbe", Eb }, + { "seta", Eb }, + /* 98 */ + { "sets", Eb }, + { "setns", Eb }, + { "setp", Eb }, + { "setnp", Eb }, + { "setl", Eb }, + { "setge", Eb }, + { "setle", Eb }, + { "setg", Eb }, + /* a0 */ + { "pushl", fs }, + { "popl", fs }, + { "(bad)" }, + { "btS", Ev, Gv }, + { "shldS", Ev, Gv, Ib }, + { "shldS", Ev, Gv, CL }, + { "(bad)" }, + { "(bad)" }, + /* a8 */ + { "pushl", gs }, + { "popl", gs }, + { "(bad)" }, + { "btsS", Ev, Gv }, + { "shrdS", Ev, Gv, Ib }, + { "shrdS", Ev, Gv, CL }, + { "(bad)" }, + { "imulS", Gv, Ev }, + /* b0 */ + { "(bad)" }, + { "(bad)" }, + { "lssS", Gv, Mp }, /* 386 lists only Mp */ + { "btrS", Ev, Gv }, + { "lfsS", Gv, Mp }, /* 386 lists only Mp */ + { "lgsS", Gv, Mp }, /* 386 lists only Mp */ + { "movzbS", Gv, Eb }, + { "movzwS", Gv, Ew }, + /* b8 */ + { "(bad)" }, + { "(bad)" }, + { GRP8 }, + { "btcS", Ev, Gv }, + { "bsfS", Gv, Ev }, + { "bsrS", Gv, Ev }, + { "movsbS", Gv, Eb }, + { "movswS", Gv, Ew }, + /* c0 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* c8 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* d0 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* d8 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* e0 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* e8 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* f0 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + /* f8 */ + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, +}; + +static char obuf[100]; +static char *obufp; +static char scratchbuf[100]; +static unsigned char *start_codep; +static unsigned char *codep; +static int mod; +static int rm; +static int reg; + +static char *names32[]={ + "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi", +}; +static char *names16[] = { + "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di", +}; +static char *names8[] = { + "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh", +}; +static char *names_seg[] = { + "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", +}; + +struct dis386 grps[][8] = { + /* GRP1b */ + { + { "addb", Eb, Ib }, + { "orb", Eb, Ib }, + { "adcb", Eb, Ib }, + { "sbbb", Eb, Ib }, + { "andb", Eb, Ib }, + { "subb", Eb, Ib }, + { "xorb", Eb, Ib }, + { "cmpb", Eb, Ib } + }, + /* GRP1S */ + { + { "addS", Ev, Iv }, + { "orS", Ev, Iv }, + { "adcS", Ev, Iv }, + { "sbbS", Ev, Iv }, + { "andS", Ev, Iv }, + { "subS", Ev, Iv }, + { "xorS", Ev, Iv }, + { "cmpS", Ev, Iv } + }, + /* GRP1Ss */ + { + { "addS", Ev, sIb }, + { "orS", Ev, sIb }, + { "adcS", Ev, sIb }, + { "sbbS", Ev, sIb }, + { "andS", Ev, sIb }, + { "subS", Ev, sIb }, + { "xorS", Ev, sIb }, + { "cmpS", Ev, sIb } + }, + /* GRP2b */ + { + { "rolb", Eb, Ib }, + { "rorb", Eb, Ib }, + { "rclb", Eb, Ib }, + { "rcrb", Eb, Ib }, + { "shlb", Eb, Ib }, + { "shrb", Eb, Ib }, + { "(bad)" }, + { "sarb", Eb, Ib }, + }, + /* GRP2S */ + { + { "rolS", Ev, Ib }, + { "rorS", Ev, Ib }, + { "rclS", Ev, Ib }, + { "rcrS", Ev, Ib }, + { "shlS", Ev, Ib }, + { "shrS", Ev, Ib }, + { "(bad)" }, + { "sarS", Ev, Ib }, + }, + /* GRP2b_one */ + { + { "rolb", Eb }, + { "rorb", Eb }, + { "rclb", Eb }, + { "rcrb", Eb }, + { "shlb", Eb }, + { "shrb", Eb }, + { "(bad)" }, + { "sarb", Eb }, + }, + /* GRP2S_one */ + { + { "rolS", Ev }, + { "rorS", Ev }, + { "rclS", Ev }, + { "rcrS", Ev }, + { "shlS", Ev }, + { "shrS", Ev }, + { "(bad)" }, + { "sarS", Ev }, + }, + /* GRP2b_cl */ + { + { "rolb", Eb, CL }, + { "rorb", Eb, CL }, + { "rclb", Eb, CL }, + { "rcrb", Eb, CL }, + { "shlb", Eb, CL }, + { "shrb", Eb, CL }, + { "(bad)" }, + { "sarb", Eb, CL }, + }, + /* GRP2S_cl */ + { + { "rolS", Ev, CL }, + { "rorS", Ev, CL }, + { "rclS", Ev, CL }, + { "rcrS", Ev, CL }, + { "shlS", Ev, CL }, + { "shrS", Ev, CL }, + { "(bad)" }, + { "sarS", Ev, CL } + }, + /* GRP3b */ + { + { "testb", Eb, Ib }, + { "(bad)", Eb }, + { "notb", Eb }, + { "negb", Eb }, + { "mulb", AL, Eb }, + { "imulb", AL, Eb }, + { "divb", AL, Eb }, + { "idivb", AL, Eb } + }, + /* GRP3S */ + { + { "testS", Ev, Iv }, + { "(bad)" }, + { "notS", Ev }, + { "negS", Ev }, + { "mulS", eAX, Ev }, + { "imulS", eAX, Ev }, + { "divS", eAX, Ev }, + { "idivS", eAX, Ev }, + }, + /* GRP4 */ + { + { "incb", Eb }, + { "decb", Eb }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + }, + /* GRP5 */ + { + { "incS", Ev }, + { "decS", Ev }, + { "call", indirEv }, + { "lcall", indirEv }, + { "jmp", indirEv }, + { "ljmp", indirEv }, + { "pushS", Ev }, + { "(bad)" }, + }, + /* GRP6 */ + { + { "sldt", Ew }, + { "str", Ew }, + { "lldt", Ew }, + { "ltr", Ew }, + { "verr", Ew }, + { "verw", Ew }, + { "(bad)" }, + { "(bad)" } + }, + /* GRP7 */ + { + { "sgdt", Ew }, + { "sidt", Ew }, + { "lgdt", Ew }, + { "lidt", Ew }, + { "smsw", Ew }, + { "(bad)" }, + { "lmsw", Ew }, + { "(bad)" }, + }, + /* GRP8 */ + { + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "btS", Ev, Ib }, + { "btsS", Ev, Ib }, + { "btrS", Ev, Ib }, + { "btcS", Ev, Ib }, + } +}; + +#define PREFIX_REPZ 1 +#define PREFIX_REPNZ 2 +#define PREFIX_LOCK 4 +#define PREFIX_CS 8 +#define PREFIX_SS 0x10 +#define PREFIX_DS 0x20 +#define PREFIX_ES 0x40 +#define PREFIX_FS 0x80 +#define PREFIX_GS 0x100 +#define PREFIX_DATA 0x200 +#define PREFIX_ADR 0x400 +#define PREFIX_FWAIT 0x800 + +static int prefixes; + +ckprefix () +{ + prefixes = 0; + while (1) + { + switch (*codep) + { + case 0xf3: + prefixes |= PREFIX_REPZ; + break; + case 0xf2: + prefixes |= PREFIX_REPNZ; + break; + case 0xf0: + prefixes |= PREFIX_LOCK; + break; + case 0x2e: + prefixes |= PREFIX_CS; + break; + case 0x36: + prefixes |= PREFIX_SS; + break; + case 0x3e: + prefixes |= PREFIX_DS; + break; + case 0x26: + prefixes |= PREFIX_ES; + break; + case 0x64: + prefixes |= PREFIX_FS; + break; + case 0x65: + prefixes |= PREFIX_GS; + break; + case 0x66: + prefixes |= PREFIX_DATA; + break; + case 0x67: + prefixes |= PREFIX_ADR; + break; + case 0x9b: + prefixes |= PREFIX_FWAIT; + break; + default: + return; + } + codep++; + } +} + +static int dflag; +static int aflag; + +static char op1out[100], op2out[100], op3out[100]; +static int start_pc; + +/* + * disassemble the first instruction in 'inbuf'. You have to make + * sure all of the bytes of the instruction are filled in. + * On the 386's of 1988, the maximum length of an instruction is 15 bytes. + * (see topic "Redundant prefixes" in the "Differences from 8086" + * section of the "Virtual 8086 Mode" chapter.) + * 'pc' should be the address of this instruction, it will + * be used to print the target address if this is a relative jump or call + * 'outbuf' gets filled in with the disassembled instruction. it should + * be long enough to hold the longest disassembled instruction. + * 100 bytes is certainly enough, unless symbol printing is added later + * The function returns the length of this instruction in bytes. + */ +i386dis (pc, inbuf, outbuf) + int pc; + unsigned char *inbuf; + char *outbuf; +{ + struct dis386 *dp; + char *p; + int i; + int enter_instruction; + char *first, *second, *third; + int needcomma; + + obuf[0] = 0; + op1out[0] = 0; + op2out[0] = 0; + op3out[0] = 0; + + start_pc = pc; + start_codep = inbuf; + codep = inbuf; + + ckprefix (); + + if (*codep == 0xc8) + enter_instruction = 1; + else + enter_instruction = 0; + + obufp = obuf; + + if (prefixes & PREFIX_REPZ) + oappend ("repz "); + if (prefixes & PREFIX_REPNZ) + oappend ("repnz "); + if (prefixes & PREFIX_LOCK) + oappend ("lock "); + + if ((prefixes & PREFIX_FWAIT) + && ((*codep < 0xd8) || (*codep > 0xdf))) + { + /* fwait not followed by floating point instruction */ + oappend ("fwait"); + strcpy (outbuf, obuf); + return (1); + } + + /* these would be initialized to 0 if disassembling for 8086 or 286 */ + dflag = 1; + aflag = 1; + + if (prefixes & PREFIX_DATA) + dflag ^= 1; + + if (prefixes & PREFIX_ADR) + { + aflag ^= 1; + oappend ("addr16 "); + } + + if (*codep == 0x0f) + dp = &dis386_twobyte[*++codep]; + else + dp = &dis386[*codep]; + codep++; + mod = (*codep >> 6) & 3; + reg = (*codep >> 3) & 7; + rm = *codep & 7; + + if (dp->name == NULL && dp->bytemode1 == FLOATCODE) + { + dofloat (); + } + else + { + if (dp->name == NULL) + dp = &grps[dp->bytemode1][reg]; + + putop (dp->name); + + obufp = op1out; + if (dp->op1) + (*dp->op1)(dp->bytemode1); + + obufp = op2out; + if (dp->op2) + (*dp->op2)(dp->bytemode2); + + obufp = op3out; + if (dp->op3) + (*dp->op3)(dp->bytemode3); + } + + obufp = obuf + strlen (obuf); + for (i = strlen (obuf); i < 6; i++) + oappend (" "); + oappend (" "); + + /* enter instruction is printed with operands in the + * same order as the intel book; everything else + * is printed in reverse order + */ + if (enter_instruction) + { + first = op1out; + second = op2out; + third = op3out; + } + else + { + first = op3out; + second = op2out; + third = op1out; + } + needcomma = 0; + if (*first) + { + oappend (first); + needcomma = 1; + } + if (*second) + { + if (needcomma) + oappend (","); + oappend (second); + needcomma = 1; + } + if (*third) + { + if (needcomma) + oappend (","); + oappend (third); + } + strcpy (outbuf, obuf); + return (codep - inbuf); +} + +char *float_mem[] = { + /* d8 */ + "fadds", + "fmuls", + "fcoms", + "fcomps", + "fsubs", + "fsubrs", + "fdivs", + "fdivrs", + /* d9 */ + "flds", + "(bad)", + "fsts", + "fstps", + "fldenv", + "fldcw", + "fNstenv", + "fNstcw", + /* da */ + "fiaddl", + "fimull", + "ficoml", + "ficompl", + "fisubl", + "fisubrl", + "fidivl", + "fidivrl", + /* db */ + "fildl", + "(bad)", + "fistl", + "fistpl", + "(bad)", + "fldt", + "(bad)", + "fstpt", + /* dc */ + "faddl", + "fmull", + "fcoml", + "fcompl", + "fsubl", + "fsubrl", + "fdivl", + "fdivrl", + /* dd */ + "fldl", + "(bad)", + "fstl", + "fstpl", + "frstor", + "(bad)", + "fNsave", + "fNstsw", + /* de */ + "fiadd", + "fimul", + "ficom", + "ficomp", + "fisub", + "fisubr", + "fidiv", + "fidivr", + /* df */ + "fild", + "(bad)", + "fist", + "fistp", + "fbld", + "fildll", + "fbstp", + "fistpll", +}; + +#define ST OP_ST, 0 +#define STi OP_STi, 0 +int OP_ST(), OP_STi(); + +#define FGRPd9_2 NULL, NULL, 0 +#define FGRPd9_4 NULL, NULL, 1 +#define FGRPd9_5 NULL, NULL, 2 +#define FGRPd9_6 NULL, NULL, 3 +#define FGRPd9_7 NULL, NULL, 4 +#define FGRPda_5 NULL, NULL, 5 +#define FGRPdb_4 NULL, NULL, 6 +#define FGRPde_3 NULL, NULL, 7 +#define FGRPdf_4 NULL, NULL, 8 + +struct dis386 float_reg[][8] = { + /* d8 */ + { + { "fadd", ST, STi }, + { "fmul", ST, STi }, + { "fcom", STi }, + { "fcomp", STi }, + { "fsub", ST, STi }, + { "fsubr", ST, STi }, + { "fdiv", ST, STi }, + { "fdivr", ST, STi }, + }, + /* d9 */ + { + { "fld", STi }, + { "fxch", STi }, + { FGRPd9_2 }, + { "(bad)" }, + { FGRPd9_4 }, + { FGRPd9_5 }, + { FGRPd9_6 }, + { FGRPd9_7 }, + }, + /* da */ + { + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { FGRPda_5 }, + { "(bad)" }, + { "(bad)" }, + }, + /* db */ + { + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { FGRPdb_4 }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + }, + /* dc */ + { + { "fadd", STi, ST }, + { "fmul", STi, ST }, + { "(bad)" }, + { "(bad)" }, + { "fsub", STi, ST }, + { "fsubr", STi, ST }, + { "fdiv", STi, ST }, + { "fdivr", STi, ST }, + }, + /* dd */ + { + { "ffree", STi }, + { "(bad)" }, + { "fst", STi }, + { "fstp", STi }, + { "fucom", STi }, + { "fucomp", STi }, + { "(bad)" }, + { "(bad)" }, + }, + /* de */ + { + { "faddp", STi, ST }, + { "fmulp", STi, ST }, + { "(bad)" }, + { FGRPde_3 }, + { "fsubp", STi, ST }, + { "fsubrp", STi, ST }, + { "fdivp", STi, ST }, + { "fdivrp", STi, ST }, + }, + /* df */ + { + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { FGRPdf_4 }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + }, +}; + + +char *fgrps[][8] = { + /* d9_2 0 */ + { + "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", + }, + + /* d9_4 1 */ + { + "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", + }, + + /* d9_5 2 */ + { + "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", + }, + + /* d9_6 3 */ + { + "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", + }, + + /* d9_7 4 */ + { + "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos", + }, + + /* da_5 5 */ + { + "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", + }, + + /* db_4 6 */ + { + "feni(287 only)","fdisi(287 only)","fNclex","fNinit", + "fNsetpm(287 only)","(bad)","(bad)","(bad)", + }, + + /* de_3 7 */ + { + "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", + }, + + /* df_4 8 */ + { + "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", + }, +}; + + +dofloat () +{ + struct dis386 *dp; + unsigned char floatop; + + floatop = codep[-1]; + + if (mod != 3) + { + putop (float_mem[(floatop - 0xd8) * 8 + reg]); + obufp = op1out; + OP_E (v_mode); + return; + } + codep++; + + dp = &float_reg[floatop - 0xd8][reg]; + if (dp->name == NULL) + { + putop (fgrps[dp->bytemode1][rm]); + /* instruction fnstsw is only one with strange arg */ + if (floatop == 0xdf && *codep == 0xe0) + strcpy (op1out, "%eax"); + } + else + { + putop (dp->name); + obufp = op1out; + if (dp->op1) + (*dp->op1)(dp->bytemode1); + obufp = op2out; + if (dp->op2) + (*dp->op2)(dp->bytemode2); + } +} + +/* ARGSUSED */ +OP_ST (ignore) +{ + oappend ("%st"); +} + +/* ARGSUSED */ +OP_STi (ignore) +{ + sprintf (scratchbuf, "%%st(%d)", rm); + oappend (scratchbuf); +} + + +/* capital letters in template are macros */ +putop (template) + char *template; +{ + char *p; + + for (p = template; *p; p++) + { + switch (*p) + { + default: + *obufp++ = *p; + break; + case 'C': /* For jcxz/jecxz */ + if (aflag == 0) + *obufp++ = 'e'; + break; + case 'N': + if ((prefixes & PREFIX_FWAIT) == 0) + *obufp++ = 'n'; + break; + case 'S': + /* operand size flag */ + if (dflag) + *obufp++ = 'l'; + else + *obufp++ = 'w'; + break; + } + } + *obufp = 0; +} + +oappend (s) +char *s; +{ + strcpy (obufp, s); + obufp += strlen (s); + *obufp = 0; +} + +append_prefix () +{ + if (prefixes & PREFIX_CS) + oappend ("%cs:"); + if (prefixes & PREFIX_DS) + oappend ("%ds:"); + if (prefixes & PREFIX_SS) + oappend ("%ss:"); + if (prefixes & PREFIX_ES) + oappend ("%es:"); + if (prefixes & PREFIX_FS) + oappend ("%fs:"); + if (prefixes & PREFIX_GS) + oappend ("%gs:"); +} + +OP_indirE (bytemode) +{ + oappend ("*"); + OP_E (bytemode); +} + +OP_E (bytemode) +{ + int disp; + int havesib; + int didoutput = 0; + int base; + int index; + int scale; + int havebase; + + /* skip mod/rm byte */ + codep++; + + havesib = 0; + havebase = 0; + disp = 0; + + if (mod == 3) + { + switch (bytemode) + { + case b_mode: + oappend (names8[rm]); + break; + case w_mode: + oappend (names16[rm]); + break; + case v_mode: + if (dflag) + oappend (names32[rm]); + else + oappend (names16[rm]); + break; + default: + oappend ("<bad dis table>"); + break; + } + return; + } + + append_prefix (); + if (rm == 4) + { + havesib = 1; + havebase = 1; + scale = (*codep >> 6) & 3; + index = (*codep >> 3) & 7; + base = *codep & 7; + codep++; + } + + switch (mod) + { + case 0: + switch (rm) + { + case 4: + /* implies havesib and havebase */ + if (base == 5) { + havebase = 0; + disp = get32 (); + } + break; + case 5: + disp = get32 (); + break; + default: + havebase = 1; + base = rm; + break; + } + break; + case 1: + disp = *(char *)codep++; + if (rm != 4) + { + havebase = 1; + base = rm; + } + break; + case 2: + disp = get32 (); + if (rm != 4) + { + havebase = 1; + base = rm; + } + break; + } + + if (mod != 0 || rm == 5 || (havesib && base == 5)) + { + sprintf (scratchbuf, "%d", disp); + oappend (scratchbuf); + } + + if (havebase || havesib) + { + oappend ("("); + if (havebase) + oappend (names32[base]); + if (havesib) + { + if (index != 4) + { + sprintf (scratchbuf, ",%s", names32[index]); + oappend (scratchbuf); + } + sprintf (scratchbuf, ",%d", 1 << scale); + oappend (scratchbuf); + } + oappend (")"); + } +} + +OP_G (bytemode) +{ + switch (bytemode) + { + case b_mode: + oappend (names8[reg]); + break; + case w_mode: + oappend (names16[reg]); + break; + case d_mode: + oappend (names32[reg]); + break; + case v_mode: + if (dflag) + oappend (names32[reg]); + else + oappend (names16[reg]); + break; + default: + oappend ("<internal disassembler error>"); + break; + } +} + +get32 () +{ + int x = 0; + + x = *codep++ & 0xff; + x |= (*codep++ & 0xff) << 8; + x |= (*codep++ & 0xff) << 16; + x |= (*codep++ & 0xff) << 24; + return (x); +} + +get16 () +{ + int x = 0; + + x = *codep++ & 0xff; + x |= (*codep++ & 0xff) << 8; + return (x); +} + +OP_REG (code) +{ + char *s; + + switch (code) + { + case indir_dx_reg: s = "(%dx)"; break; + case ax_reg: case cx_reg: case dx_reg: case bx_reg: + case sp_reg: case bp_reg: case si_reg: case di_reg: + s = names16[code - ax_reg]; + break; + case es_reg: case ss_reg: case cs_reg: + case ds_reg: case fs_reg: case gs_reg: + s = names_seg[code - es_reg]; + break; + case al_reg: case ah_reg: case cl_reg: case ch_reg: + case dl_reg: case dh_reg: case bl_reg: case bh_reg: + s = names8[code - al_reg]; + break; + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: + if (dflag) + s = names32[code - eAX_reg]; + else + s = names16[code - eAX_reg]; + break; + default: + s = "<internal disassembler error>"; + break; + } + oappend (s); +} + +OP_I (bytemode) +{ + int op; + + switch (bytemode) + { + case b_mode: + op = *codep++ & 0xff; + break; + case v_mode: + if (dflag) + op = get32 (); + else + op = get16 (); + break; + case w_mode: + op = get16 (); + break; + default: + oappend ("<internal disassembler error>"); + return; + } + sprintf (scratchbuf, "$0x%x", op); + oappend (scratchbuf); +} + +OP_sI (bytemode) +{ + int op; + + switch (bytemode) + { + case b_mode: + op = *(char *)codep++; + break; + case v_mode: + if (dflag) + op = get32 (); + else + op = (short)get16(); + break; + case w_mode: + op = (short)get16 (); + break; + default: + oappend ("<internal disassembler error>"); + return; + } + sprintf (scratchbuf, "$0x%x", op); + oappend (scratchbuf); +} + +OP_J (bytemode) +{ + int disp; + int mask = -1; + + switch (bytemode) + { + case b_mode: + disp = *(char *)codep++; + break; + case v_mode: + if (dflag) + disp = get32 (); + else + { + disp = (short)get16 (); + /* for some reason, a data16 prefix on a jump instruction + means that the pc is masked to 16 bits after the + displacement is added! */ + mask = 0xffff; + } + break; + default: + oappend ("<internal disassembelr error>"); + return; + } + + sprintf (scratchbuf, "0x%x", + (start_pc + codep - start_codep + disp) & mask); + oappend (scratchbuf); +} + +/* ARGSUSED */ +OP_SEG (dummy) +{ + static char *sreg[] = { + "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", + }; + + oappend (sreg[reg]); +} + +OP_DIR (size) +{ + int seg, offset; + + switch (size) + { + case lptr: + if (aflag) + { + offset = get32 (); + seg = get16 (); + } + else + { + offset = get16 (); + seg = get16 (); + } + sprintf (scratchbuf, "0x%x,0x%x", seg, offset); + oappend (scratchbuf); + break; + case v_mode: + if (aflag) + offset = get32 (); + else + offset = (short)get16 (); + + sprintf (scratchbuf, "0x%x", + start_pc + codep - start_codep + offset); + oappend (scratchbuf); + break; + default: + oappend ("<internal disassembler error>"); + break; + } +} + +/* ARGSUSED */ +OP_OFF (bytemode) +{ + int off; + + if (aflag) + off = get32 (); + else + off = get16 (); + + sprintf (scratchbuf, "0x%x", off); + oappend (scratchbuf); +} + +/* ARGSUSED */ +OP_ESDI (dummy) +{ + oappend ("%es:("); + oappend (aflag ? "%edi" : "%di"); + oappend (")"); +} + +/* ARGSUSED */ +OP_DSSI (dummy) +{ + oappend ("%ds:("); + oappend (aflag ? "%esi" : "%si"); + oappend (")"); +} + +/* ARGSUSED */ +OP_ONE (dummy) +{ + oappend ("1"); +} + +/* ARGSUSED */ +OP_C (dummy) +{ + codep++; /* skip mod/rm */ + sprintf (scratchbuf, "%%cr%d", reg); + oappend (scratchbuf); +} + +/* ARGSUSED */ +OP_D (dummy) +{ + codep++; /* skip mod/rm */ + sprintf (scratchbuf, "%%db%d", reg); + oappend (scratchbuf); +} + +/* ARGSUSED */ +OP_T (dummy) +{ + codep++; /* skip mod/rm */ + sprintf (scratchbuf, "%%tr%d", reg); + oappend (scratchbuf); +} + +OP_rm (bytemode) +{ + switch (bytemode) + { + case d_mode: + oappend (names32[rm]); + break; + case w_mode: + oappend (names16[rm]); + break; + } +} + +/* GDB interface */ +#include "defs.h" +#include "param.h" +#include "symtab.h" +#include "frame.h" +#include "inferior.h" + +#define MAXLEN 20 +print_insn (memaddr, stream) + CORE_ADDR memaddr; + FILE *stream; +{ + unsigned char buffer[MAXLEN]; + /* should be expanded if disassembler prints symbol names */ + char outbuf[100]; + int n; + + read_memory (memaddr, buffer, MAXLEN); + + n = i386dis ((int)memaddr, buffer, outbuf); + + fputs (outbuf, stream); + + return (n); +} + diff --git a/gnu/usr.bin/gdb/config/i386bsd-dep.c b/gnu/usr.bin/gdb/config/i386bsd-dep.c new file mode 100644 index 000000000000..80e11fa137c1 --- /dev/null +++ b/gnu/usr.bin/gdb/config/i386bsd-dep.c @@ -0,0 +1,1886 @@ +/*- + * This code is derived from software copyrighted by the Free Software + * Foundation. + * + * Modified 1991 by Donn Seeley at UUNET Technologies, Inc. + * Modified 1990 by Van Jacobson at Lawrence Berkeley Laboratory. + */ + +#ifndef lint +static char sccsid[] = "@(#)i386bsd-dep.c 6.10 (Berkeley) 6/26/91"; +#endif /* not lint */ + +/* Low level interface to ptrace, for GDB when running on the Intel 386. + Copyright (C) 1988, 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <stdio.h> +#include "defs.h" +#include "param.h" +#include "frame.h" +#include "inferior.h" +#include "value.h" + +#include <sys/param.h> +#include <sys/dir.h> +#include <signal.h> +#include <sys/ioctl.h> +#include <fcntl.h> + +#include <a.out.h> + +#ifndef N_SET_MAGIC +#define N_SET_MAGIC(exec, val) ((exec).a_magic = (val)) +#endif + +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/uio.h> +#define curpcb Xcurpcb /* XXX avoid leaking declaration from pcb.h */ +#include <sys/user.h> +#undef curpcb +#include <sys/file.h> +#include <sys/stat.h> +#include <sys/ptrace.h> + +#include <machine/reg.h> + +#ifdef KERNELDEBUG +#ifndef NEWVM +#include <sys/vmmac.h> +#include <machine/pte.h> +#else +#include <sys/proc.h> /* for curproc */ +#endif +#include <machine/vmparam.h> +#include <machine/cpu.h> +#include <ctype.h> +#include "symtab.h" /* XXX */ + +#undef vtophys /* XXX */ + +extern int kernel_debugging; + +#define KERNOFF ((unsigned)KERNBASE) +#ifndef NEWVM +#define INKERNEL(x) ((x) >= KERNOFF && (x) < KERNOFF + ctob(slr)) +#define INUPAGE(x) \ + ((x) >= KERNEL_U_ADDR && (x) < KERNEL_U_ADDR + NBPG) +#else +#define INKERNEL(x) ((x) >= KERNOFF) +#endif + +#define PT_ADDR_ANY ((caddr_t) 1) + +/* + * Convert from sysmap pte index to system virtual address & vice-versa. + * (why aren't these in one of the system vm macro files???) + */ +#define smxtob(a) (sbr + (a) * sizeof(pte)) +#define btosmx(b) (((b) - sbr) / sizeof(pte)) + +static int ok_to_cache(); +static int found_pcb; +#ifdef NEWVM +static CORE_ADDR curpcb; +static CORE_ADDR kstack; +#endif + +static void setregmap(); + +extern int errno; + +/* + * This function simply calls ptrace with the given arguments. It exists so + * that all calls to ptrace are isolated in this machine-dependent file. + */ +int +call_ptrace(request, pid, arg3, arg4) + int request; + pid_t pid; + caddr_t arg3; + int arg4; +{ + return(ptrace(request, pid, arg3, arg4)); +} + +kill_inferior() +{ + if (remote_debugging) { +#ifdef KERNELDEBUG + if (kernel_debugging) + /* + * It's a very, very bad idea to go away leaving + * breakpoints in a remote kernel or to leave it + * stopped at a breakpoint. + */ + clear_breakpoints(); +#endif + remote_close(0); + inferior_died(); + } else if (inferior_pid != 0) { + ptrace(PT_KILL, inferior_pid, 0, 0); + wait(0); + inferior_died(); + } +} + +/* + * This is used when GDB is exiting. It gives less chance of error. + */ +kill_inferior_fast() +{ + if (remote_debugging) { +#ifdef KERNELDEBUG + if (kernel_debugging) + clear_breakpoints(); +#endif + remote_close(0); + return; + } + if (inferior_pid == 0) + return; + + ptrace(PT_KILL, inferior_pid, 0, 0); + wait(0); +} + +/* + * Resume execution of the inferior process. If STEP is nonzero, single-step + * it. If SIGNAL is nonzero, give it that signal. + */ +void +resume(step, signal) + int step; + int signal; +{ + errno = 0; + if (remote_debugging) + remote_resume(step, signal); + else { + ptrace(step ? PT_STEP : PT_CONTINUE, inferior_pid, + PT_ADDR_ANY, signal); + if (errno) + perror_with_name("ptrace"); + } +} + +#ifdef ATTACH_DETACH +extern int attach_flag; + +/* + * Start debugging the process whose number is PID. + */ +attach(pid) + int pid; +{ + errno = 0; + ptrace(PT_ATTACH, pid, 0, 0); + if (errno) + perror_with_name("ptrace"); + attach_flag = 1; + return pid; +} + +/* + * Stop debugging the process whose number is PID and continue it + * with signal number SIGNAL. SIGNAL = 0 means just continue it. + */ +void +detach(signal) + int signal; +{ + errno = 0; + ptrace(PT_DETACH, inferior_pid, PT_ADDR_ANY, signal); + if (errno) + perror_with_name("ptrace"); + attach_flag = 0; +} +#endif /* ATTACH_DETACH */ + +static unsigned int +get_register_offset() +{ + unsigned int offset; + struct user u; /* XXX */ + unsigned int flags = (char *) &u.u_pcb.pcb_flags - (char *) &u; + + setregmap(ptrace(PT_READ_U, inferior_pid, (caddr_t)flags, 0)); + +#ifdef NEWVM + offset = (char *) &u.u_kproc.kp_proc.p_regs - (char *) &u; + offset = ptrace(PT_READ_U, inferior_pid, (caddr_t)offset, 0) - + USRSTACK; +#else + offset = (char *) &u.u_ar0 - (char *) &u; + offset = ptrace(PT_READ_U, inferior_pid, (caddr_t)offset, 0) - + KERNEL_U_ADDR; +#endif + + return offset; +} + +void +fetch_inferior_registers() +{ + register int regno; + register unsigned int regaddr; + char buf[MAX_REGISTER_RAW_SIZE]; + register int i; + unsigned int offset; + + if (remote_debugging) { + extern char registers[]; + + remote_fetch_registers(registers); + return; + } + + offset = get_register_offset(); + + for (regno = 0; regno < NUM_REGS; regno++) { + regaddr = register_addr(regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE(regno); i += sizeof(int)) { + *(int *)&buf[i] = ptrace(PT_READ_U, inferior_pid, + (caddr_t)regaddr, 0); + regaddr += sizeof(int); + } + supply_register(regno, buf); + } +} + +/* + * 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) + int regno; +{ + register unsigned int regaddr; + char buf[80]; + extern char registers[]; + register int i; + unsigned int offset; + + if (remote_debugging) { + extern char registers[]; + + remote_store_registers(registers); + return; + } + + offset = get_register_offset(); + + if (regno >= 0) { + regaddr = register_addr(regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE(regno); i += sizeof(int)) { + errno = 0; + ptrace(PT_WRITE_U, inferior_pid, (caddr_t)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); + for (i = 0; i < REGISTER_RAW_SIZE(regno); + i += sizeof(int)) { + errno = 0; + ptrace(PT_WRITE_U, inferior_pid, + (caddr_t)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); + } + } +} + +/* + * Copy LEN bytes from inferior's memory starting at MEMADDR to debugger + * memory starting at MYADDR. On failure (cannot read from inferior, usually + * because address is out of bounds) returns the value of errno. + */ +int +read_inferior_memory(memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & -sizeof(int); + /* Round ending address up; get number of longwords that makes. */ + register int count = (((memaddr + len) - addr) + sizeof(int) - 1) / + sizeof(int); + /* Allocate buffer of that many longwords. */ + register int *buffer = (int *) alloca(count * sizeof(int)); + extern int errno; + + if (remote_debugging) + return (remote_read_inferior_memory(memaddr, myaddr, len)); + + /* Read all the longwords */ + errno = 0; + for (i = 0; i < count && errno == 0; i++, addr += sizeof(int)) + buffer[i] = ptrace(PT_READ_I, inferior_pid, (caddr_t)addr, 0); + + /* Copy appropriate bytes out of the buffer. */ + bcopy((char *) buffer + (memaddr & (sizeof(int) - 1)), myaddr, len); + return(errno); +} + +/* + * Copy LEN bytes of data from debugger memory at MYADDR to inferior's memory + * at MEMADDR. On failure (cannot write the inferior) returns the value of + * errno. + */ + +int +write_inferior_memory(memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & -sizeof(int); + /* Round ending address up; get number of longwords that makes. */ + register int count = (((memaddr + len) - addr) + sizeof(int) - 1) / + sizeof(int); + /* Allocate buffer of that many longwords. */ + register int *buffer = (int *) alloca(count * sizeof(int)); + extern int errno; + + /* + * Fill start and end extra bytes of buffer with existing memory + * data. + */ + if (remote_debugging) + return (remote_write_inferior_memory(memaddr, myaddr, len)); + + /* + * Fill start and end extra bytes of buffer with existing memory + * data. + */ + buffer[0] = ptrace(PT_READ_I, inferior_pid, (caddr_t)addr, 0); + + if (count > 1) + buffer[count - 1] = ptrace(PT_READ_I, inferior_pid, + (caddr_t)addr + (count - 1) * sizeof(int), 0); + + /* Copy data to be written over corresponding part of buffer */ + + bcopy(myaddr, (char *) buffer + (memaddr & (sizeof(int) - 1)), len); + + /* Write the entire buffer. */ + + errno = 0; + for (i = 0; i < count && errno == 0; i++, addr += sizeof(int)) + ptrace(PT_WRITE_I, inferior_pid, (caddr_t)addr, buffer[i]); + + return(errno); +} + + +/* + * Work with core dump and executable files, for GDB. + * This code would be in core.c if it weren't machine-dependent. + */ + +#ifndef N_TXTADDR +#define N_TXTADDR(hdr) 0 +#endif /* no N_TXTADDR */ + +#ifndef N_DATADDR +#define N_DATADDR(hdr) hdr.a_text +#endif /* no N_DATADDR */ + +/* + * Make COFF and non-COFF names for things a little more compatible to reduce + * conditionals later. + */ + +#ifndef AOUTHDR +#define AOUTHDR struct exec +#endif + +extern char *sys_siglist[]; + + +/* Hook for `exec_file_command' command to call. */ + +extern void (*exec_file_display_hook) (); + +/* File names of core file and executable file. */ + +extern char *corefile; +extern char *execfile; + +/* Descriptors on which core file and executable file are open. + Note that the execchan is closed when an inferior is created + and reopened if the inferior dies or is killed. */ + +extern int corechan; +extern int execchan; + +/* Last modification time of executable file. + Also used in source.c to compare against mtime of a source file. */ + +extern int exec_mtime; + +/* Virtual addresses of bounds of the two areas of memory in the core file. */ + +extern CORE_ADDR data_start; +extern CORE_ADDR data_end; +extern CORE_ADDR stack_start; +extern CORE_ADDR stack_end; + +/* Virtual addresses of bounds of two areas of memory in the exec file. + Note that the data area in the exec file is used only when there is no core file. */ + +extern CORE_ADDR text_start; +extern CORE_ADDR text_end; + +extern CORE_ADDR exec_data_start; +extern CORE_ADDR exec_data_end; + +/* Address in executable file of start of text area data. */ + +extern int text_offset; + +/* Address in executable file of start of data area data. */ + +extern int exec_data_offset; + +/* Address in core file of start of data area data. */ + +extern int data_offset; + +/* Address in core file of start of stack area data. */ + +extern int stack_offset; + +/* a.out header saved in core file. */ + +extern AOUTHDR core_aouthdr; + +/* a.out header of exec file. */ + +extern AOUTHDR exec_aouthdr; + +extern void validate_files (); + +extern int (*core_file_hook)(); + +#ifdef KERNELDEBUG +/* + * Kernel debugging routines. + */ + +#define IOTOP 0x100000 /* XXX should get this from include file */ +#define IOBASE 0xa0000 /* XXX should get this from include file */ + +static CORE_ADDR file_offset; +static CORE_ADDR lowram; +static CORE_ADDR sbr; +static CORE_ADDR slr; +static struct pcb pcb; + +static CORE_ADDR +ksym_lookup(name) + char *name; +{ + struct symbol *sym; + int i; + + if ((i = lookup_misc_func(name)) < 0) + error("kernel symbol `%s' not found.", name); + + return (misc_function_vector[i].address); +} + +/* + * return true if 'len' bytes starting at 'addr' can be read out as + * longwords and/or locally cached (this is mostly for memory mapped + * i/o register access when debugging remote kernels). + * + * XXX the HP code does this differently with NEWVM + */ +static int +ok_to_cache(addr, len) +{ + static CORE_ADDR atdevbase; + + if (! atdevbase) + atdevbase = ksym_lookup("atdevbase"); + + if (addr >= atdevbase && addr < atdevbase + (IOTOP - IOBASE)) + return (0); + + return (1); +} + +static +physrd(addr, dat, len) + u_int addr; + char *dat; +{ + if (lseek(corechan, addr - file_offset, L_SET) == -1) + return (-1); + if (read(corechan, dat, len) != len) + return (-1); + + return (0); +} + +/* + * When looking at kernel data space through /dev/mem or with a core file, do + * virtual memory mapping. + */ +#ifdef NEWVM +static CORE_ADDR +vtophys(addr) + CORE_ADDR addr; +{ + CORE_ADDR v; + struct pte pte; + static CORE_ADDR PTD = -1; + CORE_ADDR current_ptd; + + /* + * If we're looking at the kernel stack, + * munge the address to refer to the user space mapping instead; + * that way we get the requested process's kstack, not the running one. + */ + if (addr >= kstack && addr < kstack + ctob(UPAGES)) + addr = (addr - kstack) + curpcb; + + /* + * We may no longer have a linear system page table... + * + * Here's the scoop. IdlePTD contains the physical address + * of a page table directory that always maps the kernel. + * IdlePTD is in memory that is mapped 1-to-1, so we can + * find it easily given its 'virtual' address from ksym_lookup(). + * For hysterical reasons, the value of IdlePTD is stored in sbr. + * + * To look up a kernel address, we first convert it to a 1st-level + * address and look it up in IdlePTD. This gives us the physical + * address of a page table page; we extract the 2nd-level part of + * VA and read the 2nd-level pte. Finally, we add the offset part + * of the VA into the physical address from the pte and return it. + * + * User addresses are a little more complicated. If we don't have + * a current PCB from read_pcb(), we use PTD, which is the (fixed) + * virtual address of the current ptd. Since it's NOT in 1-to-1 + * kernel space, we must look it up using IdlePTD. If we do have + * a pcb, we get the ptd from pcb_ptd. + */ + + if (INKERNEL(addr)) + current_ptd = sbr; + else if (found_pcb == 0) { + if (PTD == -1) + PTD = vtophys(ksym_lookup("PTD")); + current_ptd = PTD; + } else + current_ptd = pcb.pcb_ptd; + + /* + * Read the first-level page table (ptd). + */ + v = current_ptd + ((unsigned)addr >> PD_SHIFT) * sizeof pte; + if (physrd(v, (char *)&pte, sizeof pte) || pte.pg_v == 0) + return (~0); + + /* + * Read the second-level page table. + */ + v = i386_ptob(pte.pg_pfnum) + ((addr&PT_MASK) >> PG_SHIFT) * sizeof pte; + if (physrd(v, (char *) &pte, sizeof(pte)) || pte.pg_v == 0) + return (~0); + + addr = i386_ptob(pte.pg_pfnum) + (addr & PGOFSET); +#if 0 + printf("vtophys(%x) -> %x\n", oldaddr, addr); +#endif + return (addr); +} +#else +static CORE_ADDR +vtophys(addr) + CORE_ADDR addr; +{ + CORE_ADDR v; + struct pte pte; + CORE_ADDR oldaddr = addr; + + if (found_pcb == 0 && INUPAGE(addr)) { + static CORE_ADDR pSwtchmap; + + if (pSwtchmap == 0) + pSwtchmap = vtophys(ksym_lookup("Swtchmap")); + addr = pSwtchmap; + } else if (INKERNEL(addr)) { + /* + * In system space get system pte. If valid or reclaimable + * then physical address is combination of its page number + * and the page offset of the original address. + */ + addr = smxtob(btop(addr - KERNOFF)) - KERNOFF; + } else { + v = btop(addr); + if (v < pcb.pcb_p0lr) + addr = (CORE_ADDR) pcb.pcb_p0br + + v * sizeof (struct pte); + else if (v >= pcb.pcb_p1lr && v < P1PAGES) + addr = (CORE_ADDR) pcb.pcb_p0br + + ((pcb.pcb_szpt * NPTEPG - HIGHPAGES) - + (BTOPUSRSTACK - v)) * sizeof (struct pte); + else + return (~0); + + /* + * For p0/p1 address, user-level page table should be in + * kernel vm. Do second-level indirect by recursing. + */ + if (!INKERNEL(addr)) + return (~0); + + addr = vtophys(addr); + } + /* + * Addr is now address of the pte of the page we are interested in; + * get the pte and paste up the physical address. + */ + if (physrd(addr, (char *) &pte, sizeof(pte))) + return (~0); + + if (pte.pg_v == 0 && (pte.pg_fod || pte.pg_pfnum == 0)) + return (~0); + + addr = (CORE_ADDR)ptob(pte.pg_pfnum) + (oldaddr & PGOFSET); +#if 0 + printf("vtophys(%x) -> %x\n", oldaddr, addr); +#endif + return (addr); +} + +#endif + +static +kvread(addr) + CORE_ADDR addr; +{ + CORE_ADDR paddr = vtophys(addr); + + if (paddr != ~0) + if (physrd(paddr, (char *)&addr, sizeof(addr)) == 0); + return (addr); + + return (~0); +} + +static void +read_pcb(uaddr) + u_int uaddr; +{ + int i; + int *pcb_regs = (int *)&pcb; + +#ifdef NEWVM + if (physrd(uaddr, (char *)&pcb, sizeof pcb)) + error("cannot read pcb at %x\n", uaddr); + printf("current pcb at %x\n", uaddr); +#else + if (physrd(uaddr, (char *)&pcb, sizeof pcb)) + error("cannot read pcb at %x\n", uaddr); + printf("p0br %x p0lr %x p1br %x p1lr %x\n", + pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr); +#endif + + /* + * get the register values out of the sys pcb and + * store them where `read_register' will find them. + */ + for (i = 0; i < 8; ++i) + supply_register(i, &pcb_regs[i+10]); + supply_register(8, &pcb_regs[8]); /* eip */ + supply_register(9, &pcb_regs[9]); /* eflags */ + for (i = 10; i < 13; ++i) /* cs, ss, ds */ + supply_register(i, &pcb_regs[i+9]); + supply_register(13, &pcb_regs[18]); /* es */ + for (i = 14; i < 16; ++i) /* fs, gs */ + supply_register(i, &pcb_regs[i+8]); + + /* XXX 80387 registers? */ +} + +static void +setup_kernel_debugging() +{ + struct stat stb; + int devmem = 0; + CORE_ADDR addr; + + fstat(corechan, &stb); + if ((stb.st_mode & S_IFMT) == S_IFCHR && stb.st_rdev == makedev(2, 0)) + devmem = 1; + +#ifdef NEWVM + physrd(ksym_lookup("IdlePTD") - KERNOFF, &sbr, sizeof sbr); + slr = 2 * NPTEPG; /* XXX temporary */ + printf("IdlePTD %x\n", sbr); + curpcb = ksym_lookup("curpcb") - KERNOFF; + physrd(curpcb, &curpcb, sizeof curpcb); + kstack = ksym_lookup("kstack"); +#else + sbr = ksym_lookup("Sysmap"); + slr = ksym_lookup("Syssize"); + printf("sbr %x slr %x\n", sbr, slr); +#endif + + /* + * pcb where "panic" saved registers in first thing in current + * u area. + */ +#ifndef NEWVM + read_pcb(vtophys(ksym_lookup("u"))); +#endif + found_pcb = 1; + if (!devmem) { + /* find stack frame */ + CORE_ADDR panicstr; + char buf[256]; + register char *cp; + + panicstr = kvread(ksym_lookup("panicstr")); + if (panicstr == ~0) + return; + (void) kernel_core_file_hook(panicstr, buf, sizeof(buf)); + for (cp = buf; cp < &buf[sizeof(buf)] && *cp; cp++) + if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp))) + *cp = '?'; + if (*cp) + *cp = '\0'; + printf("panic: %s\n", buf); + read_pcb(ksym_lookup("dumppcb") - KERNOFF); + } +#ifdef NEWVM + else + read_pcb(vtophys(kstack)); +#endif + + stack_start = USRSTACK; + stack_end = USRSTACK + ctob(UPAGES); +} + +set_paddr_command(arg) + char *arg; +{ + u_int uaddr; + + if (!arg) + error_no_arg("ps-style address for new current process"); + if (!kernel_debugging) + error("not debugging kernel"); + uaddr = (u_int) parse_and_eval_address(arg); +#ifndef NEWVM + read_pcb(ctob(uaddr)); +#else + /* p_addr is now a pcb virtual address */ + read_pcb(vtophys(uaddr)); + curpcb = uaddr; +#endif + + flush_cached_frames(); + set_current_frame(create_new_frame(read_register(FP_REGNUM), read_pc())); + select_frame(get_current_frame(), 0); +} + +/* + * read len bytes from kernel virtual address 'addr' into local + * buffer 'buf'. Return 0 if read ok, 1 otherwise. On read + * errors, portion of buffer not read is zeroed. + */ +kernel_core_file_hook(addr, buf, len) + CORE_ADDR addr; + char *buf; + int len; +{ + int i; + CORE_ADDR paddr; + + while (len > 0) { + paddr = vtophys(addr); + if (paddr == ~0) { + bzero(buf, len); + return (1); + } + /* we can't read across a page boundary */ + i = min(len, NBPG - (addr & PGOFSET)); + if (physrd(paddr, buf, i)) { + bzero(buf, len); + return (1); + } + buf += i; + addr += i; + len -= i; + } + return (0); +} +#endif + +core_file_command(filename, from_tty) + char *filename; + int from_tty; +{ + int val; + extern char registers[]; +#ifdef KERNELDEBUG + struct stat stb; +#endif + + /* + * Discard all vestiges of any previous core file and mark data and + * stack spaces as empty. + */ + if (corefile) + free(corefile); + corefile = 0; + core_file_hook = 0; + + if (corechan >= 0) + close(corechan); + corechan = -1; + + /* Now, if a new core file was specified, open it and digest it. */ + + if (filename == 0) { + if (from_tty) + printf("No core file now.\n"); + return; + } + filename = tilde_expand(filename); + make_cleanup(free, filename); + if (have_inferior_p()) + error("To look at a core file, you must kill the inferior with \"kill\"."); + corechan = open(filename, O_RDONLY, 0); + if (corechan < 0) + perror_with_name(filename); + +#ifdef KERNELDEBUG + fstat(corechan, &stb); + + if (kernel_debugging) { + setup_kernel_debugging(); + core_file_hook = kernel_core_file_hook; + } else if ((stb.st_mode & S_IFMT) == S_IFCHR && + stb.st_rdev == makedev(2, 1)) { + /* looking at /dev/kmem */ + data_offset = data_start = KERNOFF; + data_end = ~0; /* XXX */ + stack_end = stack_start = data_end; + } else +#endif + { + /* + * 4.2-style core dump file. + */ + struct user u; + unsigned int reg_offset; + + val = myread(corechan, &u, sizeof u); + if (val < 0) + perror_with_name("Not a core file: reading upage"); + if (val != sizeof u) + error("Not a core file: could only read %d bytes", val); + + /* + * We are depending on exec_file_command having been + * called previously to set exec_data_start. Since + * the executable and the core file share the same + * text segment, the address of the data segment will + * be the same in both. + */ + data_start = exec_data_start; + +#ifndef NEWVM + data_end = data_start + NBPG * u.u_dsize; + stack_start = stack_end - NBPG * u.u_ssize; + data_offset = NBPG * UPAGES; + stack_offset = NBPG * (UPAGES + u.u_dsize); + + /* + * Some machines put an absolute address in here and + * some put the offset in the upage of the regs. + */ + reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR; +#else + data_end = data_start + + NBPG * u.u_kproc.kp_eproc.e_vm.vm_dsize; + stack_start = stack_end - + NBPG * u.u_kproc.kp_eproc.e_vm.vm_ssize; + data_offset = NBPG * UPAGES; + stack_offset = NBPG * + (UPAGES + u.u_kproc.kp_eproc.e_vm.vm_dsize); + + reg_offset = (int) u.u_kproc.kp_proc.p_regs - USRSTACK; +#endif + + setregmap(u.u_pcb.pcb_flags); + + /* + * I don't know where to find this info. So, for now, + * mark it as not available. + */ + /* N_SET_MAGIC (core_aouthdr, 0); */ + bzero ((char *) &core_aouthdr, sizeof core_aouthdr); + + /* + * Read the register values out of the core file and + * store them where `read_register' will find them. + */ + { + register int regno; + + for (regno = 0; regno < NUM_REGS; regno++) { + char buf[MAX_REGISTER_RAW_SIZE]; + + val = lseek(corechan, register_addr(regno, reg_offset), 0); + if (val < 0 + || (val = myread(corechan, buf, sizeof buf)) < 0) { + char *buffer = (char *) alloca(strlen(reg_names[regno]) + 30); + strcpy(buffer, "Reading register "); + strcat(buffer, reg_names[regno]); + perror_with_name(buffer); + } + supply_register(regno, buf); + } + } + } +#endif + if (filename[0] == '/') + corefile = savestring(filename, strlen(filename)); + else + corefile = concat(current_directory, "/", filename); + + set_current_frame(create_new_frame(read_register(FP_REGNUM), + read_pc())); + select_frame(get_current_frame(), 0); + validate_files(); +} + +exec_file_command(filename, from_tty) + char *filename; + int from_tty; +{ + int val; + + /* + * Eliminate all traces of old exec file. Mark text segment as empty. + */ + + if (execfile) + free(execfile); + execfile = 0; + data_start = 0; + data_end = 0; + stack_start = 0; + stack_end = 0; + text_start = 0; + text_end = 0; + exec_data_start = 0; + exec_data_end = 0; + if (execchan >= 0) + close(execchan); + execchan = -1; + + /* Now open and digest the file the user requested, if any. */ + + if (filename) { + filename = tilde_expand(filename); + make_cleanup(free, filename); + + execchan = openp(getenv("PATH"), 1, filename, O_RDONLY, 0, + &execfile); + if (execchan < 0) + perror_with_name(filename); + + { + struct stat st_exec; + +#ifdef HEADER_SEEK_FD + HEADER_SEEK_FD(execchan); +#endif + + val = myread(execchan, &exec_aouthdr, sizeof(AOUTHDR)); + + if (val < 0) + perror_with_name(filename); + +#ifdef KERNELDEBUG + if (kernel_debugging) { + /* Gross and disgusting XXX */ + text_start = KERNTEXT_BASE; + exec_data_start = KERNTEXT_BASE + + (exec_aouthdr.a_text + 4095) & ~ 4095; + } else { +#endif + text_start = N_TXTADDR(exec_aouthdr); + exec_data_start = N_DATADDR(exec_aouthdr); +#ifdef KERNELDEBUG + } +#endif + + text_offset = N_TXTOFF(exec_aouthdr); + exec_data_offset = N_TXTOFF(exec_aouthdr) + exec_aouthdr.a_text; + + text_end = text_start + exec_aouthdr.a_text; + exec_data_end = exec_data_start + exec_aouthdr.a_data; + + fstat(execchan, &st_exec); + exec_mtime = st_exec.st_mtime; + } + + validate_files(); + } else if (from_tty) + printf("No exec file now.\n"); + + /* Tell display code (if any) about the changed file name. */ + if (exec_file_display_hook) + (*exec_file_display_hook) (filename); +} + +int dummy_code[] = { + 0xb8909090, /* nop; nop; nop; movl $0x32323232,%eax */ + 0x32323232, +#define DUMMY_CALL_INDEX 1 + 0x90ccd0ff, /* call %eax; int3; nop */ +}; + +/* + * Build `dummy' call instructions on inferior's stack to cause + * it to call a subroutine. + * + * N.B. - code in wait_for_inferior requires that sp < pc < fp when + * we take the trap 2 above so it will recognize that we stopped + * at a `dummy' call. So, after the call sp is *not* decremented + * to clean the arguments, code & other stuff we lay on the stack. + * Since the regs are restored to saved values at the breakpoint, + * sp will get reset correctly. Also, this restore means we don't + * have to construct frame linkage info to save pc & fp. The lack + * of frame linkage means we can't do a backtrace, etc., if the + * called function gets a fault or hits a breakpoint but code in + * run_stack_dummy makes this impossible anyway. + */ +CORE_ADDR +setup_dummy(sp, funaddr, nargs, args, struct_return_bytes, pushfn) + CORE_ADDR sp; + CORE_ADDR funaddr; + int nargs; + value *args; + int struct_return_bytes; + CORE_ADDR (*pushfn)(); +{ + int padding, i; + CORE_ADDR top = sp, struct_addr, pc; + + i = arg_stacklen(nargs, args) + struct_return_bytes + + sizeof(dummy_code); + if (i & 3) + padding = 4 - (i & 3); + else + padding = 0; + pc = sp - sizeof(dummy_code); + sp = pc - padding - struct_return_bytes; + struct_addr = sp; + while (--nargs >= 0) + sp = (*pushfn)(sp, *args++); + if (struct_return_bytes) + STORE_STRUCT_RETURN(struct_addr, sp); + write_register(SP_REGNUM, sp); + + dummy_code[DUMMY_CALL_INDEX] = (int)funaddr; + write_memory(pc, (char *)dummy_code, sizeof(dummy_code)); + + return pc; +} + +/* helper functions for m-i386.h */ + +/* stdio style buffering to minimize calls to ptrace */ +static CORE_ADDR codestream_next_addr; +static CORE_ADDR codestream_addr; +static unsigned char codestream_buf[sizeof (int)]; +static int codestream_off; +static int codestream_cnt; + +#define codestream_tell() (codestream_addr + codestream_off) +#define codestream_peek() (codestream_cnt == 0 ? \ + codestream_fill(1): codestream_buf[codestream_off]) +#define codestream_get() (codestream_cnt-- == 0 ? \ + codestream_fill(0) : codestream_buf[codestream_off++]) + +static unsigned char +codestream_fill (peek_flag) +{ + codestream_addr = codestream_next_addr; + codestream_next_addr += sizeof (int); + codestream_off = 0; + codestream_cnt = sizeof (int); + read_memory (codestream_addr, + (unsigned char *)codestream_buf, + sizeof (int)); + + if (peek_flag) + return (codestream_peek()); + else + return (codestream_get()); +} + +static void +codestream_seek (place) +{ + codestream_next_addr = place & -sizeof (int); + codestream_cnt = 0; + codestream_fill (1); + while (codestream_tell() != place) + codestream_get (); +} + +static void +codestream_read (buf, count) + unsigned char *buf; +{ + unsigned char *p; + int i; + p = buf; + for (i = 0; i < count; i++) + *p++ = codestream_get (); +} + +/* next instruction is a jump, move to target */ +static +i386_follow_jump () +{ + int long_delta; + short short_delta; + char byte_delta; + int data16; + int pos; + + pos = codestream_tell (); + + data16 = 0; + if (codestream_peek () == 0x66) + { + codestream_get (); + data16 = 1; + } + + switch (codestream_get ()) + { + case 0xe9: + /* relative jump: if data16 == 0, disp32, else disp16 */ + if (data16) + { + codestream_read ((unsigned char *)&short_delta, 2); + pos += short_delta + 3; /* include size of jmp inst */ + } + else + { + codestream_read ((unsigned char *)&long_delta, 4); + pos += long_delta + 5; + } + break; + case 0xeb: + /* relative jump, disp8 (ignore data16) */ + codestream_read ((unsigned char *)&byte_delta, 1); + pos += byte_delta + 2; + break; + } + codestream_seek (pos + data16); +} + +/* + * find & return amound a local space allocated, and advance codestream to + * first register push (if any) + * + * if entry sequence doesn't make sense, return -1, and leave + * codestream pointer random + */ +static long +i386_get_frame_setup (pc) +{ + unsigned char op; + + codestream_seek (pc); + + i386_follow_jump (); + + op = codestream_get (); + + if (op == 0x58) /* popl %eax */ + { + /* + * this function must start with + * + * popl %eax 0x58 + * xchgl %eax, (%esp) 0x87 0x04 0x24 + * or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00 + * + * (the system 5 compiler puts out the second xchg + * inst, and the assembler doesn't try to optimize it, + * so the 'sib' form gets generated) + * + * this sequence is used to get the address of the return + * buffer for a function that returns a structure + */ + int pos; + unsigned char buf[4]; + static unsigned char proto1[3] = { 0x87,0x04,0x24 }; + static unsigned char proto2[4] = { 0x87,0x44,0x24,0x00 }; + pos = codestream_tell (); + codestream_read (buf, 4); + if (bcmp (buf, proto1, 3) == 0) + pos += 3; + else if (bcmp (buf, proto2, 4) == 0) + pos += 4; + + codestream_seek (pos); + op = codestream_get (); /* update next opcode */ + } + + if (op == 0x55) /* pushl %esp */ + { + /* check for movl %esp, %ebp - can be written two ways */ + switch (codestream_get ()) + { + case 0x8b: + if (codestream_get () != 0xec) + return (-1); + break; + case 0x89: + if (codestream_get () != 0xe5) + return (-1); + break; + default: + return (-1); + } + /* check for stack adjustment + * + * subl $XXX, %esp + * + * note: you can't subtract a 16 bit immediate + * from a 32 bit reg, so we don't have to worry + * about a data16 prefix + */ + op = codestream_peek (); + if (op == 0x83) + { + /* subl with 8 bit immed */ + codestream_get (); + if (codestream_get () != 0xec) + return (-1); + /* subl with signed byte immediate + * (though it wouldn't make sense to be negative) + */ + return (codestream_get()); + } + else if (op == 0x81) + { + /* subl with 32 bit immed */ + int locals; + codestream_get(); + if (codestream_get () != 0xec) + return (-1); + /* subl with 32 bit immediate */ + codestream_read ((unsigned char *)&locals, 4); + return (locals); + } + else + { + return (0); + } + } + else if (op == 0xc8) + { + /* enter instruction: arg is 16 bit unsigned immed */ + unsigned short slocals; + codestream_read ((unsigned char *)&slocals, 2); + codestream_get (); /* flush final byte of enter instruction */ + return (slocals); + } + return (-1); +} + +/* Return number of args passed to a frame. + Can return -1, meaning no way to tell. */ + +/* on the 386, the instruction following the call could be: + * popl %ecx - one arg + * addl $imm, %esp - imm/4 args; imm may be 8 or 32 bits + * anything else - zero args + */ + +int +i386_frame_num_args (fi) + struct frame_info fi; +{ + int retpc; + unsigned char op; + struct frame_info *pfi; + + pfi = get_prev_frame_info ((fi)); + if (pfi == 0) + { + /* Note: this can happen if we are looking at the frame for + main, because FRAME_CHAIN_VALID won't let us go into + start. If we have debugging symbols, that's not really + a big deal; it just means it will only show as many arguments + to main as are declared. */ + return -1; + } + else + { + retpc = pfi->pc; + op = read_memory_integer (retpc, 1); + if (op == 0x59) + /* pop %ecx */ + return 1; + else if (op == 0x83) + { + op = read_memory_integer (retpc+1, 1); + if (op == 0xc4) + /* addl $<signed imm 8 bits>, %esp */ + return (read_memory_integer (retpc+2,1)&0xff)/4; + else + return 0; + } + else if (op == 0x81) + { /* add with 32 bit immediate */ + op = read_memory_integer (retpc+1, 1); + if (op == 0xc4) + /* addl $<imm 32>, %esp */ + return read_memory_integer (retpc+2, 4) / 4; + else + return 0; + } + else + { + return 0; + } + } +} + +/* + * parse the first few instructions of the function to see + * what registers were stored. + * + * We handle these cases: + * + * The startup sequence can be at the start of the function, + * or the function can start with a branch to startup code at the end. + * + * %ebp can be set up with either the 'enter' instruction, or + * 'pushl %ebp, movl %esp, %ebp' (enter is too slow to be useful, + * but was once used in the sys5 compiler) + * + * Local space is allocated just below the saved %ebp by either the + * 'enter' instruction, or by 'subl $<size>, %esp'. 'enter' has + * a 16 bit unsigned argument for space to allocate, and the + * 'addl' instruction could have either a signed byte, or + * 32 bit immediate. + * + * Next, the registers used by this function are pushed. In + * the sys5 compiler they will always be in the order: %edi, %esi, %ebx + * (and sometimes a harmless bug causes it to also save but not restore %eax); + * however, the code below is willing to see the pushes in any order, + * and will handle up to 8 of them. + * + * If the setup sequence is at the end of the function, then the + * next instruction will be a branch back to the start. + */ + +i386_frame_find_saved_regs (fip, fsrp) + struct frame_info *fip; + struct frame_saved_regs *fsrp; +{ + unsigned long locals; + unsigned char *p; + unsigned char op; + CORE_ADDR dummy_bottom; + CORE_ADDR adr; + int i; + + bzero (fsrp, sizeof *fsrp); + +#if 0 + /* if frame is the end of a dummy, compute where the + * beginning would be + */ + dummy_bottom = fip->frame - 4 - NUM_REGS*4 - CALL_DUMMY_LENGTH; + + /* check if the PC is in the stack, in a dummy frame */ + if (dummy_bottom <= fip->pc && fip->pc <= fip->frame) + { + /* all regs were saved by push_call_dummy () */ + adr = fip->frame - 4; + for (i = 0; i < NUM_REGS; i++) + { + fsrp->regs[i] = adr; + adr -= 4; + } + return; + } +#endif + + locals = i386_get_frame_setup (get_pc_function_start (fip->pc)); + + if (locals >= 0) + { + adr = fip->frame - 4 - locals; + for (i = 0; i < 8; i++) + { + op = codestream_get (); + if (op < 0x50 || op > 0x57) + break; + fsrp->regs[op - 0x50] = adr; + adr -= 4; + } + } + + fsrp->regs[PC_REGNUM] = fip->frame + 4; + fsrp->regs[FP_REGNUM] = fip->frame; +} + +/* return pc of first real instruction */ +i386_skip_prologue (pc) +{ + unsigned char op; + int i; + + if (i386_get_frame_setup (pc) < 0) + return (pc); + + /* found valid frame setup - codestream now points to + * start of push instructions for saving registers + */ + + /* skip over register saves */ + for (i = 0; i < 8; i++) + { + op = codestream_peek (); + /* break if not pushl inst */ + if (op < 0x50 || op > 0x57) + break; + codestream_get (); + } + + i386_follow_jump (); + + return (codestream_tell ()); +} + +i386_pop_frame () +{ + FRAME frame = get_current_frame (); + CORE_ADDR fp; + int regnum; + struct frame_saved_regs fsr; + struct frame_info *fi; + + fi = get_frame_info (frame); + fp = fi->frame; + get_frame_saved_regs (fi, &fsr); + for (regnum = 0; regnum < NUM_REGS; regnum++) + { + CORE_ADDR adr; + adr = fsr.regs[regnum]; + if (adr) + write_register (regnum, read_memory_integer (adr, 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); + flush_cached_frames (); + set_current_frame ( create_new_frame (read_register (FP_REGNUM), + read_pc ())); +} + +/* this table must line up with REGISTER_NAMES in m-i386.h */ +/* symbols like 'EAX' come from <sys/reg.h> */ +static int trapmap[] = +{ + tEAX, tECX, tEDX, tEBX, + tESP, tEBP, tESI, tEDI, + tEIP, tEFLAGS, tCS, tSS, + tDS, tES, tES, tES /* lies: no fs or gs */ +}; +#if defined(FM_TRAP) || defined(EX_TRAPSTK) +static int syscallmap[] = +{ + sEAX, sECX, sEDX, sEBX, + sESP, sEBP, sESI, sEDI, + sEIP, sEFLAGS, sCS, sSS, + sCS, sCS, sCS, sCS /* lies: no ds, es, fs or gs */ +}; +#endif +static int *regmap; + +static void +setregmap(flags) + int flags; +{ +#ifdef FM_TRAP + regmap = flags & FM_TRAP ? trapmap: syscallmap; +#elif EX_TRAPSTK + regmap = flags & EX_TRAPSTK ? trapmap : syscallmap; +#else + regmap = trapmap; /* the lesser evil */ +#endif +} + +/* blockend is the value of u.u_ar0, and points to the + * place where GS is stored + */ +i386_register_u_addr (blockend, regnum) +{ +#if 0 + /* this will be needed if fp registers are reinstated */ + /* for now, you can look at them with 'info float' + * sys5 wont let you change them with ptrace anyway + */ + if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM) + { + int ubase, fpstate; + struct user u; + ubase = blockend + 4 * (SS + 1) - KSTKSZ; + fpstate = ubase + ((char *)&u.u_fpstate - (char *)&u); + return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM)); + } + else +#endif + return (blockend + 4 * regmap[regnum]); +} + +i387_to_double (from, to) + char *from; + char *to; +{ + long *lp; + /* push extended mode on 387 stack, then pop in double mode + * + * first, set exception masks so no error is generated - + * number will be rounded to inf or 0, if necessary + */ + asm ("pushl %eax"); /* grab a stack slot */ + asm ("fstcw (%esp)"); /* get 387 control word */ + asm ("movl (%esp),%eax"); /* save old value */ + asm ("orl $0x3f,%eax"); /* mask all exceptions */ + asm ("pushl %eax"); + asm ("fldcw (%esp)"); /* load new value into 387 */ + + asm ("movl 8(%ebp),%eax"); + asm ("fldt (%eax)"); /* push extended number on 387 stack */ + asm ("fwait"); + asm ("movl 12(%ebp),%eax"); + asm ("fstpl (%eax)"); /* pop double */ + asm ("fwait"); + + asm ("popl %eax"); /* flush modified control word */ + asm ("fnclex"); /* clear exceptions */ + asm ("fldcw (%esp)"); /* restore original control word */ + asm ("popl %eax"); /* flush saved copy */ +} + +double_to_i387 (from, to) + char *from; + char *to; +{ + /* push double mode on 387 stack, then pop in extended mode + * no errors are possible because every 64-bit pattern + * can be converted to an extended + */ + asm ("movl 8(%ebp),%eax"); + asm ("fldl (%eax)"); + asm ("fwait"); + asm ("movl 12(%ebp),%eax"); + asm ("fstpt (%eax)"); + asm ("fwait"); +} + +struct env387 +{ + unsigned short control; + unsigned short r0; + unsigned short status; + unsigned short r1; + unsigned short tag; + unsigned short r2; + unsigned long eip; + unsigned short code_seg; + unsigned short opcode; + unsigned long operand; + unsigned short operand_seg; + unsigned short r3; + unsigned char regs[8][10]; +}; + +static +print_387_control_word (control) +unsigned short control; +{ + printf ("control 0x%04x: ", control); + printf ("compute to "); + switch ((control >> 8) & 3) + { + case 0: printf ("24 bits; "); break; + case 1: printf ("(bad); "); break; + case 2: printf ("53 bits; "); break; + case 3: printf ("64 bits; "); break; + } + printf ("round "); + switch ((control >> 10) & 3) + { + case 0: printf ("NEAREST; "); break; + case 1: printf ("DOWN; "); break; + case 2: printf ("UP; "); break; + case 3: printf ("CHOP; "); break; + } + if (control & 0x3f) + { + printf ("mask:"); + if (control & 0x0001) printf (" INVALID"); + if (control & 0x0002) printf (" DENORM"); + if (control & 0x0004) printf (" DIVZ"); + if (control & 0x0008) printf (" OVERF"); + if (control & 0x0010) printf (" UNDERF"); + if (control & 0x0020) printf (" LOS"); + printf (";"); + } + printf ("\n"); + if (control & 0xe080) printf ("warning: reserved bits on 0x%x\n", + control & 0xe080); +} + +static +print_387_status_word (status) + unsigned short status; +{ + printf ("status 0x%04x: ", status); + if (status & 0xff) + { + printf ("exceptions:"); + if (status & 0x0001) printf (" INVALID"); + if (status & 0x0002) printf (" DENORM"); + if (status & 0x0004) printf (" DIVZ"); + if (status & 0x0008) printf (" OVERF"); + if (status & 0x0010) printf (" UNDERF"); + if (status & 0x0020) printf (" LOS"); + if (status & 0x0040) printf (" FPSTACK"); + printf ("; "); + } + printf ("flags: %d%d%d%d; ", + (status & 0x4000) != 0, + (status & 0x0400) != 0, + (status & 0x0200) != 0, + (status & 0x0100) != 0); + + printf ("top %d\n", (status >> 11) & 7); +} + +static +print_387_status (status, ep) + unsigned short status; + struct env387 *ep; +{ + int i; + int bothstatus; + int top; + int fpreg; + unsigned char *p; + + bothstatus = ((status != 0) && (ep->status != 0)); + if (status != 0) + { + if (bothstatus) + printf ("u: "); + print_387_status_word (status); + } + + if (ep->status != 0) + { + if (bothstatus) + printf ("e: "); + print_387_status_word (ep->status); + } + + print_387_control_word (ep->control); + printf ("last exception: "); + printf ("opcode 0x%x; ", ep->opcode); + printf ("pc 0x%x:0x%x; ", ep->code_seg, ep->eip); + printf ("operand 0x%x:0x%x\n", ep->operand_seg, ep->operand); + + top = (ep->status >> 11) & 7; + + printf (" regno tag msb lsb value\n"); + for (fpreg = 7; fpreg >= 0; fpreg--) + { + int st_regno; + double val; + + /* The physical regno `fpreg' is only relevant as an index into the + * tag word. Logical `%st' numbers are required for indexing `p->regs. + */ + st_regno = (fpreg + 8 - top) & 0x7; + + printf ("%%st(%d) %s ", st_regno, fpreg == top ? "=>" : " "); + + switch ((ep->tag >> (fpreg * 2)) & 3) + { + case 0: printf ("valid "); break; + case 1: printf ("zero "); break; + case 2: printf ("trap "); break; + case 3: printf ("empty "); break; + } + for (i = 9; i >= 0; i--) + printf ("%02x", ep->regs[st_regno][i]); + + i387_to_double (ep->regs[st_regno], (char *)&val); + printf (" %g\n", val); + } +#if 0 /* reserved fields are always 0xffff on 486's */ + if (ep->r0) + printf ("warning: reserved0 is 0x%x\n", ep->r0); + if (ep->r1) + printf ("warning: reserved1 is 0x%x\n", ep->r1); + if (ep->r2) + printf ("warning: reserved2 is 0x%x\n", ep->r2); + if (ep->r3) + printf ("warning: reserved3 is 0x%x\n", ep->r3); +#endif +} + +#ifdef __386BSD__ +#define fpstate save87 +#define U_FPSTATE(u) u.u_pcb.pcb_savefpu +#endif + +#ifndef U_FPSTATE +#define U_FPSTATE(u) u.u_fpstate +#endif + +i386_float_info () +{ + struct user u; /* just for address computations */ + int i; + /* fpstate defined in <sys/user.h> */ + struct fpstate *fpstatep; + char buf[sizeof (struct fpstate) + 2 * sizeof (int)]; + unsigned int uaddr; + char fpvalid; + unsigned int rounded_addr; + unsigned int rounded_size; + extern int corechan; + int skip; + +#ifndef __386BSD__ /* XXX - look at pcb flags */ + uaddr = (char *)&u.u_fpvalid - (char *)&u; + if (have_inferior_p()) + { + unsigned int data; + unsigned int mask; + + rounded_addr = uaddr & -sizeof (int); + data = ptrace (PT_READ_U, inferior_pid, (caddr_t)rounded_addr, 0); + mask = 0xff << ((uaddr - rounded_addr) * 8); + + fpvalid = ((data & mask) != 0); + } + else + { + if (lseek (corechan, uaddr, 0) < 0) + perror ("seek on core file"); + if (myread (corechan, &fpvalid, 1) < 0) + perror ("read on core file"); + + } + + if (fpvalid == 0) + { + printf ("no floating point status saved\n"); + return; + } +#endif /* not __386BSD__ */ + + uaddr = (char *)&U_FPSTATE(u) - (char *)&u; + if (have_inferior_p ()) + { + int *ip; + + rounded_addr = uaddr & -sizeof (int); + rounded_size = (((uaddr + sizeof (struct fpstate)) - uaddr) + + sizeof (int) - 1) / sizeof (int); + skip = uaddr - rounded_addr; + + ip = (int *)buf; + for (i = 0; i < rounded_size; i++) + { + *ip++ = ptrace (PT_READ_U, inferior_pid, (caddr_t)rounded_addr, 0); + rounded_addr += sizeof (int); + } + } + else + { + if (lseek (corechan, uaddr, 0) < 0) + perror_with_name ("seek on core file"); + if (myread (corechan, buf, sizeof (struct fpstate)) < 0) + perror_with_name ("read from core file"); + skip = 0; + } + +#ifdef __386BSD__ + print_387_status (0, (struct env387 *)buf); +#else + fpstatep = (struct fpstate *)(buf + skip); + print_387_status (fpstatep->status, (struct env387 *)fpstatep->state); +#endif +} + +void +_initialize_i386bsd_dep() +{ +#ifdef KERNELDEBUG + add_com ("process-address", class_obscure, set_paddr_command, + "The process identified by (ps-style) ADDR becomes the\n\ +\"current\" process context for kernel debugging."); + add_com_alias ("paddr", "process-address", class_obscure, 0); +#endif +} diff --git a/gnu/usr.bin/gdb/config/m-i386-sv32.h b/gnu/usr.bin/gdb/config/m-i386-sv32.h new file mode 100644 index 000000000000..38fb4eb6d5b6 --- /dev/null +++ b/gnu/usr.bin/gdb/config/m-i386-sv32.h @@ -0,0 +1,28 @@ +/* Macro defintions for i386, running System V 3.2. + Copyright (C) 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "m-i386.h" + +/* Apparently there is inconsistency among various System V's about what + the name of this field is. */ +#define U_FPSTATE(u) u.u_fps.u_fpstate + +/* TIOCGETC is defined in System V 3.2 termio.h, but struct tchars + is not. This makes problems for inflow.c. */ +#define TIOCGETC_BROKEN diff --git a/gnu/usr.bin/gdb/config/m-i386.h b/gnu/usr.bin/gdb/config/m-i386.h new file mode 100644 index 000000000000..5449ec454c95 --- /dev/null +++ b/gnu/usr.bin/gdb/config/m-i386.h @@ -0,0 +1,394 @@ +/* Macro defintions for i386. + Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Define the bit, byte, and word ordering of the machine. */ +/* #define BITS_BIG_ENDIAN */ +/* #define BYTES_BIG_ENDIAN */ +/* #define WORDS_BIG_ENDIAN */ + +/* + * Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu) + * July 1988 + */ + + +#ifndef i386 +#define i386 +#endif + +/* I'm running gdb 3.4 under 386/ix 2.0.2, which is a derivative of AT&T's +Sys V/386 3.2. + +On some machines, gdb crashes when it's starting up while calling the +vendor's termio tgetent() routine. It always works when run under +itself (actually, under 3.2, it's not an infinitely recursive bug.) +After some poking around, it appears that depending on the environment +size, or whether you're running YP, or the phase of the moon or something, +the stack is not always long-aligned when main() is called, and tgetent() +takes strong offense at that. On some machines this bug never appears, but +on those where it does, it occurs quite reliably. */ +#define ALIGN_STACK_ON_STARTUP + +/* define USG if you are using sys5 /usr/include's */ +#define USG + +/* USG systems need these */ +#define vfork() fork() +#define MAXPATHLEN 500 + +/* define this if you don't have the extension to coff that allows + * file names to appear in the string table + * (aux.x_file.x_foff) + */ +#define COFF_NO_LONG_FILE_NAMES + +/* turn this on when rest of gdb is ready */ +/* #define IEEE_FLOAT */ + +#define NBPG NBPC +#define UPAGES USIZE + +#define HAVE_TERMIO + +/* Get rid of any system-imposed stack limit if possible. */ + +/* #define SET_STACK_LIMIT_HUGE not in sys5 */ + +/* 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 */ + +/* Specify debugger information format. */ + +/* #define READ_DBX_FORMAT */ +#define COFF_FORMAT + +/* number of traps that happen between exec'ing the shell + * to run an inferior, and when we finally get to + * the inferior code. This is 2 on most implementations. + */ +#define START_INFERIOR_TRAPS_EXPECTED 4 + +/* 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(frompc) {(frompc) = i386_skip_prologue((frompc));} + +/* 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 0xe0000000 + +/* Address of end of stack space. */ + +#define STACK_END_ADDR 0x80000000 + +/* Stack grows downward. */ + +#define INNER_THAN < + +/* Sequence of bytes for breakpoint instruction. */ + +#define BREAKPOINT {0xcc} + +/* 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 1 + +/* Nonzero if instruction at PC is a return instruction. */ + +#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0xc3) + +/* Return 1 if P points to an invalid floating point value. + LEN is the length in bytes -- not relevant on the 386. */ + +#define INVALID_FLOAT(p, len) (0) + +/* code to execute to print interesting information about the + * floating point processor (if any) + * No need to define if there is nothing to do. + */ +#define FLOAT_INFO { i386_float_info (); } + + +/* Largest integer type */ +#define LONGEST long + +/* Name of the builtin type for the LONGEST type above. */ +#define BUILTIN_TYPE_LONGEST builtin_type_long + +/* Say how long (ordinary) registers are. */ + +#define REGISTER_TYPE long + +/* Number of machine registers */ + +#define NUM_REGS 16 + +/* Initializer for an array of names of registers. + There should be NUM_REGS strings in this initializer. */ + +/* the order of the first 8 registers must match the compiler's + * numbering scheme (which is the same as the 386 scheme) + * also, this table must match regmap in i386-pinsn.c. + */ +#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \ + "esp", "ebp", "esi", "edi", \ + "eip", "ps", "cs", "ss", \ + "ds", "es", "fs", "gs", \ + } + +/* 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 5 /* Contains address of executing stack frame */ +#define SP_REGNUM 4 /* Contains address of top of stack */ + +#define PC_REGNUM 8 +#define PS_REGNUM 9 + +#define REGISTER_U_ADDR(addr, blockend, regno) \ + (addr) = i386_register_u_addr ((blockend),(regno)); + +/* Total amount of space needed to store our copies of the machine's + register state, the array `registers'. */ +#define REGISTER_BYTES (NUM_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. */ + +#define REGISTER_RAW_SIZE(N) (4) + +/* Number of bytes of storage in the program's representation + for register N. */ + +#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), 4);} + +/* 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), 4);} + +/* Return the GDB type object for the "standard" data type + of data in register N. */ + +#define REGISTER_VIRTUAL_TYPE(N) (builtin_type_int) + +/* Store the address of the place in which to copy the structure the + subroutine will return. This is called from call_function. */ + +#define STORE_STRUCT_RETURN(ADDR, SP) \ + { (SP) -= sizeof (ADDR); \ + write_memory ((SP), &(ADDR), sizeof (ADDR)); } + +/* 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. */ + +#define FRAME_CHAIN(thisframe) \ + (outside_startup_file ((thisframe)->pc) ? \ + read_memory_integer ((thisframe)->frame, 4) :\ + 0) + +#define FRAME_CHAIN_VALID(chain, thisframe) \ + (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe)))) + +#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain) + +/* Define other aspects of the stack frame. */ + +/* A macro that tells us whether the function invocation represented + by FI does not have a frame on the stack associated with it. If it + does not, FRAMELESS is set to 1, else 0. */ +#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \ + FRAMELESS_LOOK_FOR_PROLOGUE(FI, FRAMELESS) + +#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->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(numargs, fi) (numargs) = i386_frame_num_args(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) \ +{ i386_frame_find_saved_regs ((frame_info), &(frame_saved_regs)); } + + +/* Things needed for making the inferior call functions. */ + +/* Push an empty stack frame, to record the current PC, etc. */ + +#define PUSH_DUMMY_FRAME { i386_push_dummy_frame (); } + +/* Discard from the stack the innermost frame, restoring all registers. */ + +#define POP_FRAME { i386_pop_frame (); } + +/* this is + * call 11223344 (32 bit relative) + * int3 + */ + +#define CALL_DUMMY { 0x223344e8, 0xcc11 } + +#define CALL_DUMMY_LENGTH 8 + +#define CALL_DUMMY_START_OFFSET 0 /* Start execution at beginning of dummy */ + +/* 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, pc, fun, nargs, type) \ +{ \ + int from, to, delta, loc; \ + loc = (int)(read_register (SP_REGNUM) - CALL_DUMMY_LENGTH); \ + from = loc + 5; \ + to = (int)(fun); \ + delta = to - from; \ + *(int *)((char *)(dummyname) + 1) = delta; \ +} + + +#if 0 +/* 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, 0, 0, 0, 0, \ + 0, 0, 0, 0, 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) {} + +/* Push the frame pointer register on the stack. */ +#define PUSH_FRAME_PTR {} + +/* Copy the top-of-stack to the frame pointer register. */ +#define POP_FRAME_PTR {} + +/* 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 {} + +/* 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 {} +#endif diff --git a/gnu/usr.bin/gdb/config/m-i386bsd.h b/gnu/usr.bin/gdb/config/m-i386bsd.h new file mode 100644 index 000000000000..15d97b23d339 --- /dev/null +++ b/gnu/usr.bin/gdb/config/m-i386bsd.h @@ -0,0 +1,375 @@ +/*- + * This code is derived from software copyrighted by the Free Software + * Foundation. + * + * Modified 1991 by Donn Seeley at UUNET Technologies, Inc. + * Modified 1991 by William Jolitz at UUNET Technologies, Inc. + * + * @(#)m-i386bsd.h 6.7 (Berkeley) 5/8/91 + */ + +/* Macro definitions for i386. + Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Define the bit, byte, and word ordering of the machine. */ +/* #define BITS_BIG_ENDIAN */ +/* #define BYTES_BIG_ENDIAN */ +/* #define WORDS_BIG_ENDIAN */ + +/* + * Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu) + * July 1988 + * [ MODIFIED FOR 386BSD W. Jolitz ] + */ + +#ifndef i386 +#define i386 1 +#define i386b 1 +#endif + +#define IEEE_FLOAT +#define LONG_LONG + +/* Library stuff: POSIX tty (not supported yet), V7 tty (sigh), vprintf. */ + +#define HAVE_TERMIOS 1 +#define USE_OLD_TTY 1 +#define HAVE_VPRINTF 1 + +/* We support local and remote kernel debugging. */ + +#define KERNELDEBUG 1 + +/* 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 + +/* Specify debugger information format. */ + +#define READ_DBX_FORMAT + +/* number of traps that happen between exec'ing the shell + * to run an inferior, and when we finally get to + * the inferior code. This is 2 on most implementations. + */ +#define START_INFERIOR_TRAPS_EXPECTED 2 + +/* 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(frompc) {(frompc) = i386_skip_prologue((frompc));} + +/* 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. */ + +#ifdef NEWVM +#include <machine/vmparam.h> +#define KERNEL_U_ADDR USRSTACK +#else +#define KERNEL_U_ADDR 0xfdffd000 +#endif + +/* Address of end of stack space. */ + +#define STACK_END_ADDR KERNEL_U_ADDR + +/* Stack grows downward. */ + +#define INNER_THAN < + +/* Sequence of bytes for breakpoint instruction. */ + +#define BREAKPOINT {0xcc} + +/* 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 1 + +/* Nonzero if instruction at PC is a return instruction. */ + +#define ABOUT_TO_RETURN(pc) \ + strchr("\302\303\312\313\317", read_memory_integer(pc, 1)) + +/* Return 1 if P points to an invalid floating point value. + LEN is the length in bytes -- not relevant on the 386. */ + +#define INVALID_FLOAT(p, len) (0) + +/* code to execute to print interesting information about the + * floating point processor (if any) + * No need to define if there is nothing to do. + */ +#define FLOAT_INFO { i386_float_info (); } + + +/* Largest integer type */ +#define LONGEST long long + +/* Name of the builtin type for the LONGEST type above. */ +#define BUILTIN_TYPE_LONGEST builtin_type_long_long + +/* Say how long (ordinary) registers are. */ + +#define REGISTER_TYPE long + +/* Number of machine registers */ + +#define NUM_REGS 16 + +/* Initializer for an array of names of registers. + There should be NUM_REGS strings in this initializer. */ + +/* the order of the first 8 registers must match the compiler's + * numbering scheme (which is the same as the 386 scheme) + * also, this table must match regmap in i386-pinsn.c. + */ +#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \ + "esp", "ebp", "esi", "edi", \ + "eip", "ps", "cs", "ss", \ + "ds", "es", "fs", "gs", \ + } + +/* 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 5 /* Contains address of executing stack frame */ +#define SP_REGNUM 4 /* Contains address of top of stack */ + +#define PC_REGNUM 8 +#define PS_REGNUM 9 + +#define REGISTER_U_ADDR(addr, blockend, regno) \ + (addr) = i386_register_u_addr ((blockend),(regno)); + +/* Total amount of space needed to store our copies of the machine's + register state, the array `registers'. */ +#define REGISTER_BYTES (NUM_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. */ + +#define REGISTER_RAW_SIZE(N) (4) + +/* Number of bytes of storage in the program's representation + for register N. */ + +#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), 4);} + +/* 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), 4);} + +/* Return the GDB type object for the "standard" data type + of data in register N. */ + +#define REGISTER_VIRTUAL_TYPE(N) (builtin_type_int) + +/* Store the address of the place in which to copy the structure the + subroutine will return. This is called from call_function. */ + +#define STORE_STRUCT_RETURN(ADDR, SP) \ + { (SP) -= sizeof (ADDR); \ + write_memory ((SP), &(ADDR), sizeof (ADDR)); } + +/* 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. */ + +#define FRAME_CHAIN(thisframe) \ + (outside_startup_file ((thisframe)->pc) ? \ + read_memory_integer ((thisframe)->frame, 4) :\ + 0) + +#ifdef KERNELDEBUG +#define KERNTEXT_BASE 0xfe000000 +#ifdef NEWVM +#define KERNSTACK_TOP (read_register(SP_REGNUM) + 0x2000) /* approximate */ +#else +/* #define KERNSTACK_TOP (P1PAGES << PGSHIFT) */ +#define KERNSTACK_TOP 0xfe000000 +#endif +extern int kernel_debugging; +#define FRAME_CHAIN_VALID(chain, thisframe) \ + (chain != 0 && \ + !kernel_debugging ? outside_startup_file(FRAME_SAVED_PC(thisframe)) :\ + (chain >= read_register(SP_REGNUM) && chain < KERNSTACK_TOP)) +#else +#define FRAME_CHAIN_VALID(chain, thisframe) \ + (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe)))) +#endif + +#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain) + +/* Define other aspects of the stack frame. */ + +/* A macro that tells us whether the function invocation represented + by FI does not have a frame on the stack associated with it. If it + does not, FRAMELESS is set to 1, else 0. */ +#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \ + FRAMELESS_LOOK_FOR_PROLOGUE(FI, FRAMELESS) + +#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->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(numargs, fi) (numargs) = i386_frame_num_args(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) \ +{ i386_frame_find_saved_regs ((frame_info), &(frame_saved_regs)); } + + +/* Discard from the stack the innermost frame, restoring all registers. */ + +#define POP_FRAME { i386_pop_frame (); } + +#define NEW_CALL_FUNCTION + +#if 0 +/* 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, 0, 0, 0, 0, \ + 0, 0, 0, 0, 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) {} + +/* Push the frame pointer register on the stack. */ +#define PUSH_FRAME_PTR {} + +/* Copy the top-of-stack to the frame pointer register. */ +#define POP_FRAME_PTR {} + +/* 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 {} + +/* 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 {} +#endif diff --git a/gnu/usr.bin/gdb/config/m-i386g-sv32.h b/gnu/usr.bin/gdb/config/m-i386g-sv32.h new file mode 100644 index 000000000000..3d69eea184e0 --- /dev/null +++ b/gnu/usr.bin/gdb/config/m-i386g-sv32.h @@ -0,0 +1,28 @@ +/* Macro defintions for i386, running System V 3.2. + Copyright (C) 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "m-i386gas.h" + +/* Apparently there is inconsistency among various System V's about what + the name of this field is. */ +#define U_FPSTATE(u) u.u_fps.u_fpstate + +/* TIOCGETC is defined in System V 3.2 termio.h, but struct tchars + is not. This makes problems for inflow.c. */ +#define TIOCGETC_BROKEN diff --git a/gnu/usr.bin/gdb/config/m-i386gas.h b/gnu/usr.bin/gdb/config/m-i386gas.h new file mode 100644 index 000000000000..fbd21385cc77 --- /dev/null +++ b/gnu/usr.bin/gdb/config/m-i386gas.h @@ -0,0 +1,37 @@ +/* Macro definitions for i386 using the GNU object file format. + Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + * Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu) + * July 1988 + * + * i386gnu: COFF_ENCAPSULATE + */ + + +#define COFF_ENCAPSULATE + +#include "m-i386.h" + + +#define NAMES_HAVE_UNDERSCORE + +#undef COFF_FORMAT +#define READ_DBX_FORMAT + diff --git a/gnu/usr.bin/gdb/copying.c b/gnu/usr.bin/gdb/copying.c new file mode 100644 index 000000000000..b3d75198078e --- /dev/null +++ b/gnu/usr.bin/gdb/copying.c @@ -0,0 +1,215 @@ +/* Do not modify this file; it is created automatically + by copying.awk. */ +extern int immediate_quit; +static void +copying_info () +{ + immediate_quit++; + printf_filtered ("\n"); + printf_filtered (" GNU GENERAL PUBLIC LICENSE\n"); + printf_filtered (" Version 1, February 1989\n"); + printf_filtered ("\n"); + printf_filtered (" Copyright (C) 1989 Free Software Foundation, Inc.\n"); + printf_filtered (" 675 Mass Ave, Cambridge, MA 02139, USA\n"); + printf_filtered (" Everyone is permitted to copy and distribute verbatim copies\n"); + printf_filtered (" of this license document, but changing it is not allowed.\n"); + printf_filtered ("\n"); + printf_filtered (" Preamble\n"); + printf_filtered ("\n"); + printf_filtered (" The license agreements of most software companies try to keep users\n"); + printf_filtered ("at the mercy of those companies. By contrast, our General Public\n"); + printf_filtered ("License is intended to guarantee your freedom to share and change free\n"); + printf_filtered ("software--to make sure the software is free for all its users. The\n"); + printf_filtered ("General Public License applies to the Free Software Foundation's\n"); + printf_filtered ("software and to any other program whose authors commit to using it.\n"); + printf_filtered ("You can use it for your programs, too.\n"); + printf_filtered ("\n"); + printf_filtered (" When we speak of free software, we are referring to freedom, not\n"); + printf_filtered ("price. Specifically, the General Public License is designed to make\n"); + printf_filtered ("sure that you have the freedom to give away or sell copies of free\n"); + printf_filtered ("software, that you receive source code or can get it if you want it,\n"); + printf_filtered ("that you can change the software or use pieces of it in new free\n"); + printf_filtered ("programs; and that you know you can do these things.\n"); + printf_filtered ("\n"); + printf_filtered (" To protect your rights, we need to make restrictions that forbid\n"); + printf_filtered ("anyone to deny you these rights or to ask you to surrender the rights.\n"); + printf_filtered ("These restrictions translate to certain responsibilities for you if you\n"); + printf_filtered ("distribute copies of the software, or if you modify it.\n"); + printf_filtered ("\n"); + printf_filtered (" For example, if you distribute copies of a such a program, whether\n"); + printf_filtered ("gratis or for a fee, you must give the recipients all the rights that\n"); + printf_filtered ("you have. You must make sure that they, too, receive or can get the\n"); + printf_filtered ("source code. And you must tell them their rights.\n"); + printf_filtered ("\n"); + printf_filtered (" We protect your rights with two steps: (1) copyright the software, and\n"); + printf_filtered ("(2) offer you this license which gives you legal permission to copy,\n"); + printf_filtered ("distribute and/or modify the software.\n"); + printf_filtered ("\n"); + printf_filtered (" Also, for each author's protection and ours, we want to make certain\n"); + printf_filtered ("that everyone understands that there is no warranty for this free\n"); + printf_filtered ("software. If the software is modified by someone else and passed on, we\n"); + printf_filtered ("want its recipients to know that what they have is not the original, so\n"); + printf_filtered ("that any problems introduced by others will not reflect on the original\n"); + printf_filtered ("authors' reputations.\n"); + printf_filtered ("\n"); + printf_filtered (" The precise terms and conditions for copying, distribution and\n"); + printf_filtered ("modification follow.\n"); + printf_filtered ("\n"); + printf_filtered (" GNU GENERAL PUBLIC LICENSE\n"); + printf_filtered (" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n"); + printf_filtered ("\n"); + printf_filtered (" 0. This License Agreement applies to any program or other work which\n"); + printf_filtered ("contains a notice placed by the copyright holder saying it may be\n"); + printf_filtered ("distributed under the terms of this General Public License. The\n"); + printf_filtered ("\"Program\", below, refers to any such program or work, and a \"work based\n"); + printf_filtered ("on the Program\" means either the Program or any work containing the\n"); + printf_filtered ("Program or a portion of it, either verbatim or with modifications. Each\n"); + printf_filtered ("licensee is addressed as \"you\".\n"); + printf_filtered ("\n"); + printf_filtered (" 1. You may copy and distribute verbatim copies of the Program's source\n"); + printf_filtered ("code as you receive it, in any medium, provided that you conspicuously and\n"); + printf_filtered ("appropriately publish on each copy an appropriate copyright notice and\n"); + printf_filtered ("disclaimer of warranty; keep intact all the notices that refer to this\n"); + printf_filtered ("General Public License and to the absence of any warranty; and give any\n"); + printf_filtered ("other recipients of the Program a copy of this General Public License\n"); + printf_filtered ("along with the Program. You may charge a fee for the physical act of\n"); + printf_filtered ("transferring a copy.\n"); + printf_filtered ("\n"); + printf_filtered (" 2. You may modify your copy or copies of the Program or any portion of\n"); + printf_filtered ("it, and copy and distribute such modifications under the terms of Paragraph\n"); + printf_filtered ("1 above, provided that you also do the following:\n"); + printf_filtered ("\n"); + printf_filtered (" a) cause the modified files to carry prominent notices stating that\n"); + printf_filtered (" you changed the files and the date of any change; and\n"); + printf_filtered ("\n"); + printf_filtered (" b) cause the whole of any work that you distribute or publish, that\n"); + printf_filtered (" in whole or in part contains the Program or any part thereof, either\n"); + printf_filtered (" with or without modifications, to be licensed at no charge to all\n"); + printf_filtered (" third parties under the terms of this General Public License (except\n"); + printf_filtered (" that you may choose to grant warranty protection to some or all\n"); + printf_filtered (" third parties, at your option).\n"); + printf_filtered ("\n"); + printf_filtered (" c) If the modified program normally reads commands interactively when\n"); + printf_filtered (" run, you must cause it, when started running for such interactive use\n"); + printf_filtered (" in the simplest and most usual way, to print or display an\n"); + printf_filtered (" announcement including an appropriate copyright notice and a notice\n"); + printf_filtered (" that there is no warranty (or else, saying that you provide a\n"); + printf_filtered (" warranty) and that users may redistribute the program under these\n"); + printf_filtered (" conditions, and telling the user how to view a copy of this General\n"); + printf_filtered (" Public License.\n"); + printf_filtered ("\n"); + printf_filtered (" d) You may charge a fee for the physical act of transferring a\n"); + printf_filtered (" copy, and you may at your option offer warranty protection in\n"); + printf_filtered (" exchange for a fee.\n"); + printf_filtered ("\n"); + printf_filtered ("Mere aggregation of another independent work with the Program (or its\n"); + printf_filtered ("derivative) on a volume of a storage or distribution medium does not bring\n"); + printf_filtered ("the other work under the scope of these terms.\n"); + printf_filtered ("\n"); + printf_filtered (" 3. You may copy and distribute the Program (or a portion or derivative of\n"); + printf_filtered ("it, under Paragraph 2) in object code or executable form under the terms of\n"); + printf_filtered ("Paragraphs 1 and 2 above provided that you also do one of the following:\n"); + printf_filtered ("\n"); + printf_filtered (" a) accompany it with the complete corresponding machine-readable\n"); + printf_filtered (" source code, which must be distributed under the terms of\n"); + printf_filtered (" Paragraphs 1 and 2 above; or,\n"); + printf_filtered ("\n"); + printf_filtered (" b) accompany it with a written offer, valid for at least three\n"); + printf_filtered (" years, to give any third party free (except for a nominal charge\n"); + printf_filtered (" for the cost of distribution) a complete machine-readable copy of the\n"); + printf_filtered (" corresponding source code, to be distributed under the terms of\n"); + printf_filtered (" Paragraphs 1 and 2 above; or,\n"); + printf_filtered ("\n"); + printf_filtered (" c) accompany it with the information you received as to where the\n"); + printf_filtered (" corresponding source code may be obtained. (This alternative is\n"); + printf_filtered (" allowed only for noncommercial distribution and only if you\n"); + printf_filtered (" received the program in object code or executable form alone.)\n"); + printf_filtered ("\n"); + printf_filtered ("Source code for a work means the preferred form of the work for making\n"); + printf_filtered ("modifications to it. For an executable file, complete source code means\n"); + printf_filtered ("all the source code for all modules it contains; but, as a special\n"); + printf_filtered ("exception, it need not include source code for modules which are standard\n"); + printf_filtered ("libraries that accompany the operating system on which the executable\n"); + printf_filtered ("file runs, or for standard header files or definitions files that\n"); + printf_filtered ("accompany that operating system.\n"); + printf_filtered ("\n"); + printf_filtered (" 4. You may not copy, modify, sublicense, distribute or transfer the\n"); + printf_filtered ("Program except as expressly provided under this General Public License.\n"); + printf_filtered ("Any attempt otherwise to copy, modify, sublicense, distribute or transfer\n"); + printf_filtered ("the Program is void, and will automatically terminate your rights to use\n"); + printf_filtered ("the Program under this License. However, parties who have received\n"); + printf_filtered ("copies, or rights to use copies, from you under this General Public\n"); + printf_filtered ("License will not have their licenses terminated so long as such parties\n"); + printf_filtered ("remain in full compliance.\n"); + printf_filtered ("\n"); + printf_filtered (" 5. By copying, distributing or modifying the Program (or any work based\n"); + printf_filtered ("on the Program) you indicate your acceptance of this license to do so,\n"); + printf_filtered ("and all its terms and conditions.\n"); + printf_filtered ("\n"); + printf_filtered (" 6. Each time you redistribute the Program (or any work based on the\n"); + printf_filtered ("Program), the recipient automatically receives a license from the original\n"); + printf_filtered ("licensor to copy, distribute or modify the Program subject to these\n"); + printf_filtered ("terms and conditions. You may not impose any further restrictions on the\n"); + printf_filtered ("recipients' exercise of the rights granted herein.\n"); + printf_filtered ("\n"); + printf_filtered (" 7. The Free Software Foundation may publish revised and/or new versions\n"); + printf_filtered ("of the General Public License from time to time. Such new versions will\n"); + printf_filtered ("be similar in spirit to the present version, but may differ in detail to\n"); + printf_filtered ("address new problems or concerns.\n"); + printf_filtered ("\n"); + printf_filtered ("Each version is given a distinguishing version number. If the Program\n"); + printf_filtered ("specifies a version number of the license which applies to it and \"any\n"); + printf_filtered ("later version\", you have the option of following the terms and conditions\n"); + printf_filtered ("either of that version or of any later version published by the Free\n"); + printf_filtered ("Software Foundation. If the Program does not specify a version number of\n"); + printf_filtered ("the license, you may choose any version ever published by the Free Software\n"); + printf_filtered ("Foundation.\n"); + printf_filtered ("\n"); + printf_filtered (" 8. If you wish to incorporate parts of the Program into other free\n"); + printf_filtered ("programs whose distribution conditions are different, write to the author\n"); + printf_filtered ("to ask for permission. For software which is copyrighted by the Free\n"); + printf_filtered ("Software Foundation, write to the Free Software Foundation; we sometimes\n"); + printf_filtered ("make exceptions for this. Our decision will be guided by the two goals\n"); + printf_filtered ("of preserving the free status of all derivatives of our free software and\n"); + printf_filtered ("of promoting the sharing and reuse of software generally.\n"); + printf_filtered ("\n"); + immediate_quit--; +} + +static void +warranty_info () +{ + immediate_quit++; + printf_filtered (" NO WARRANTY\n"); + printf_filtered ("\n"); + printf_filtered (" 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"); + printf_filtered ("FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n"); + printf_filtered ("OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"); + printf_filtered ("PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"); + printf_filtered ("OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"); + printf_filtered ("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n"); + printf_filtered ("TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n"); + printf_filtered ("PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"); + printf_filtered ("REPAIR OR CORRECTION.\n"); + printf_filtered ("\n"); + printf_filtered (" 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"); + printf_filtered ("WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"); + printf_filtered ("REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"); + printf_filtered ("INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"); + printf_filtered ("OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"); + printf_filtered ("TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"); + printf_filtered ("YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"); + printf_filtered ("PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"); + printf_filtered ("POSSIBILITY OF SUCH DAMAGES.\n"); + printf_filtered ("\n"); + immediate_quit--; +} + +void +_initialize_copying () +{ + add_info ("copying", copying_info, + "Conditions for redistributing copies of GDB."); + add_info ("warranty", warranty_info, + "Various kinds of warranty you do not have."); +} diff --git a/gnu/usr.bin/gdb/core.c b/gnu/usr.bin/gdb/core.c new file mode 100644 index 000000000000..307addb54ae1 --- /dev/null +++ b/gnu/usr.bin/gdb/core.c @@ -0,0 +1,581 @@ +/*- + * This code is derived from software copyrighted by the Free Software + * Foundation. + * + * Modified 1991 by Donn Seeley at UUNET Technologies, Inc. + * Modified 1990 by Van Jacobson at Lawrence Berkeley Laboratory. + */ + +#ifndef lint +static char sccsid[] = "@(#)core.c 6.3 (Berkeley) 5/8/91"; +#endif /* not lint */ + +/* Work with core dump and executable files, for GDB. + Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <stdio.h> +#include "defs.h" +#include "param.h" +#include "frame.h" /* required by inferior.h */ +#include "inferior.h" + +#ifdef USG +#include <sys/types.h> +#include <fcntl.h> +#endif + +#ifdef COFF_ENCAPSULATE +#include "a.out.encap.h" +#else +#include <a.out.h> +#endif +#ifndef N_MAGIC +#ifdef COFF_FORMAT +#define N_MAGIC(exec) ((exec).magic) +#else +#define N_MAGIC(exec) ((exec).a_magic) +#endif +#endif +#include <signal.h> +#include <sys/param.h> +#include <sys/dir.h> +#include <sys/file.h> +#include <sys/stat.h> + +#ifdef UMAX_CORE +#include <sys/ptrace.h> +#else +#include <sys/user.h> +#endif + +#ifndef N_TXTADDR +#define N_TXTADDR(hdr) 0 +#endif /* no N_TXTADDR */ + +#ifndef N_DATADDR +#define N_DATADDR(hdr) hdr.a_text +#endif /* no N_DATADDR */ + +#ifndef COFF_FORMAT +#ifndef AOUTHDR +#define AOUTHDR struct exec +#endif +#endif + +extern char *sys_siglist[]; + +extern core_file_command (), exec_file_command (); + +/* Hook for `exec_file_command' command to call. */ + +void (*exec_file_display_hook) (); + +/* File names of core file and executable file. */ + +char *corefile; +char *execfile; + +/* Descriptors on which core file and executable file are open. + Note that the execchan is closed when an inferior is created + and reopened if the inferior dies or is killed. */ + +int corechan; +int execchan; + +/* Last modification time of executable file. + Also used in source.c to compare against mtime of a source file. */ + +int exec_mtime; + +/* Virtual addresses of bounds of the two areas of memory in the core file. */ + +CORE_ADDR data_start; +CORE_ADDR data_end; +CORE_ADDR stack_start; +CORE_ADDR stack_end; + +#if defined (REG_STACK_SEGMENT) +/* Start and end of the register stack segment. */ +CORE_ADDR reg_stack_start; +CORE_ADDR reg_stack_end; +#endif /* REG_STACK_SEGMENT */ + +/* Virtual addresses of bounds of two areas of memory in the exec file. + Note that the data area in the exec file is used only when there is no core file. */ + +CORE_ADDR text_start; +CORE_ADDR text_end; + +CORE_ADDR exec_data_start; +CORE_ADDR exec_data_end; + +/* Offset within executable file of start of text area data. */ + +int text_offset; + +/* Offset within executable file of start of data area data. */ + +int exec_data_offset; + +/* Offset within core file of start of data area data. */ + +int data_offset; + +/* Offset within core file of start of stack area data. */ + +int stack_offset; + +#ifdef COFF_FORMAT +/* various coff data structures */ + +FILHDR file_hdr; +SCNHDR text_hdr; +SCNHDR data_hdr; + +#endif /* not COFF_FORMAT */ + +/* a.out header saved in core file. */ + +AOUTHDR core_aouthdr; + +/* a.out header of exec file. */ + +AOUTHDR exec_aouthdr; + +void validate_files (); +unsigned int register_addr (); + +/* Call this to specify the hook for exec_file_command to call back. + This is called from the x-window display code. */ + +void +specify_exec_file_hook (hook) + void (*hook) (); +{ + exec_file_display_hook = hook; +} + +/* The exec file must be closed before running an inferior. + If it is needed again after the inferior dies, it must + be reopened. */ + +void +close_exec_file () +{ + if (execchan >= 0) + close (execchan); + execchan = -1; +} + +void +reopen_exec_file () +{ + if (execchan < 0 && execfile != 0) + { + char *filename = concat (execfile, "", ""); + exec_file_command (filename, 0); + free (filename); + } +} + +/* If we have both a core file and an exec file, + print a warning if they don't go together. + This should really check that the core file came + from that exec file, but I don't know how to do it. */ + +void +validate_files () +{ + if (execfile != 0 && corefile != 0) + { + struct stat st_core; + + if (fstat (corechan, &st_core) < 0) + /* It might be a good idea to print an error message. + On the other hand, if the user tries to *do* anything with + the core file, (s)he'll find out soon enough. */ + return; + + if (N_MAGIC (core_aouthdr) != 0 + && bcmp (&core_aouthdr, &exec_aouthdr, sizeof core_aouthdr)) + printf ("Warning: core file does not match specified executable file.\n"); + else if (exec_mtime > st_core.st_mtime) { +#ifdef KERNELDEBUG + extern int kernel_debugging; + if (!kernel_debugging) +#endif + printf ("Warning: exec file is newer than core file.\n"); + } + } +} + +/* 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 (err) + int err; +{ + if (err && execfile == 0) + error ("No executable file specified.\n\ +Use the \"exec-file\" and \"symbol-file\" commands."); + return execfile; +} + +int +have_core_file_p () +{ + return corefile != 0; +} + +static void +files_info () +{ + char *symfile; + extern char *get_sym_file (); + + if (execfile) + printf ("Executable file \"%s\".\n", execfile); + else + printf ("No executable file\n"); + if (corefile == 0) + printf ("No core dump file\n"); + else + printf ("Core dump file \"%s\".\n", corefile); + + if (have_inferior_p ()) + printf ("Using the running image of the program, rather than these files.\n"); + + symfile = get_sym_file (); + if (symfile != 0) + printf ("Symbols from \"%s\".\n", symfile); + +#ifdef FILES_INFO_HOOK + if (FILES_INFO_HOOK ()) + return; +#endif + + if (! have_inferior_p ()) + { + if (execfile) + { + printf ("Text segment in executable from 0x%x to 0x%x.\n", + text_start, text_end); + printf ("Data segment in executable from 0x%x to 0x%x.\n", + exec_data_start, exec_data_end); + if (corefile) + printf ("(But since we have a core file, we're using...)\n"); + } + if (corefile) + { + printf ("Data segment in core file from 0x%x to 0x%x.\n", + data_start, data_end); + printf ("Stack segment in core file from 0x%x to 0x%x.\n", + stack_start, stack_end); + } + } +} + +/* Read "memory data" from core file and/or executable file. + Returns zero if successful, 1 if xfer_core_file failed, errno value if + ptrace failed. */ + +int +read_memory (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + if (len == 0) + return 0; + + if (have_inferior_p ()) + { + if (remote_debugging) + return remote_read_inferior_memory (memaddr, myaddr, len); + else + return read_inferior_memory (memaddr, myaddr, len); + } + else + return xfer_core_file (memaddr, myaddr, len); +} + +/* Write LEN bytes of data starting at address MYADDR + into debugged program memory at address MEMADDR. + Returns zero if successful, or an errno value if ptrace failed. */ + +int +write_memory (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + if (have_inferior_p ()) + { + if (remote_debugging) + return remote_write_inferior_memory (memaddr, myaddr, len); + else + return write_inferior_memory (memaddr, myaddr, len); + } + else + error ("Can write memory only when program being debugged is running."); +} + +#ifndef XFER_CORE_FILE +int (*core_file_hook)(); /* hook to handle special core files like + like /dev/mem and crash dumps */ + +/* Read from the program's memory (except for inferior processes). + This function is misnamed, since it only reads, never writes; and + since it will use the core file and/or executable file as necessary. + + It should be extended to write as well as read, FIXME, for patching files. + + Return 0 if address could be read, 1 if not. */ + +int +xfer_core_file (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + register int i; + register int val; + int xferchan; + char **xferfile; + int fileptr; + int returnval = 0; + + if (core_file_hook) + return ((*core_file_hook)(memaddr, myaddr, len)); + + while (len > 0) + { + xferfile = 0; + xferchan = 0; + + /* Determine which file the next bunch of addresses reside in, + and where in the file. Set the file's read/write pointer + to point at the proper place for the desired address + and set xferfile and xferchan for the correct file. + + If desired address is nonexistent, leave them zero. + + i is set to the number of bytes that can be handled + along with the next address. + + We put the most likely tests first for efficiency. */ + + /* Note that if there is no core file + data_start and data_end are equal. */ + if (memaddr >= data_start && memaddr < data_end) + { + i = min (len, data_end - memaddr); + fileptr = memaddr - data_start + data_offset; + xferfile = &corefile; + xferchan = corechan; + } + /* Note that if there is no core file + stack_start and stack_end are equal. */ + else if (memaddr >= stack_start && memaddr < stack_end) + { + i = min (len, stack_end - memaddr); + fileptr = memaddr - stack_start + stack_offset; + xferfile = &corefile; + xferchan = corechan; + } +#ifdef REG_STACK_SEGMENT + /* Pyramids have an extra segment in the virtual address space + for the (control) stack of register-window frames */ + else if (memaddr >= reg_stack_start && memaddr < reg_stack_end) + { + i = min (len, reg_stack_end - memaddr); + fileptr = memaddr - reg_stack_start + reg_stack_offset; + xferfile = &corefile; + xferchan = corechan; + } +#endif /* REG_STACK_SEGMENT */ + + else if (corechan < 0 + && memaddr >= exec_data_start && memaddr < exec_data_end) + { + i = min (len, exec_data_end - memaddr); + fileptr = memaddr - exec_data_start + exec_data_offset; + xferfile = &execfile; + xferchan = execchan; + } + else if (memaddr >= text_start && memaddr < text_end) + { + i = min (len, text_end - memaddr); + fileptr = memaddr - text_start + text_offset; + xferfile = &execfile; + xferchan = execchan; + } + else if (memaddr < text_start) + { + i = min (len, text_start - memaddr); + } + else if (memaddr >= text_end + && memaddr < (corechan >= 0? data_start : exec_data_start)) + { + i = min (len, data_start - memaddr); + } + else if (corechan >= 0 + && memaddr >= data_end && memaddr < stack_start) + { + i = min (len, stack_start - memaddr); + } + else if (corechan < 0 && memaddr >= exec_data_end) + { + /* Since there is nothing at higher addresses than data + (without a core file or an inferior, there is no + stack, set i to do the rest of the operation now. */ + i = len; + } +#ifdef REG_STACK_SEGMENT + else if (memaddr >= reg_stack_end && reg_stack_end != 0) + { + i = min (len, reg_stack_start - memaddr); + } + else if (memaddr >= stack_end && memaddr < reg_stack_start) +#else /* no REG_STACK_SEGMENT. */ + else if (memaddr >= stack_end && stack_end != 0) +#endif /* no REG_STACK_SEGMENT. */ + { + /* Since there is nothing at higher addresses than + the stack, set i to do the rest of the operation now. */ + i = len; + } + else + { + /* Address did not classify into one of the known ranges. + This shouldn't happen; we catch the endpoints. */ + fatal ("Internal: Bad case logic in xfer_core_file."); + } + + /* Now we know which file to use. + Set up its pointer and transfer the data. */ + if (xferfile) + { + if (*xferfile == 0) + if (xferfile == &execfile) + error ("No program file to examine."); + else + error ("No core dump file or running program to examine."); + val = lseek (xferchan, fileptr, 0); + if (val == -1) + perror_with_name (*xferfile); + val = myread (xferchan, myaddr, i); + if (val < 0) + perror_with_name (*xferfile); + } + /* If this address is for nonexistent memory, + read zeros if reading, or do nothing if writing. + Actually, we never right. */ + else + { + bzero (myaddr, i); + returnval = 1; + } + + memaddr += i; + myaddr += i; + len -= i; + } + return returnval; +} +#endif /* XFER_CORE_FILE */ + +/* My replacement for the read system call. + Used like `read' but keeps going if `read' returns too soon. */ + +int +myread (desc, addr, len) + int desc; + char *addr; + int len; +{ + register int val; + int orglen = len; + + while (len > 0) + { + val = read (desc, addr, len); + if (val < 0) + return val; + if (val == 0) + return orglen - len; + len -= val; + addr += val; + } + return orglen; +} + +#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. */ + +unsigned int +register_addr (regno, blockend) + int regno; + int blockend; +{ + int addr; + + if (regno < 0 || regno >= NUM_REGS) + error ("Invalid register number %d.", regno); + + REGISTER_U_ADDR (addr, blockend, regno); + + return addr; +} + +#endif /* REGISTER_U_ADDR */ + +void +_initialize_core() +{ + corechan = -1; + execchan = -1; + corefile = 0; + execfile = 0; + exec_file_display_hook = 0; + + text_start = 0; + text_end = 0; + data_start = 0; + data_end = 0; + exec_data_start = 0; + exec_data_end = 0; + stack_start = STACK_END_ADDR; + stack_end = STACK_END_ADDR; + + add_com ("core-file", class_files, core_file_command, + "Use FILE as core dump for examining memory and registers.\n\ +No arg means have no core file."); + add_com ("exec-file", class_files, exec_file_command, + "Use FILE as program for getting contents of pure memory.\n\ +If FILE cannot be found as specified, your execution directory path\n\ +is searched for a command of that name.\n\ +No arg means have no executable file."); + add_info ("files", files_info, "Names of files being debugged."); +} + diff --git a/gnu/usr.bin/gdb/cplus-dem.c b/gnu/usr.bin/gdb/cplus-dem.c new file mode 100644 index 000000000000..8ea9c8bb55ac --- /dev/null +++ b/gnu/usr.bin/gdb/cplus-dem.c @@ -0,0 +1,996 @@ +/* Demangler for GNU C++ + Copyright (C) 1989 Free Software Foundation, Inc. + written by James Clark (jjc@jclark.uucp) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This is for g++ 1.36.1 (November 6 version). It will probably + require changes for any other version. + + Modified for g++ 1.36.2 (November 18 version). */ + +/* This file exports one function + + char *cplus_demangle (const char *name, int mode) + + If NAME is a mangled function name produced by GNU C++, then + a pointer to a malloced string giving a C++ representation + of the name will be returned; otherwise NULL will be returned. + It is the caller's responsibility to free the string which + is returned. + + If MODE > 0, then ANSI qualifiers such as `const' and `void' are output. + Otherwise they are not. + If MODE >= 0, parameters are emitted; otherwise not. + + For example, + + cplus_demangle ("foo__1Ai", 0) => "A::foo(int)" + cplus_demangle ("foo__1Ai", 1) => "A::foo(int)" + cplus_demangle ("foo__1Ai", -1) => "A::foo" + + cplus_demangle ("foo__1Afe", 0) => "A::foo(float,...)" + cplus_demangle ("foo__1Afe", 1) => "A::foo(float,...)" + cplus_demangle ("foo__1Afe", -1) => "A::foo" + + This file imports xmalloc and xrealloc, which are like malloc and + realloc except that they generate a fatal error if there is no + available memory. */ + +/* #define nounderscore 1 /* define this is names don't start with _ */ + +#include <stdio.h> +#include <ctype.h> + +#ifdef USG +#include <memory.h> +#include <string.h> +#else +#include <strings.h> +#define memcpy(s1, s2, n) bcopy ((s2), (s1), (n)) +#define memcmp(s1, s2, n) bcmp ((s2), (s1), (n)) +#define strchr index +#define strrchr rindex +#endif + +#ifndef __STDC__ +#define const +#endif + +#ifdef __STDC__ +extern char *cplus_demangle (const char *type, int mode); +#else +extern char *cplus_demangle (); +#endif + +#ifdef __STDC__ +extern char *xmalloc (int); +extern char *xrealloc (char *, int); +#else +extern char *xmalloc (); +extern char *xrealloc (); +#endif + +static char **typevec = 0; +static int ntypes = 0; +static int typevec_size = 0; + +static struct { + const char *in; + const char *out; +} optable[] = { + "new", " new", + "delete", " delete", + "ne", "!=", + "eq", "==", + "ge", ">=", + "gt", ">", + "le", "<=", + "lt", "<", + "plus", "+", + "minus", "-", + "mult", "*", + "convert", "+", /* unary + */ + "negate", "-", /* unary - */ + "trunc_mod", "%", + "trunc_div", "/", + "truth_andif", "&&", + "truth_orif", "||", + "truth_not", "!", + "postincrement", "++", + "postdecrement", "--", + "bit_ior", "|", + "bit_xor", "^", + "bit_and", "&", + "bit_not", "~", + "call", "()", + "cond", "?:", + "alshift", "<<", + "arshift", ">>", + "component", "->", + "indirect", "*", + "method_call", "->()", + "addr", "&", /* unary & */ + "array", "[]", + "nop", "", /* for operator= */ +}; + +/* Beware: these aren't '\0' terminated. */ + +typedef struct { + char *b; /* pointer to start of string */ + char *p; /* pointer after last character */ + char *e; /* pointer after end of allocated space */ +} string; + +#ifdef __STDC__ +static void string_need (string *s, int n); +static void string_delete (string *s); +static void string_init (string *s); +static void string_clear (string *s); +static int string_empty (string *s); +static void string_append (string *p, const char *s); +static void string_appends (string *p, string *s); +static void string_appendn (string *p, const char *s, int n); +static void string_prepend (string *p, const char *s); +#if 0 +static void string_prepends (string *p, string *s); +#endif +static void string_prependn (string *p, const char *s, int n); +static int get_count (const char **type, int *count); +static int do_args (const char **type, string *decl, int arg_mode); +static int do_type (const char **type, string *result, int arg_mode); +static int do_arg (const char **type, string *result, int arg_mode); +static void munge_function_name (string *name, int arg_mode); +static void remember_type (const char *type, int len); +#else +static void string_need (); +static void string_delete (); +static void string_init (); +static void string_clear (); +static int string_empty (); +static void string_append (); +static void string_appends (); +static void string_appendn (); +static void string_prepend (); +static void string_prepends (); +static void string_prependn (); +static int get_count (); +static int do_args (); +static int do_type (); +static int do_arg (); +static int do_args (); +static void munge_function_name (); +static void remember_type (); +#endif + +char * +cplus_demangle (type, arg_mode) + const char *type; + int arg_mode; +{ + string decl; + int n; + int success = 0; + int constructor = 0; + int const_flag = 0; + int i; + const char *p; +#ifndef LONGERNAMES + const char *premangle; +#endif + +# define print_ansi_qualifiers (arg_mode > 0) +# define print_arg_types (arg_mode >= 0) + + if (type == NULL || *type == '\0') + return NULL; +#ifndef nounderscore + if (*type++ != '_') + return NULL; +#endif + p = type; + while (*p != '\0' && !(*p == '_' && p[1] == '_')) + p++; + if (*p == '\0') + { + /* destructor */ + if (type[0] == '_' && type[1] == '$' && type[2] == '_') + { + int n = (strlen (type) - 3)*2 + 3 + 2 + 1; + char *tem = (char *) xmalloc (n); + strcpy (tem, type + 3); + strcat (tem, "::~"); + strcat (tem, type + 3); + strcat (tem, "()"); + return tem; + } + /* static data member */ + if (*type != '_' && (p = strchr (type, '$')) != NULL) + { + int n = strlen (type) + 2; + char *tem = (char *) xmalloc (n); + memcpy (tem, type, p - type); + strcpy (tem + (p - type), "::"); + strcpy (tem + (p - type) + 2, p + 1); + return tem; + } + /* virtual table "_vt$" */ + if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == '$') + { + int n = strlen (type + 4) + 14 + 1; + char *tem = (char *) xmalloc (n); + strcpy (tem, type + 4); + strcat (tem, " virtual table"); + return tem; + } + return NULL; + } + + string_init (&decl); + + if (p == type) + { + if (!isdigit (p[2])) + { + string_delete (&decl); + return NULL; + } + constructor = 1; + } + else + { + string_appendn (&decl, type, p - type); + munge_function_name (&decl, arg_mode); + } + p += 2; + +#ifndef LONGERNAMES + premangle = p; +#endif + switch (*p) + { + case 'C': + /* a const member function */ + if (!isdigit (p[1])) + { + string_delete (&decl); + return NULL; + } + p += 1; + const_flag = 1; + /* fall through */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + n = 0; + do + { + n *= 10; + n += *p - '0'; + p += 1; + } + while (isdigit (*p)); + if (strlen (p) < n) + { + string_delete (&decl); + return NULL; + } + if (constructor) + { + string_appendn (&decl, p, n); + string_append (&decl, "::"); + string_appendn (&decl, p, n); + } + else + { + string_prepend (&decl, "::"); + string_prependn (&decl, p, n); + } + p += n; +#ifndef LONGERNAMES + remember_type (premangle, p - premangle); +#endif + success = do_args (&p, &decl, arg_mode); + if (const_flag && print_arg_types) + string_append (&decl, " const"); + break; + case 'F': + p += 1; + success = do_args (&p, &decl, arg_mode); + break; + } + + for (i = 0; i < ntypes; i++) + if (typevec[i] != NULL) + free (typevec[i]); + ntypes = 0; + if (typevec != NULL) + { + free ((char *)typevec); + typevec = NULL; + typevec_size = 0; + } + + if (success) + { + string_appendn (&decl, "", 1); + return decl.b; + } + else + { + string_delete (&decl); + return NULL; + } +} + +static int +get_count (type, count) + const char **type; + int *count; +{ + if (!isdigit (**type)) + return 0; + *count = **type - '0'; + *type += 1; + /* see flush_repeats in cplus-method.c */ + if (isdigit (**type)) + { + const char *p = *type; + int n = *count; + do + { + n *= 10; + n += *p - '0'; + p += 1; + } + while (isdigit (*p)); + if (*p == '_') + { + *type = p + 1; + *count = n; + } + } + return 1; +} + +/* result will be initialised here; it will be freed on failure */ + +static int +do_type (type, result, arg_mode) + const char **type; + string *result; + int arg_mode; +{ + int n; + int done; + int non_empty = 0; + int success; + string decl; + const char *remembered_type; + + string_init (&decl); + string_init (result); + + done = 0; + success = 1; + while (success && !done) + { + int member; + switch (**type) + { + case 'P': + *type += 1; + string_prepend (&decl, "*"); + break; + + case 'R': + *type += 1; + string_prepend (&decl, "&"); + break; + + case 'T': + *type += 1; + if (!get_count (type, &n) || n >= ntypes) + success = 0; + else + { + remembered_type = typevec[n]; + type = &remembered_type; + } + break; + + case 'F': + *type += 1; + if (!string_empty (&decl) && decl.b[0] == '*') + { + string_prepend (&decl, "("); + string_append (&decl, ")"); + } + if (!do_args (type, &decl, arg_mode) || **type != '_') + success = 0; + else + *type += 1; + break; + + case 'M': + case 'O': + { + int constp = 0; + int volatilep = 0; + + member = **type == 'M'; + *type += 1; + if (!isdigit (**type)) + { + success = 0; + break; + } + n = 0; + do + { + n *= 10; + n += **type - '0'; + *type += 1; + } + while (isdigit (**type)); + if (strlen (*type) < n) + { + success = 0; + break; + } + string_append (&decl, ")"); + string_prepend (&decl, "::"); + string_prependn (&decl, *type, n); + string_prepend (&decl, "("); + *type += n; + if (member) + { + if (**type == 'C') + { + *type += 1; + constp = 1; + } + if (**type == 'V') + { + *type += 1; + volatilep = 1; + } + if (*(*type)++ != 'F') + { + success = 0; + break; + } + } + if ((member && !do_args (type, &decl, arg_mode)) || **type != '_') + { + success = 0; + break; + } + *type += 1; + if (! print_ansi_qualifiers) + break; + if (constp) + { + if (non_empty) + string_append (&decl, " "); + else + non_empty = 1; + string_append (&decl, "const"); + } + if (volatilep) + { + if (non_empty) + string_append (&decl, " "); + else + non_empty = 1; + string_append (&decl, "volatile"); + } + break; + } + + case 'C': + if ((*type)[1] == 'P') + { + *type += 1; + if (print_ansi_qualifiers) + { + if (!string_empty (&decl)) + string_prepend (&decl, " "); + string_prepend (&decl, "const"); + } + break; + } + + /* fall through */ + default: + done = 1; + break; + } + } + + done = 0; + non_empty = 0; + while (success && !done) + { + switch (**type) + { + case 'C': + *type += 1; + if (print_ansi_qualifiers) + { + if (non_empty) + string_append (result, " "); + else + non_empty = 1; + string_append (result, "const"); + } + break; + case 'U': + *type += 1; + if (non_empty) + string_append (result, " "); + else + non_empty = 1; + string_append (result, "unsigned"); + break; + case 'V': + *type += 1; + if (print_ansi_qualifiers) + { + if (non_empty) + string_append (result, " "); + else + non_empty = 1; + string_append (result, "volatile"); + } + break; + default: + done = 1; + break; + } + } + + if (success) + switch (**type) + { + case '\0': + case '_': + break; + case 'v': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "void"); + break; + case 'x': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "long long"); + break; + case 'l': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "long"); + break; + case 'i': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "int"); + break; + case 's': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "short"); + break; + case 'c': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "char"); + break; + case 'r': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "long double"); + break; + case 'd': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "double"); + break; + case 'f': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "float"); + break; + case 'G': + *type += 1; + if (!isdigit (**type)) + { + success = 0; + break; + } + /* fall through */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + n = 0; + do + { + n *= 10; + n += **type - '0'; + *type += 1; + } + while (isdigit (**type)); + if (strlen (*type) < n) + { + success = 0; + break; + } + if (non_empty) + string_append (result, " "); + string_appendn (result, *type, n); + *type += n; + break; + default: + success = 0; + break; + } + + if (success) + { + if (!string_empty (&decl)) + { + string_append (result, " "); + string_appends (result, &decl); + } + string_delete (&decl); + return 1; + } + else + { + string_delete (&decl); + string_delete (result); + return 0; + } +} + +/* `result' will be initialised in do_type; it will be freed on failure */ + +static int +do_arg (type, result, arg_mode) + const char **type; + string *result; + int arg_mode; +{ + const char *start = *type; + + if (!do_type (type, result, arg_mode)) + return 0; + remember_type (start, *type - start); + return 1; +} + +static void +remember_type (start, len) + const char *start; + int len; +{ + char *tem; + + if (ntypes >= typevec_size) + { + if (typevec_size == 0) + { + typevec_size = 3; + typevec = (char **) xmalloc (sizeof (char*)*typevec_size); + } + else + { + typevec_size *= 2; + typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size); + } + } + tem = (char *) xmalloc (len + 1); + memcpy (tem, start, len); + tem[len] = '\0'; + typevec[ntypes++] = tem; +} + +/* `decl' must be already initialised, usually non-empty; + it won't be freed on failure */ + +static int +do_args (type, decl, arg_mode) + const char **type; + string *decl; + int arg_mode; +{ + string arg; + int need_comma = 0; + + if (print_arg_types) + string_append (decl, "("); + + while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v') + { + if (**type == 'N') + { + int r; + int t; + *type += 1; + if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes) + return 0; + while (--r >= 0) + { + const char *tem = typevec[t]; + if (need_comma && print_arg_types) + string_append (decl, ", "); + if (!do_arg (&tem, &arg, arg_mode)) + return 0; + if (print_arg_types) + string_appends (decl, &arg); + string_delete (&arg); + need_comma = 1; + } + } + else + { + if (need_comma & print_arg_types) + string_append (decl, ", "); + if (!do_arg (type, &arg, arg_mode)) + return 0; + if (print_arg_types) + string_appends (decl, &arg); + string_delete (&arg); + need_comma = 1; + } + } + + if (**type == 'v') + *type += 1; + else if (**type == 'e') + { + *type += 1; + if (print_arg_types) + { + if (need_comma) + string_append (decl, ","); + string_append (decl, "..."); + } + } + + if (print_arg_types) + string_append (decl, ")"); + return 1; +} + +static void +munge_function_name (name, arg_mode) + string *name; + int arg_mode; +{ + if (!string_empty (name) && name->p - name->b >= 3 + && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == '$') + { + int i; + /* see if it's an assignment expression */ + if (name->p - name->b >= 10 /* op$assign_ */ + && memcmp (name->b + 3, "assign_", 7) == 0) + { + for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++) + { + int len = name->p - name->b - 10; + if (strlen (optable[i].in) == len + && memcmp (optable[i].in, name->b + 10, len) == 0) + { + string_clear (name); + string_append (name, "operator"); + string_append (name, optable[i].out); + string_append (name, "="); + return; + } + } + } + else + { + for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++) + { + int len = name->p - name->b - 3; + if (strlen (optable[i].in) == len + && memcmp (optable[i].in, name->b + 3, len) == 0) + { + string_clear (name); + string_append (name, "operator"); + string_append (name, optable[i].out); + return; + } + } + } + return; + } + else if (!string_empty (name) && name->p - name->b >= 5 + && memcmp (name->b, "type$", 5) == 0) + { + /* type conversion operator */ + string type; + const char *tem = name->b + 5; + if (do_type (&tem, &type, arg_mode)) + { + string_clear (name); + string_append (name, "operator "); + string_appends (name, &type); + string_delete (&type); + return; + } + } +} + +/* a mini string-handling package */ + +static void +string_need (s, n) + string *s; + int n; +{ + if (s->b == NULL) + { + if (n < 32) + n = 32; + s->p = s->b = (char *) xmalloc (n); + s->e = s->b + n; + } + else if (s->e - s->p < n) + { + int tem = s->p - s->b; + n += tem; + n *= 2; + s->b = (char *) xrealloc (s->b, n); + s->p = s->b + tem; + s->e = s->b + n; + } +} + +static void +string_delete (s) + string *s; +{ + if (s->b != NULL) + { + free (s->b); + s->b = s->e = s->p = NULL; + } +} + +static void +string_init (s) + string *s; +{ + s->b = s->p = s->e = NULL; +} + +static void +string_clear (s) + string *s; +{ + s->p = s->b; +} + +static int +string_empty (s) + string *s; +{ + return s->b == s->p; +} + +static void +string_append (p, s) + string *p; + const char *s; +{ + int n; + if (s == NULL || *s == '\0') + return; + n = strlen (s); + string_need (p, n); + memcpy (p->p, s, n); + p->p += n; +} + +static void +string_appends (p, s) + string *p, *s; +{ + int n; + if (s->b == s->p) + return; + n = s->p - s->b; + string_need (p, n); + memcpy (p->p, s->b, n); + p->p += n; +} + +static void +string_appendn (p, s, n) + string *p; + const char *s; + int n; +{ + if (n == 0) + return; + string_need (p, n); + memcpy (p->p, s, n); + p->p += n; +} + +static void +string_prepend (p, s) + string *p; + const char *s; +{ + if (s == NULL || *s == '\0') + return; + string_prependn (p, s, strlen (s)); +} + +#if 0 +static void +string_prepends (p, s) + string *p, *s; +{ + if (s->b == s->p) + return; + string_prependn (p, s->b, s->p - s->b); +} +#endif + +static void +string_prependn (p, s, n) + string *p; + const char *s; + int n; +{ + char *q; + + if (n == 0) + return; + string_need (p, n); + for (q = p->p - 1; q >= p->b; q--) + q[n] = q[0]; + memcpy (p->b, s, n); + p->p += n; +} diff --git a/gnu/usr.bin/gdb/dbxread.c b/gnu/usr.bin/gdb/dbxread.c new file mode 100644 index 000000000000..7a25665536a4 --- /dev/null +++ b/gnu/usr.bin/gdb/dbxread.c @@ -0,0 +1,5727 @@ +/*- + * This code is derived from software copyrighted by the Free Software + * Foundation. + * + * Modified 1991 by Donn Seeley at UUNET Technologies, Inc. + * Modified 1990 by Van Jacobson at Lawrence Berkeley Laboratory. + */ + +#ifndef lint +static char sccsid[] = "@(#)dbxread.c 6.3 (Berkeley) 5/8/91"; +#endif /* not lint */ + +/* Read dbx symbol tables and convert to internal format, for GDB. + Copyright (C) 1986, 1987, 1988, 1989 Free Software Foundation, Inc. + +This file is part of GDB. + +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Symbol read-in occurs in two phases: + 1. A scan (read_dbx_symtab()) of the entire executable, whose sole + purpose is to make a list of symbols (partial symbol table) + which will cause symbols + to be read in if referenced. This scan happens when the + "symbol-file" command is given (symbol_file_command()). + 2. Full read-in of symbols. (psymtab_to_symtab()). This happens + when a symbol in a file for which symbols have not yet been + read in is referenced. + 2a. The "add-file" command. Similar to #2. */ + +#include <stdio.h> +#include "defs.h" +#include "param.h" + +#ifdef READ_DBX_FORMAT + +#ifdef USG +#include <sys/types.h> +#include <fcntl.h> +#define L_SET 0 +#define L_INCR 1 +#endif + +#ifdef COFF_ENCAPSULATE +#include "a.out.encap.h" +#include "stab.gnu.h" +#else +#include <a.out.h> +#include <stab.h> +#endif +#include <ctype.h> + +#ifndef NO_GNU_STABS +/* + * Define specifically gnu symbols here. + */ + +/* The following type indicates the definition of a symbol as being + an indirect reference to another symbol. The other symbol + appears as an undefined reference, immediately following this symbol. + + Indirection is asymmetrical. The other symbol's value will be used + to satisfy requests for the indirect symbol, but not vice versa. + If the other symbol does not have a definition, libraries will + be searched to find a definition. */ +#ifndef N_INDR +#define N_INDR 0xa +#endif + +/* The following symbols refer to set elements. + All the N_SET[ATDB] symbols with the same name form one set. + Space is allocated for the set in the text section, and each set + element's value is stored into one word of the space. + The first word of the space is the length of the set (number of elements). + + The address of the set is made into an N_SETV symbol + whose name is the same as the name of the set. + This symbol acts like a N_DATA global symbol + in that it can satisfy undefined external references. */ + +#ifndef N_SETA +#define N_SETA 0x14 /* Absolute set element symbol */ +#endif /* This is input to LD, in a .o file. */ + +#ifndef N_SETT +#define N_SETT 0x16 /* Text set element symbol */ +#endif /* This is input to LD, in a .o file. */ + +#ifndef N_SETD +#define N_SETD 0x18 /* Data set element symbol */ +#endif /* This is input to LD, in a .o file. */ + +#ifndef N_SETB +#define N_SETB 0x1A /* Bss set element symbol */ +#endif /* This is input to LD, in a .o file. */ + +/* Macros dealing with the set element symbols defined in a.out.h */ +#define SET_ELEMENT_P(x) ((x)>=N_SETA&&(x)<=(N_SETB|N_EXT)) +#define TYPE_OF_SET_ELEMENT(x) ((x)-N_SETA+N_ABS) + +#ifndef N_SETV +#define N_SETV 0x1C /* Pointer to set vector in data area. */ +#endif /* This is output from LD. */ + +#ifndef N_WARNING +#define N_WARNING 0x1E /* Warning message to print if file included */ +#endif /* This is input to ld */ + +#ifndef __GNU_STAB__ + +/* Line number for the data section. This is to be used to describe + the source location of a variable declaration. */ +#ifndef N_DSLINE +#define N_DSLINE (N_SLINE+N_DATA-N_TEXT) +#endif + +/* Line number for the bss section. This is to be used to describe + the source location of a variable declaration. */ +#ifndef N_BSLINE +#define N_BSLINE (N_SLINE+N_BSS-N_TEXT) +#endif + +#endif /* not __GNU_STAB__ */ +#endif /* NO_GNU_STABS */ + +#include <obstack.h> +#include <sys/param.h> +#include <sys/file.h> +#include <sys/stat.h> + +#include "symtab.h" + +#ifndef COFF_FORMAT +#ifndef AOUTHDR +#define AOUTHDR struct exec +#endif +#endif + +static void add_symbol_to_list (); +static void read_dbx_symtab (); +static void process_one_symbol (); +static void free_all_psymbols (); +static struct type *read_type (); +static struct type *read_range_type (); +static struct type *read_enum_type (); +static struct type *read_struct_type (); +static struct type *read_array_type (); +static long read_number (); +static void read_huge_number (); +static void finish_block (); +static struct blockvector *make_blockvector (); +static struct symbol *define_symbol (); +static void start_subfile (); +static int hashname (); +static void hash_symsegs (); +static struct pending *copy_pending (); +static void fix_common_block (); + +static void add_undefined_type (); +static void cleanup_undefined_types (); + +extern char *index(); + +extern struct symtab *read_symsegs (); +extern void free_all_symtabs (); +extern void free_all_psymtabs (); +extern void free_inclink_symtabs (); + +/* C++ */ +static struct type **read_args (); + +/* Macro to determine which symbols to ignore when reading the first symbol + of a file. Some machines override this definition. */ +#ifdef N_NSYMS +#ifndef IGNORE_SYMBOL +/* This code is used on Ultrix systems. Ignore it */ +#define IGNORE_SYMBOL(type) (type == N_NSYMS) +#endif +#else +#ifndef IGNORE_SYMBOL +/* Don't ignore any symbols. */ +#define IGNORE_SYMBOL(type) (0) +#endif +#endif /* not N_NSYMS */ + +/* Macro for number of symbol table entries (in usual a.out format). + Some machines override this definition. */ +#ifndef NUMBER_OF_SYMBOLS +#ifdef COFF_HEADER +#define NUMBER_OF_SYMBOLS \ + ((COFF_HEADER(hdr) ? hdr.coffhdr.filehdr.f_nsyms : hdr.a_syms) / \ + sizeof (struct nlist)) +#else +#define NUMBER_OF_SYMBOLS (hdr.a_syms / sizeof (struct nlist)) +#endif +#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 AOUTHDR 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 +#ifdef HEADER_SEEK_FD +#define READ_FILE_HEADERS(DESC, NAME) \ +{ HEADER_SEEK_FD (DESC); \ + 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); } +#else +#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 +#endif + +/* Non-zero if this is an object (.o) file, rather than an executable. + Distinguishing between the two is rarely necessary (and seems like + a hack, but there is no other way to do ADDR_OF_TEXT_SEGMENT + right for SunOS). */ +#if !defined (IS_OBJECT_FILE) +/* This will not work + if someone decides to make ld preserve relocation info. */ +#define IS_OBJECT_FILE (hdr.a_trsize != 0) +#endif + +/* Macro for size of text segment */ +#ifndef SIZE_OF_TEXT_SEGMENT +#define SIZE_OF_TEXT_SEGMENT hdr.a_text +#endif + +/* Get the address in debugged memory of the start + of the text segment. */ +#if !defined (ADDR_OF_TEXT_SEGMENT) +#if defined (N_TXTADDR) +#define ADDR_OF_TEXT_SEGMENT (IS_OBJECT_FILE ? 0 : N_TXTADDR (hdr)) +#else /* no N_TXTADDR */ +#define ADDR_OF_TEXT_SEGMENT 0 +#endif /* no N_TXTADDR */ +#endif /* no ADDR_OF_TEXT_SEGMENT */ + +/* Macro to get entry point from headers. */ +#ifndef ENTRY_POINT +#define ENTRY_POINT hdr.a_entry +#endif + +/* Macro for name of symbol to indicate a file compiled with gcc. */ +#ifndef GCC_COMPILED_FLAG_SYMBOL +#define GCC_COMPILED_FLAG_SYMBOL "gcc_compiled." +#endif + +/* Convert stab register number (from `r' declaration) to a gdb REGNUM. */ + +#ifndef STAB_REG_TO_REGNUM +#define STAB_REG_TO_REGNUM(VALUE) (VALUE) +#endif + +/* Define this as 1 if a pcc declaration of a char or short argument + gives the correct address. Otherwise assume pcc gives the + address of the corresponding int, which is not the same on a + big-endian machine. */ + +#ifndef BELIEVE_PCC_PROMOTION +#define BELIEVE_PCC_PROMOTION 0 +#endif + +/* Nonzero means give verbose info on gdb action. From main.c. */ +extern int info_verbose; + +/* Chain of symtabs made from reading the file's symsegs. + These symtabs do not go into symtab_list themselves, + but the information is copied from them when appropriate + to make the symtabs that will exist permanently. */ + +static struct symtab *symseg_chain; + +/* Symseg symbol table for the file whose data we are now processing. + It is one of those in symseg_chain. Or 0, for a compilation that + has no symseg. */ + +static struct symtab *current_symseg; + +/* Name of source file whose symbol data we are now processing. + This comes from a symbol of type N_SO. */ + +static char *last_source_file; + +/* Core address of start of text of current source file. + This too comes from the N_SO symbol. */ + +static CORE_ADDR last_source_start_addr; + +/* End of the text segment of the executable file, + as found in the symbol _etext. */ + +static CORE_ADDR end_of_text_addr; + +/* The list of sub-source-files within the current individual compilation. + Each file gets its own symtab with its own linetable and associated info, + but they all share one blockvector. */ + +struct subfile +{ + struct subfile *next; + char *name; + struct linetable *line_vector; + int line_vector_length; + int line_vector_index; + int prev_line_number; +}; + +static struct subfile *subfiles; + +static struct subfile *current_subfile; + +/* Count symbols as they are processed, for error messages. */ + +static int symnum; + +/* Vector of types defined so far, indexed by their dbx type numbers. + (In newer sun systems, dbx uses a pair of numbers in parens, + as in "(SUBFILENUM,NUMWITHINSUBFILE)". Then these numbers must be + translated through the type_translations hash table to get + the index into the type vector.) */ + +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; + +/* 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. */ +/* The use of the LOC_BLOCK code in this chain is nonstandard-- + it refers to a FORTRAN common block rather than the usual meaning. */ + +#define HASHSIZE 127 +static struct symbol *global_sym_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. */ + +#define PENDINGSIZE 100 + +struct pending +{ + struct pending *next; + 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 */ + +struct pending *global_symbols; /* global functions and variables */ + +struct pending *local_symbols; /* everything local to lexical context */ + +/* List of symbols declared since the last BCOMM. This list is a tail + of local_symbols. When ECOMM is seen, the symbols on the list + are noted so their proper addresses can be filled in later, + using the common block base address gotten from the assembler + stabs. */ + +struct pending *common_block; +int common_block_i; + +/* Stack representing unclosed lexical contexts + (that will become blocks, eventually). */ + +struct context_stack +{ + struct pending *locals; + struct pending_block *old_blocks; + struct symbol *name; + CORE_ADDR start_addr; + int depth; +}; + +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). */ + +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 startup_file_start; /* From blockframe.c */ +extern CORE_ADDR startup_file_end; /* From blockframe.c */ + +/* File name symbols were loaded from. */ + +static char *symfile; + +/* Low and high symbol values (inclusive) for the global variable + entries in the symbol file. */ + +static int first_global_sym, last_global_sym; + +/* Structures with which to manage partial symbol allocation. */ + +struct psymbol_allocation_list global_psymbols, static_psymbols; + +/* Global variable which, when set, indicates that we are processing a + .o file compiled with gcc */ + +static unsigned char processing_gcc_compilation; + +/* Make a list of forward references which haven't been defined. */ +static struct type **undef_types; +static int undef_types_allocated, undef_types_length; + + /* Setup a define to deal cleanly with the underscore problem */ + +#ifdef NAMES_HAVE_UNDERSCORE +#define HASH_OFFSET 1 +#else +#define HASH_OFFSET 0 +#endif + +#if 0 +/* I'm not sure why this is here. To debug bugs which cause + an infinite loop of allocations, I suppose. In any event, + dumping core when out of memory isn't usually right. */ +static int +xxmalloc (n) +{ + int v = malloc (n); + if (v == 0) + { + fprintf (stderr, "Virtual memory exhausted.\n"); + abort (); + } + return v; +} +#else /* not 0 */ +#define xxmalloc xmalloc +#endif /* not 0 */ + +/* 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 */ + +/* For each identified header file, we have a table of types defined + in that header file. + + header_files maps header file names to their type tables. + It is a vector of n_header_files elements. + Each element describes one header file. + It contains a vector of types. + + Sometimes it can happen that the same header file produces + different results when included in different places. + This can result from conditionals or from different + things done before including the file. + When this happens, there are multiple entries for the file in this table, + one entry for each distinct set of results. + The entries are distinguished by the INSTANCE field. + The INSTANCE field appears in the N_BINCL and N_EXCL symbol table and is + used to match header-file references to their corresponding data. */ + +struct header_file +{ + char *name; /* Name of header file */ + int instance; /* Numeric code distinguishing instances + of one header file that produced + different results when included. + It comes from the N_BINCL or N_EXCL. */ + struct type **vector; /* Pointer to vector of types */ + int length; /* Allocated length (# elts) of that vector */ +}; + +static struct header_file *header_files; + +static int n_header_files; + +static int n_allocated_header_files; + +/* During initial symbol readin, we need to have a structure to keep + track of which psymtabs have which bincls in them. This structure + is used during readin to setup the list of dependencies within each + partial symbol table. */ + +struct header_file_location +{ + char *name; /* Name of header file */ + int instance; /* See above */ + struct partial_symtab *pst; /* Partial symtab that has the + BINCL/EINCL defs for this file */ +}; + +/* The actual list and controling variables */ +static struct header_file_location *bincl_list, *next_bincl; +static int bincls_allocated; + +/* Within each object file, various header files are assigned numbers. + A type is defined or referred to with a pair of numbers + (FILENUM,TYPENUM) where FILENUM is the number of the header file + and TYPENUM is the number within that header file. + TYPENUM is the index within the vector of types for that header file. + + FILENUM == 1 is special; it refers to the main source of the object file, + and not to any header file. FILENUM != 1 is interpreted by looking it up + in the following table, which contains indices in header_files. */ + +static int *this_object_header_files; + +static int n_this_object_header_files; + +static int n_allocated_this_object_header_files; + +/* When a header file is getting special overriding definitions + for one source file, record here the header_files index + of its normal definition vector. + At other times, this is -1. */ + +static int header_file_prev_index; + +/* At the start of reading dbx symbols, allocate our tables. */ + +static void +init_header_files () +{ + n_allocated_header_files = 10; + 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 *) xxmalloc (10 * sizeof (int)); +} + +/* At the end of reading dbx symbols, free our tables. */ + +static void +free_header_files () +{ + register int i; + for (i = 0; i < n_header_files; i++) + free (header_files[i].name); + if (header_files) free (header_files); + if (this_object_header_files) + free (this_object_header_files); +} + +/* Called at the start of each object file's symbols. + Clear out the mapping of header file numbers to header files. */ + +static void +new_object_header_files () +{ + /* Leave FILENUM of 0 free for builtin types and this file's types. */ + n_this_object_header_files = 1; + header_file_prev_index = -1; +} + +/* Add header file number I for this object file + at the next successive FILENUM. */ + +static void +add_this_object_header_file (i) + int i; +{ + if (n_this_object_header_files == n_allocated_this_object_header_files) + { + n_allocated_this_object_header_files *= 2; + this_object_header_files + = (int *) xrealloc (this_object_header_files, + n_allocated_this_object_header_files * sizeof (int)); + } + + this_object_header_files[n_this_object_header_files++] = i; +} + +/* Add to this file an "old" header file, one already seen in + a previous object file. NAME is the header file's name. + INSTANCE is its instance code, to select among multiple + symbol tables for the same header file. */ + +static void +add_old_header_file (name, instance) + char *name; + int instance; +{ + register struct header_file *p = header_files; + register int i; + + for (i = 0; i < n_header_files; i++) + if (!strcmp (p[i].name, name) && instance == p[i].instance) + { + add_this_object_header_file (i); + return; + } + error ("Invalid symbol data: \"repeated\" header file that hasn't been seen before, at symtab pos %d.", + symnum); +} + +/* Add to this file a "new" header file: definitions for its types follow. + NAME is the header file's name. + Most often this happens only once for each distinct header file, + but not necessarily. If it happens more than once, INSTANCE has + a different value each time, and references to the header file + use INSTANCE values to select among them. + + dbx output contains "begin" and "end" markers for each new header file, + but at this level we just need to know which files there have been; + so we record the file when its "begin" is seen and ignore the "end". */ + +static void +add_new_header_file (name, instance) + char *name; + int instance; +{ + register int i; + register struct header_file *p = header_files; + header_file_prev_index = -1; + +#if 0 + /* This code was used before I knew about the instance codes. + My first hypothesis is that it is not necessary now + that instance codes are handled. */ + + /* Has this header file a previous definition? + If so, make a new entry anyway so that this use in this source file + gets a separate entry. Later source files get the old entry. + Record here the index of the old entry, so that any type indices + not previously defined can get defined in the old entry as + well as in the new one. */ + + for (i = 0; i < n_header_files; i++) + if (!strcmp (p[i].name, name)) + { + header_file_prev_index = i; + } + +#endif + + /* Make sure there is room for one more header file. */ + + if (n_header_files == n_allocated_header_files) + { + n_allocated_header_files *= 2; + header_files = (struct header_file *) + xrealloc (header_files, + (n_allocated_header_files + * sizeof (struct header_file))); + } + + /* Create an entry for this header file. */ + + i = n_header_files++; + header_files[i].name = savestring (name, strlen(name)); + header_files[i].instance = instance; + header_files[i].length = 10; + header_files[i].vector + = (struct type **) xxmalloc (10 * sizeof (struct type *)); + bzero (header_files[i].vector, 10 * sizeof (struct type *)); + + add_this_object_header_file (i); +} + +/* Look up a dbx type-number pair. Return the address of the slot + where the type for that number-pair is stored. + The number-pair is in TYPENUMS. + + This can be used for finding the type associated with that pair + or for associating a new type with the pair. */ + +static struct type ** +dbx_lookup_type (typenums) + int typenums[2]; +{ + register int filenum = typenums[0], index = typenums[1]; + + if (filenum < 0 || filenum >= n_this_object_header_files) + error ("Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", + filenum, index, symnum); + + if (filenum == 0) + { + /* Type is defined outside of header files. + Find it in this object file's type vector. */ + 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]; + } + else + { + register int real_filenum = this_object_header_files[filenum]; + register struct header_file *f; + + if (real_filenum >= n_header_files) + abort (); + + f = &header_files[real_filenum]; + + if (index >= f->length) + { + f->length *= 2; + f->vector = (struct type **) + xrealloc (f->vector, f->length * sizeof (struct type *)); + bzero (&f->vector[f->length / 2], + f->length * sizeof (struct type *) / 2); + } + return &f->vector[index]; + } +} + +/* Create a type object. Occaisionally used when you need a type + which isn't going to be given a type number. */ + +static struct type * +dbx_create_type () +{ + register struct type *type = + (struct type *) obstack_alloc (symbol_obstack, sizeof (struct type)); + + bzero (type, sizeof (struct type)); + TYPE_VPTR_FIELDNO (type) = -1; + return type; +} + +/* Make sure there is a type allocated for type numbers TYPENUMS + and return the type object. + This can create an empty (zeroed) type object. + TYPENUMS may be (-1, -1) to return a new type object that is not + put into the type vector, and so may not be referred to by number. */ + +static struct type * +dbx_alloc_type (typenums) + int typenums[2]; +{ + register struct type **type_addr; + register struct type *type; + + if (typenums[1] != -1) + { + type_addr = dbx_lookup_type (typenums); + type = *type_addr; + } + else + { + type_addr = 0; + type = 0; + } + + /* 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 = dbx_create_type (); + if (type_addr) + *type_addr = type; + } + + return type; +} + +#if 0 +static struct type ** +explicit_lookup_type (real_filenum, index) + int real_filenum, index; +{ + register struct header_file *f = &header_files[real_filenum]; + + if (index >= f->length) + { + f->length *= 2; + f->vector = (struct type **) + xrealloc (f->vector, f->length * sizeof (struct type *)); + bzero (&f->vector[f->length / 2], + f->length * sizeof (struct type *) / 2); + } + return &f->vector[index]; +} +#endif + +/* 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; +{ + /* 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; + *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 +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; i += next->nsyms, next = next->next); + + 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) + { + 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; + BLOCK_SUPERBLOCK (block) = 0; /* Filled in when containing block is made */ + BLOCK_GCC_COMPILED (block) = processing_gcc_compilation; + + /* 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; + next->next = free_pendings; + free_pendings = 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. */ + + /* 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) + { + 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; + +#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) + { + next1 = next->next; + free (next); + } +#endif + pending_blocks = 0; + + return blockvector; +} + +/* Manage the vector of line numbers. */ + +static void +record_line (line, pc) + int line; + CORE_ADDR pc; +{ + struct linetable_entry *e; + /* Ignore the dummy line number in libg.o */ + + if (line == 0xffff) + return; + + /* Make sure line vector is big enough. */ + + if (line_vector_index + 1 >= line_vector_length) + { + line_vector_length *= 2; + line_vector = (struct linetable *) + xrealloc (line_vector, + (sizeof (struct linetable) + + line_vector_length * sizeof (struct linetable_entry))); + current_subfile->line_vector = line_vector; + } + + e = line_vector->item + line_vector_index++; + e->line = line; e->pc = pc; +} + +/* Start a new symtab for a new source file. + This is called when a dbx symbol of type N_SO is seen; + it indicates the start of data for one original source file. */ + +static void +start_symtab (name, start_addr) + char *name; + CORE_ADDR start_addr; +{ + register struct symtab *s; + + last_source_file = name; + last_source_start_addr = start_addr; + file_symbols = 0; + global_symbols = 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) + if (s->ldsymoff == symnum * sizeof (struct nlist)) + break; + current_symseg = s; + if (s != 0) + return; + + type_vector_length = 160; + 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 + for this file (the top-level source file). */ + + subfiles = 0; + current_subfile = 0; + start_subfile (name); + +#if 0 /* This is now set at the beginning of read_ofile_symtab */ + /* Set default for compiler to pcc; assume that we aren't processing + a gcc compiled file until proved otherwise. */ + + processing_gcc_compilation = 0; +#endif +} + +/* Handle an N_SOL symbol, which indicates the start of + code that came from an included (or otherwise merged-in) + source file with a different name. */ + +static void +start_subfile (name) + char *name; +{ + register struct subfile *subfile; + + /* Save the current subfile's line vector data. */ + + if (current_subfile) + { + current_subfile->line_vector_index = line_vector_index; + current_subfile->line_vector_length = line_vector_length; + current_subfile->prev_line_number = prev_line_number; + } + + /* See if this subfile is already known as a subfile of the + current main source file. */ + + for (subfile = subfiles; subfile; subfile = subfile->next) + { + if (!strcmp (subfile->name, name)) + { + line_vector = subfile->line_vector; + line_vector_index = subfile->line_vector_index; + line_vector_length = subfile->line_vector_length; + prev_line_number = subfile->prev_line_number; + current_subfile = subfile; + return; + } + } + + /* This subfile is not known. Add an entry for it. */ + + line_vector_index = 0; + line_vector_length = 1000; + prev_line_number = -2; /* Force first line number to be explicit */ + line_vector = (struct linetable *) + xxmalloc (sizeof (struct linetable) + + line_vector_length * sizeof (struct linetable_entry)); + + /* Make an entry for this subfile in the list of all subfiles + of the current main source file. */ + + subfile = (struct subfile *) xxmalloc (sizeof (struct subfile)); + subfile->next = subfiles; + subfile->name = savestring (name, strlen (name)); + subfile->line_vector = line_vector; + subfiles = subfile; + current_subfile = subfile; +} + +/* 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. + + END_ADDR is the address of the end of the file's text. */ + +static void +end_symtab (end_addr) + CORE_ADDR end_addr; +{ + register struct symtab *symtab; + register struct blockvector *blockvector; + register struct subfile *subfile; + register struct linetable *lv; + struct subfile *nextsub; + + if (current_symseg != 0) + { + last_source_file = 0; + current_symseg = 0; + return; + } + + /* Finish the lexical context of the last function in the file; + pop the context stack. */ + + if (context_stack_depth > 0) + { + 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); + } + + /* Cleanup any undefined types that have been left hanging around + (this needs to be done before the finish_blocks so that + file_symbols is still good). */ + cleanup_undefined_types (); + + /* Finish defining all the blocks of this symtab. */ + finish_block (0, &file_symbols, 0, last_source_start_addr, end_addr); + finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr); + blockvector = make_blockvector (); + + current_subfile->line_vector_index = line_vector_index; + + /* Now create the symtab objects proper, one for each subfile. */ + /* (The main file is one of them.) */ + + for (subfile = subfiles; subfile; subfile = nextsub) + { + symtab = (struct symtab *) xxmalloc (sizeof (struct symtab)); + symtab->free_ptr = 0; + + /* Fill in its components. */ + symtab->blockvector = blockvector; + type_vector->length = type_vector_length; + symtab->typevector = type_vector; + symtab->free_code = free_linetable; + if (subfile->next == 0) + symtab->free_ptr = (char *) type_vector; + + symtab->filename = subfile->name; + lv = subfile->line_vector; + lv->nitems = subfile->line_vector_index; + symtab->linetable = (struct linetable *) + xrealloc (lv, (sizeof (struct linetable) + + lv->nitems * sizeof (struct linetable_entry))); + symtab->nlines = 0; + symtab->line_charpos = 0; + + /* Link the new symtab into the list of such. */ + symtab->next = symtab_list; + symtab_list = symtab; + + nextsub = subfile->next; + free (subfile); + } + + type_vector = 0; + type_vector_length = -1; + line_vector = 0; + line_vector_length = -1; + last_source_file = 0; +} + +#ifdef N_BINCL + +/* Handle the N_BINCL and N_EINCL symbol types + that act like N_SOL for switching source files + (different subfiles, as we call them) within one object file, + but using a stack rather than in an arbitrary order. */ + +struct subfile_stack +{ + struct subfile_stack *next; + char *name; + int prev_index; +}; + +struct subfile_stack *subfile_stack; + +static void +push_subfile () +{ + register struct subfile_stack *tem + = (struct subfile_stack *) xxmalloc (sizeof (struct subfile_stack)); + + tem->next = subfile_stack; + subfile_stack = tem; + if (current_subfile == 0 || current_subfile->name == 0) + abort (); + tem->name = current_subfile->name; + tem->prev_index = header_file_prev_index; +} + +static char * +pop_subfile () +{ + register char *name; + register struct subfile_stack *link = subfile_stack; + + if (link == 0) + abort (); + + name = link->name; + subfile_stack = link->next; + header_file_prev_index = link->prev_index; + free (link); + + return name; +} +#endif /* Have N_BINCL */ + +/* 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, type) + char *name; + CORE_ADDR address; + int type; +{ + register struct misc_bunch *new; + register unsigned char mtype; + + if (misc_bunch_index == MISC_BUNCH_SIZE) + { + new = (struct misc_bunch *) xxmalloc (sizeof (struct misc_bunch)); + misc_bunch_index = 0; + new->next = misc_bunch; + misc_bunch = new; + } + misc_bunch->contents[misc_bunch_index].name = name; + misc_bunch->contents[misc_bunch_index].address = address; + switch (type &~ N_EXT) + { + case N_TEXT: mtype = mf_text; break; + case N_DATA: mtype = mf_data; break; + case N_BSS: mtype = mf_bss; break; + case N_ABS: mtype = mf_abs; break; +#ifdef N_SETV + case N_SETV: mtype = mf_data; break; +#endif + default: mtype = mf_unknown; break; + } + misc_bunch->contents[misc_bunch_index].type = mtype; + 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; + } +} + +/* INCLINK nonzero means bunches are from an incrementally-linked file. + Add them to the existing bunches. |