1 /*-------------------------------------------------------------------------
2 cmd.c - source file for debugger command execution
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
32 EXTERN_STACK_DCL(callStack,function *,1024);
35 " GNU GENERAL PUBLIC LICENSE
38 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
39 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
40 Everyone is permitted to copy and distribute verbatim copies
41 of this license document, but changing it is not allowed.
45 The licenses for most software are designed to take away your
46 freedom to share and change it. By contrast, the GNU General Public
47 License is intended to guarantee your freedom to share and change free
48 software--to make sure the software is free for all its users. This
49 General Public License applies to most of the Free Software
50 Foundation's software and to any other program whose authors commit to
51 using it. (Some other Free Software Foundation software is covered by
52 the GNU Library General Public License instead.) You can apply it to
55 When we speak of free software, we are referring to freedom, not
56 price. Our General Public Licenses are designed to make sure that you
57 have the freedom to distribute copies of free software (and charge for
58 this service if you wish), that you receive source code or can get it
59 if you want it, that you can change the software or use pieces of it
60 in new free programs; and that you know you can do these things.
62 To protect your rights, we need to make restrictions that forbid
63 anyone to deny you these rights or to ask you to surrender the rights.
64 These restrictions translate to certain responsibilities for you if you
65 distribute copies of the software, or if you modify it.
67 For example, if you distribute copies of such a program, whether
68 gratis or for a fee, you must give the recipients all the rights that
69 you have. You must make sure that they, too, receive or can get the
70 source code. And you must show them these terms so they know their
73 We protect your rights with two steps: (1) copyright the software, and
74 (2) offer you this license which gives you legal permission to copy,
75 distribute and/or modify the software.
77 Also, for each author's protection and ours, we want to make certain
78 that everyone understands that there is no warranty for this free
79 software. If the software is modified by someone else and passed on, we
80 want its recipients to know that what they have is not the original, so
81 that any problems introduced by others will not reflect on the original
84 Finally, any free program is threatened constantly by software
85 patents. We wish to avoid the danger that redistributors of a free
86 program will individually obtain patent licenses, in effect making the
87 program proprietary. To prevent this, we have made it clear that any
88 patent must be licensed for everyone's free use or not licensed at all.
90 The precise terms and conditions for copying, distribution and
93 GNU GENERAL PUBLIC LICENSE
94 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
96 0. This License applies to any program or other work which contains
97 a notice placed by the copyright holder saying it may be distributed
98 under the terms of this General Public License. The \"Program\", below,
99 refers to any such program or work, and a \"work based on the Program\"
100 means either the Program or any derivative work under copyright law:
101 that is to say, a work containing the Program or a portion of it,
102 either verbatim or with modifications and/or translated into another
103 language. (Hereinafter, translation is included without limitation in
104 the term \"modification\".) Each licensee is addressed as \"you\".
106 Activities other than copying, distribution and modification are not
107 covered by this License; they are outside its scope. The act of
108 running the Program is not restricted, and the output from the Program
109 is covered only if its contents constitute a work based on the
110 Program (independent of having been made by running the Program).
111 Whether that is true depends on what the Program does.
113 1. You may copy and distribute verbatim copies of the Program's
114 source code as you receive it, in any medium, provided that you
115 conspicuously and appropriately publish on each copy an appropriate
116 copyright notice and disclaimer of warranty; keep intact all the
117 notices that refer to this License and to the absence of any warranty;
118 and give any other recipients of the Program a copy of this License
119 along with the Program.
121 You may charge a fee for the physical act of transferring a copy, and
122 you may at your option offer warranty protection in exchange for a fee.
124 2. You may modify your copy or copies of the Program or any portion
125 of it, thus forming a work based on the Program, and copy and
126 distribute such modifications or work under the terms of Section 1
127 above, provided that you also meet all of these conditions:
129 a) You must cause the modified files to carry prominent notices
130 stating that you changed the files and the date of any change.
132 b) You must cause any work that you distribute or publish, that in
133 whole or in part contains or is derived from the Program or any
134 part thereof, to be licensed as a whole at no charge to all third
135 parties under the terms of this License.
137 c) If the modified program normally reads commands interactively
138 when run, you must cause it, when started running for such
139 interactive use in the most ordinary way, to print or display an
140 announcement including an appropriate copyright notice and a
141 notice that there is no warranty (or else, saying that you provide
142 a warranty) and that users may redistribute the program under
143 these conditions, and telling the user how to view a copy of this
144 License. (Exception: if the Program itself is interactive but
145 does not normally print such an announcement, your work based on
146 the Program is not required to print an announcement.)
148 These requirements apply to the modified work as a whole. If
149 identifiable sections of that work are not derived from the Program,
150 and can be reasonably considered independent and separate works in
151 themselves, then this License, and its terms, do not apply to those
152 sections when you distribute them as separate works. But when you
153 distribute the same sections as part of a whole which is a work based
154 on the Program, the distribution of the whole must be on the terms of
155 this License, whose permissions for other licensees extend to the
156 entire whole, and thus to each and every part regardless of who wrote it.
158 Thus, it is not the intent of this section to claim rights or contest
159 your rights to work written entirely by you; rather, the intent is to
160 exercise the right to control the distribution of derivative or
161 collective works based on the Program.
163 In addition, mere aggregation of another work not based on the Program
164 with the Program (or with a work based on the Program) on a volume of
165 a storage or distribution medium does not bring the other work under
166 the scope of this License.
168 3. You may copy and distribute the Program (or a work based on it,
169 under Section 2) in object code or executable form under the terms of
170 Sections 1 and 2 above provided that you also do one of the following:
172 a) Accompany it with the complete corresponding machine-readable
173 source code, which must be distributed under the terms of Sections
174 1 and 2 above on a medium customarily used for software interchange; or,
176 b) Accompany it with a written offer, valid for at least three
177 years, to give any third party, for a charge no more than your
178 cost of physically performing source distribution, a complete
179 machine-readable copy of the corresponding source code, to be
180 distributed under the terms of Sections 1 and 2 above on a medium
181 customarily used for software interchange; or,
183 c) Accompany it with the information you received as to the offer
184 to distribute corresponding source code. (This alternative is
185 allowed only for noncommercial distribution and only if you
186 received the program in object code or executable form with such
187 an offer, in accord with Subsection b above.)
189 The source code for a work means the preferred form of the work for
190 making modifications to it. For an executable work, complete source
191 code means all the source code for all modules it contains, plus any
192 associated interface definition files, plus the scripts used to
193 control compilation and installation of the executable. However, as a
194 special exception, the source code distributed need not include
195 anything that is normally distributed (in either source or binary
196 form) with the major components (compiler, kernel, and so on) of the
197 operating system on which the executable runs, unless that component
198 itself accompanies the executable.
200 If distribution of executable or object code is made by offering
201 access to copy from a designated place, then offering equivalent
202 access to copy the source code from the same place counts as
203 distribution of the source code, even though third parties are not
204 compelled to copy the source along with the object code.
206 4. You may not copy, modify, sublicense, or distribute the Program
207 except as expressly provided under this License. Any attempt
208 otherwise to copy, modify, sublicense or distribute the Program is
209 void, and will automatically terminate your rights under this License.
210 However, parties who have received copies, or rights, from you under
211 this License will not have their licenses terminated so long as such
212 parties remain in full compliance.
214 5. You are not required to accept this License, since you have not
215 signed it. However, nothing else grants you permission to modify or
216 distribute the Program or its derivative works. These actions are
217 prohibited by law if you do not accept this License. Therefore, by
218 modifying or distributing the Program (or any work based on the
219 Program), you indicate your acceptance of this License to do so, and
220 all its terms and conditions for copying, distributing or modifying
221 the Program or works based on it.
223 6. Each time you redistribute the Program (or any work based on the
224 Program), the recipient automatically receives a license from the
225 original licensor to copy, distribute or modify the Program subject to
226 these terms and conditions. You may not impose any further
227 restrictions on the recipients' exercise of the rights granted herein.
228 You are not responsible for enforcing compliance by third parties to
231 7. If, as a consequence of a court judgment or allegation of patent
232 infringement or for any other reason (not limited to patent issues),
233 conditions are imposed on you (whether by court order, agreement or
234 otherwise) that contradict the conditions of this License, they do not
235 excuse you from the conditions of this License. If you cannot
236 distribute so as to satisfy simultaneously your obligations under this
237 License and any other pertinent obligations, then as a consequence you
238 may not distribute the Program at all. For example, if a patent
239 license would not permit royalty-free redistribution of the Program by
240 all those who receive copies directly or indirectly through you, then
241 the only way you could satisfy both it and this License would be to
242 refrain entirely from distribution of the Program.
244 If any portion of this section is held invalid or unenforceable under
245 any particular circumstance, the balance of the section is intended to
246 apply and the section as a whole is intended to apply in other
249 It is not the purpose of this section to induce you to infringe any
250 patents or other property right claims or to contest validity of any
251 such claims; this section has the sole purpose of protecting the
252 integrity of the free software distribution system, which is
253 implemented by public license practices. Many people have made
254 generous contributions to the wide range of software distributed
255 through that system in reliance on consistent application of that
256 system; it is up to the author/donor to decide if he or she is willing
257 to distribute software through any other system and a licensee cannot
260 This section is intended to make thoroughly clear what is believed to
261 be a consequence of the rest of this License.
263 8. If the distribution and/or use of the Program is restricted in
264 certain countries either by patents or by copyrighted interfaces, the
265 original copyright holder who places the Program under this License
266 may add an explicit geographical distribution limitation excluding
267 those countries, so that distribution is permitted only in or among
268 countries not thus excluded. In such case, this License incorporates
269 the limitation as if written in the body of this License.
271 9. The Free Software Foundation may publish revised and/or new versions
272 of the General Public License from time to time. Such new versions will
273 be similar in spirit to the present version, but may differ in detail to
274 address new problems or concerns.
276 Each version is given a distinguishing version number. If the Program
277 specifies a version number of this License which applies to it and \"any
278 later version\", you have the option of following the terms and conditions
279 either of that version or of any later version published by the Free
280 Software Foundation. If the Program does not specify a version number of
281 this License, you may choose any version ever published by the Free Software
284 10. If you wish to incorporate parts of the Program into other free
285 programs whose distribution conditions are different, write to the author
286 to ask for permission. For software which is copyrighted by the Free
287 Software Foundation, write to the Free Software Foundation; we sometimes
288 make exceptions for this. Our decision will be guided by the two goals
289 of preserving the free status of all derivatives of our free software and
290 of promoting the sharing and reuse of software generally.
292 static char *warranty=
295 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
296 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
297 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
298 PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
299 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
300 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
301 TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
302 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
303 REPAIR OR CORRECTION.
305 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
306 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
307 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
308 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
309 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
310 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
311 YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
312 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
313 POSSIBILITY OF SUCH DAMAGES.
316 static void printTypeInfo(link *);
317 static void printValAggregates (symbol *,link *,char,unsigned int);
319 int srcMode = SRC_CMODE ;
321 /*-----------------------------------------------------------------*/
322 /* funcWithName - returns function with name */
323 /*-----------------------------------------------------------------*/
324 DEFSETFUNC(funcWithName)
326 function *func = item;
328 V_ARG(function **,funcp);
333 if (strcmp(func->sym->name,name) == 0) {
341 /*-----------------------------------------------------------------*/
342 /* setBPatModLine - set break point at the line specified for the */
343 /*-----------------------------------------------------------------*/
344 static void setBPatModLine (module *mod, int line)
346 /* look for the first executable line after the line
347 specified & get the break point there */
348 if (srcMode == SRC_CMODE && line > mod->ncLines) {
349 fprintf(stderr,"No line %d in file \"%s\".\n",
354 if (srcMode == SRC_AMODE && line > mod->nasmLines) {
355 fprintf(stderr,"No line %d in file \"%s\".\n",
360 for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ;
362 if (srcMode == SRC_CMODE) {
363 if (mod->cLines[line]->addr) {
364 setBreakPoint (mod->cLines[line]->addr, CODE, USER,
365 userBpCB, mod->c_name, line);
370 if (mod->asmLines[line]->addr) {
371 setBreakPoint (mod->asmLines[line]->addr, CODE, USER,
372 userBpCB, mod->asm_name, line);
381 /*-----------------------------------------------------------------*/
382 /* clearBPatModLine - clr break point at the line specified */
383 /*-----------------------------------------------------------------*/
384 static void clearBPatModLine (module *mod, int line)
386 /* look for the first executable line after the line
387 specified & get the break point there */
388 if (srcMode == SRC_CMODE && line > mod->ncLines) {
389 fprintf(stderr,"No line %d in file \"%s\".\n",
394 if (srcMode == SRC_AMODE && line > mod->ncLines) {
395 fprintf(stderr,"No line %d in file \"%s\".\n",
400 for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ;
402 if (srcMode == SRC_CMODE)
403 if (mod->cLines[line]->addr) {
404 clearUSERbp (mod->cLines[line]->addr);
408 if (mod->asmLines[line]->addr) {
409 clearUSERbp (mod->asmLines[line]->addr);
417 /*-----------------------------------------------------------------*/
418 /* funcWithNameModule - returns functions with a name module combo */
419 /*-----------------------------------------------------------------*/
420 DEFSETFUNC(funcWithNameModule)
422 function *func = item;
425 V_ARG(function **,funcp);
430 if (strcmp(func->sym->name,fname) == 0 &&
431 strcmp(func->mod->c_name,mname) == 0) {
439 /*-----------------------------------------------------------------*/
440 /* funcInAddr - given an address returns the function */
441 /*-----------------------------------------------------------------*/
442 DEFSETFUNC(funcInAddr)
444 function *func = item;
445 V_ARG(unsigned int,addr);
446 V_ARG(function **,funcp);
451 /* in the address range */
452 if (func->sym->addr <= addr &&
453 func->sym->eaddr >= addr) {
462 /*-----------------------------------------------------------------*/
463 /* setStepBp - will set STEP Bp @ function entry points */
464 /*-----------------------------------------------------------------*/
465 DEFSETFUNC(setStepBp)
467 function *func = item;
469 if (func->sym && func->sym->addr ) {
471 /* set the entry break point */
472 setBreakPoint (func->sym->addr , CODE , STEP ,
473 stepBpCB ,func->mod->c_name , func->entryline);
481 /*-----------------------------------------------------------------*/
482 /* setStepEPBp - sets a given type of bp @ the execution point */
483 /*-----------------------------------------------------------------*/
484 DEFSETFUNC(setStepEPBp)
490 setBreakPoint (ep->addr, CODE, bptype,
491 stepBpCB, mname, ep->line);
495 /*-----------------------------------------------------------------*/
496 /* setNextEPBp - sets a given type of bp @ the execution point */
497 /*-----------------------------------------------------------------*/
498 DEFSETFUNC(setNextEPBp)
504 setBreakPoint (ep->addr, CODE, bptype,
505 nextBpCB, mname, ep->line);
509 /*-----------------------------------------------------------------*/
510 /* lineAtAddr - for execution points returns the one with addr */
511 /*-----------------------------------------------------------------*/
512 DEFSETFUNC(lineAtAddr)
515 V_ARG(unsigned int,addr);
520 /* address must be an exact match */
521 if (ep->addr == addr) {
534 /*-----------------------------------------------------------------*/
535 /* discoverContext - find out the current context of the bp */
536 /*-----------------------------------------------------------------*/
537 context *discoverContext (unsigned addr)
539 function *func = NULL;
542 /* find the function we are in */
543 if (!applyToSet(functions,funcInAddr,addr,&func)) {
544 fprintf(stderr, "Error?:discoverContext: cannot apply to set!\n");
548 currCtxt->func = func;
549 currCtxt->addr = func->laddr = addr;
550 currCtxt->modName = func->modName;
552 /* find the c line number */
553 if(applyToSet(func->cfpoints,lineAtAddr,addr,
554 &line,&currCtxt->block,&currCtxt->level))
555 currCtxt->cline = func->lline = line;
557 currCtxt->cline = func->exitline;
559 /* find the asm line number */
561 if (applyToSet(func->afpoints,lineAtAddr,addr,
563 currCtxt->asmline = line;
565 currCtxt->asmline = -1;
571 /*-----------------------------------------------------------------*/
572 /* simGo - send 'go' cmd to simulator and wait till a break occurs */
573 /*-----------------------------------------------------------------*/
574 void simGo (unsigned int gaddr)
580 addr = simGoTillBp (gaddr);
582 /* got the pc for the break point now first
583 discover the program context i.e. module, function
584 linenumber of the source etc, etc etc */
585 ctxt = discoverContext (addr);
587 /* dispatch all the break point call back functions */
588 rv = dispatchCB (addr,ctxt);
592 /* the dispatch call back function will return
593 non-zero if an user break point has been hit
594 if not then we continue with the execution
597 fprintf(stdout, "Stopping at non-user breakpoint\n");
600 // I took this out, after running "run" it would just keep re-running
601 // even after a lot of break points hit. For some reason above code
602 // not triggering(dispatchCB). This seems to be by design, startup adds
603 // a bunch of breakpoints-but they are not USER breakpoints. Perhaps the
604 // debugger changed with its implementation of "go"("run"). It seems we
605 // need to add a "next" or "step" followed by a "run"...
606 // I added a "step" in simi.c when we want a resume function, this seems
609 // still there is question of how do we stop it initially, since
610 // it must be started before it can get a context. If so, we would
611 // want it to just run up to an initial entry point you'd think...
612 // I don't see why we can't set breakpoints before an initial run,
613 // this does not seem right to me.
615 // line #'s are a bit off too.
625 /*-----------------------------------------------------------------*/
626 /* cmdSetUserBp - set break point at the user specified location */
627 /*-----------------------------------------------------------------*/
628 int cmdSetUserBp (char *s, context *cctxt)
631 function *func = NULL;
633 /* user break point location specification can be of the following
635 a) <nothing> - break point at current location
636 b) lineno - number of the current module
637 c) filename:lineno - line number of the given file
638 e) filename:function- function X in file Y (useful for static functions)
639 f) function - function entry point
643 fprintf(stdout,"No symbol table is loaded. Use the \"file\" command.\n");
646 /* white space skip */
647 while (*s && isspace(*s)) s++;
649 /* null terminate it after stripping trailing blanks*/
651 while (bp != s && isspace(*bp)) bp--;
654 /* case a) nothing */
655 /* if nothing given then current location : we know
656 the current execution location from the currentContext */
659 /* if current context is known */
661 if (srcMode == SRC_CMODE)
662 /* set the break point */
663 setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
664 cctxt->func->mod->c_name, cctxt->cline);
666 setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
667 cctxt->func->mod->asm_name, cctxt->asmline);
671 fprintf(stderr,"No default breakpoint address now.\n");
677 /* check if line number */
682 /* if current context not present then we must get the module
683 which has main & set the break point @ line number provided
684 of that module : if current context known then set the bp
685 at the line number given for the current module
688 if (!cctxt->func->mod) {
689 if (!applyToSet(functions,funcWithName,"main"))
690 fprintf(stderr,"Function \"main\" not defined.\n");
692 setBPatModLine(func->mod,line);
694 setBPatModLine(cctxt->func->mod,line);
696 fprintf(stdout,"No symbol information currently\n");
702 if ((bp = strchr(s,':'))) {
707 if (srcMode == SRC_CMODE) {
708 if (!applyToSet(modules,moduleWithCName,s,&mod)) {
709 fprintf (stderr,"No source file named %s.\n",s);
713 if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
714 fprintf (stderr,"No source file named %s.\n",s);
719 /* case c) filename:lineno */
720 if (isdigit(*(bp +1))) {
722 setBPatModLine (mod,atoi(bp+1));
726 /* case d) filename:function */
727 if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func))
728 fprintf(stderr,"Function \"%s\" not defined.\n",bp+1);
731 (srcMode == SRC_CMODE ?
738 /* case e) function */
739 if (!applyToSet(functions,funcWithName,s,&func))
740 fprintf(stderr,"Function \"%s\" not defined.\n",s);
742 setBPatModLine(func->mod,
743 (srcMode == SRC_CMODE ?
751 /*-----------------------------------------------------------------*/
752 /* cmdListAsm - list assembler source code */
753 /*-----------------------------------------------------------------*/
754 int cmdListAsm (char *s, context *cctxt)
756 fprintf(stderr,"'listasm' command not yet implemented\n");
760 /*-----------------------------------------------------------------*/
761 /* cmdSetOption - set debugger options */
762 /*-----------------------------------------------------------------*/
763 int cmdSetOption (char *s, context *cctxt)
765 while (*s && isspace(*s)) s++;
766 if (strncmp(s,"srcmode",7) == 0 ) {
767 if (srcMode == SRC_CMODE)
771 fprintf(stderr,"source mode set to '%s'\n",
772 (srcMode == SRC_CMODE ? "C" : "asm"));
776 fprintf(stderr,"'set %s' command not yet implemented\n",s);
780 /*-----------------------------------------------------------------*/
781 /* cmdContinue - continue till next break point */
782 /*-----------------------------------------------------------------*/
783 int cmdContinue (char *s, context *cctxt)
785 if (!cctxt || !cctxt->func) {
786 fprintf(stdout,"The program is not being run.\n");
790 fprintf(stdout,"Continuing.\n");
795 /*-----------------------------------------------------------------*/
796 /* cmdDelUserBp - delete user break point */
797 /*-----------------------------------------------------------------*/
798 int cmdDelUserBp (char *s, context *cctxt)
801 while (isspace(*s)) s++;
806 fprintf (stdout,"Delete all breakpoints? (y or n) ");
808 fgets(buffer,sizeof(buffer),stdin);
809 if (toupper(buffer[0]) == 'Y')
815 /* determine the break point number */
816 if (sscanf(s,"%d",&bpnum) == 1)
822 /*-----------------------------------------------------------------*/
823 /* cmdStep - single step thru C source file */
824 /*-----------------------------------------------------------------*/
825 int cmdStep (char *s, context *cctxt)
827 function *func = NULL;
829 if (!cctxt || !cctxt->func || !cctxt->func->mod)
830 fprintf(stdout,"The program is not being run.\n");
832 /* if we are @ the end of a function then set
833 break points at execution points of the
834 function in the call stack... */
835 if (cctxt->addr == cctxt->func->sym->eaddr) {
836 if ((func = STACK_PEEK(callStack))) {
837 if (srcMode == SRC_CMODE)
838 applyToSet (func->cfpoints,setStepEPBp,STEP,
841 applyToSet (func->afpoints,setStepEPBp,STEP,
842 func->mod->asm_name);
845 /* set breakpoints at all function entry points
846 and all exepoints of this functions & for
847 all functions one up in the call stack */
849 /* all function entry points */
850 applyToSet(functions,setStepBp);
852 if (srcMode == SRC_CMODE) {
853 /* for all execution points in this function */
854 applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP,
855 cctxt->func->mod->c_name);
857 /* set a break point @ the current function's
859 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP ,
860 stepBpCB, cctxt->func->mod->c_name,
861 cctxt->func->exitline);
863 /* now break point @ callers execution points */
864 if ((func = STACK_PPEEK(callStack))) {
865 applyToSet (func->cfpoints,setStepEPBp,STEP,
867 /* set bp @ callers exit point */
868 setBreakPoint (func->sym->eaddr, CODE, STEP ,
869 stepBpCB, func->mod->c_name,
873 /* for all execution points in this function */
874 applyToSet(cctxt->func->afpoints,setStepEPBp,STEP,
875 cctxt->func->mod->asm_name);
877 /* set a break point @ the current function's
879 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP ,
880 stepBpCB, cctxt->func->mod->asm_name,
881 cctxt->func->aexitline);
883 /* now break point @ callers execution points */
884 if ((func = STACK_PPEEK(callStack))) {
886 applyToSet (func->afpoints,setStepEPBp,STEP,
887 func->mod->asm_name);
889 /* set bp @ callers exit point */
890 setBreakPoint (func->sym->eaddr, CODE, STEP ,
891 stepBpCB, func->mod->asm_name,
902 /*-----------------------------------------------------------------*/
903 /* cmdNext - next executable C statement file */
904 /*-----------------------------------------------------------------*/
905 int cmdNext (char *s, context *cctxt)
907 function *func = NULL;
908 /* next is almost the same as step except we don't
909 we don't set break point for all function entry
911 if (!cctxt || !cctxt->func || !cctxt->func->mod)
912 fprintf(stdout,"The program is not being run.\n");
915 /* if we are @ the end of a function then set
916 break points at execution points of the
917 function in the call stack... */
918 if (cctxt->addr == cctxt->func->sym->eaddr) {
919 if ((func = STACK_PEEK(callStack))) {
920 if (srcMode == SRC_CMODE)
921 applyToSet (func->cfpoints,setStepEPBp,STEP,
924 applyToSet (func->afpoints,setStepEPBp,STEP,
925 func->mod->asm_name);
928 if (srcMode == SRC_CMODE) {
929 /* for all execution points in this function */
930 applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT,
931 cctxt->func->mod->c_name);
932 /* set a break point @ the current function's
934 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT ,
935 nextBpCB, cctxt->func->mod->c_name,
936 cctxt->func->exitline);
938 /* now break point @ callers execution points */
939 if ((func = STACK_PPEEK(callStack))) {
940 applyToSet (func->cfpoints,setNextEPBp,NEXT ,
942 /* set bp @ callers exit point */
943 setBreakPoint (func->sym->eaddr, CODE, NEXT ,
944 stepBpCB, func->mod->c_name,
948 /* for all execution points in this function */
949 applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT,
950 cctxt->func->mod->asm_name);
951 /* set a break point @ the current function's
953 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT ,
954 nextBpCB, cctxt->func->mod->asm_name,
955 cctxt->func->aexitline);
957 /* now break point @ callers execution points */
958 if ((func = STACK_PPEEK(callStack))) {
959 applyToSet (func->cfpoints,setNextEPBp,NEXT ,
960 func->mod->asm_name);
961 /* set bp @ callers exit point */
962 setBreakPoint (func->sym->eaddr, CODE, NEXT ,
963 stepBpCB, func->mod->asm_name,
973 /*-----------------------------------------------------------------*/
974 /* cmdRun - run till next break point */
975 /*-----------------------------------------------------------------*/
976 int cmdRun (char *s, context *cctxt)
979 if (!cctxt || !cctxt->func || !cctxt->func->mod) {
980 fprintf(stdout,"Starting program\n");
985 "The program being debugged has been started already.\n");
986 fprintf(stdout,"Start it from the beginning? (y or n) ");
989 fgets(buff,sizeof(buff),stdin);
990 if (toupper(buff[0]) == 'Y') {
999 /*-----------------------------------------------------------------*/
1000 /* infoStack - print call stack information */
1001 /*-----------------------------------------------------------------*/
1002 static void infoStack(context *ctxt)
1007 STACK_STARTWALK(callStack) ;
1008 while ((func = STACK_WALK(callStack))) {
1010 fprintf(stdout,"#%d 0x%04x %s () at %s:%d\n",i++,
1011 func->laddr,func->sym->name,
1012 func->mod->c_name,func->lline);
1017 /*-----------------------------------------------------------------*/
1018 /* cmdInfo - info command */
1019 /*-----------------------------------------------------------------*/
1020 int cmdInfo (char *s, context *cctxt)
1022 while (isspace(*s)) s++;
1024 /* list all break points */
1025 if (strcmp(s,"break") == 0) {
1030 /* info frame same as frame */
1031 if (strcmp(s,"frame") == 0) {
1036 /* info stack display call stack */
1037 if (strcmp(s,"stack") == 0) {
1042 /* info stack display call stack */
1043 if (strcmp(s,"registers") == 0) {
1044 fprintf(stdout,"%s",simRegs());
1048 fprintf(stdout,"Undefined info command: \"%s\". Try \"help\n",s);
1053 /*-----------------------------------------------------------------*/
1054 /* cmdQuit - quit debugging */
1055 /*-----------------------------------------------------------------*/
1056 int cmdQuit (char *s, context *cctxt)
1063 /*-----------------------------------------------------------------*/
1064 /* cmdListSrc - list src */
1065 /*-----------------------------------------------------------------*/
1066 int cmdListSrc (char *s, context *cctxt)
1068 static int currline = 0;
1071 static module *mod = NULL;
1072 int llines = listLines;
1074 while (*s && isspace(*s)) s++;
1076 /* if the user has spcified line numer then the line number
1077 can be of the following formats
1078 LINE - just line number
1079 FILE:LINE - filename line number
1080 FUNCTION - list a function
1081 FILE:FUNCTION - function in file */
1082 if (!cctxt || !cctxt->func || !cctxt->func->mod) {
1083 fprintf(stdout,"No symbol table is loaded. Use the \"file\" command.\n");
1089 sscanf(s,"%d",&pline);
1090 mod = cctxt->func->mod;
1094 function *func = NULL;
1096 /* if ':' present then FILE:LINE || FILE:FUNCTION */
1097 if ((bp = strchr(s,':'))) {
1102 if (srcMode == SRC_CMODE) {
1103 if (!applyToSet(modules,moduleWithCName,s,&mod)) {
1104 fprintf (stderr,"No source file named %s.\n",s);
1108 if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
1109 fprintf (stderr,"No source file named %s.\n",s);
1113 sscanf(bp,"%d",&pline);
1116 if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) {
1117 fprintf(stdout,"Function \"%s\" not defined.\n",bp);
1121 if (srcMode == SRC_CMODE) {
1122 pline = func->entryline;
1123 llines = func->exitline - func->entryline + 1;
1125 pline = func->aentryline;
1126 llines = func->aexitline - func->aentryline + 1;
1132 if (!applyToSet(functions,funcWithName,s,&func)) {
1133 fprintf(stderr,"Function \"%s\" not defined.\n",s);
1138 if (srcMode == SRC_CMODE) {
1139 pline = func->entryline;
1140 llines = func->exitline - func->entryline + 1;
1142 pline = func->aentryline;
1143 llines = func->aexitline - func->aentryline + 1;
1149 /* if no line specified & we had listed
1150 before then continue from that listing */
1154 mod = cctxt->func->mod;
1155 if (srcMode == SRC_CMODE)
1156 pline = cctxt->cline;
1158 pline = cctxt->asmline;
1162 for ( i = 0 ; i < llines ; i++ ) {
1163 if (srcMode == SRC_CMODE) {
1164 if ( (pline + i) >= mod->ncLines )
1166 fprintf(stdout,"%d\t%s",pline + i,
1167 mod->cLines[pline +i]->src);
1169 if ( (pline + i) >= mod->nasmLines )
1171 fprintf(stdout,"%d\t%s",pline + i,
1172 mod->asmLines[pline +i]->src);
1175 currline = pline + i ;
1179 /*-----------------------------------------------------------------*/
1180 /* printValBasic - print value of basic types */
1181 /*-----------------------------------------------------------------*/
1182 static void printValBasic(symbol *sym,unsigned addr,char mem, int size)
1198 v.val = simGetValue(addr,mem,size);
1199 /* if this a floating point number then */
1200 if (IS_FLOAT(sym->type))
1201 fprintf(stdout,"%f",v.f);
1203 if (IS_PTR(sym->type))
1204 fprintf(stdout,"0x%x",v.val);
1206 if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) {
1207 if (IS_CHAR(sym->etype))
1208 fprintf(stdout,"'%c' %d 0x%x",v.val,v.val,v.val);
1210 if (IS_INT(sym->etype))
1211 if (IS_LONG(sym->etype))
1212 if (SPEC_USIGN(sym->etype))
1213 fprintf(stdout,"%d 0x%x",v.val,v.val);
1215 fprintf(stdout,"%d 0x%x",v.sval,v.sval);
1217 fprintf(stdout,"%d 0x%x",v.i.lo,v.i.lo);
1219 fprintf(stdout,"0x%x",v.val);
1221 fprintf(stdout,"0x%x",v.val);
1226 /*-----------------------------------------------------------------*/
1227 /* printValFunc - prints function values */
1228 /*-----------------------------------------------------------------*/
1229 static void printValFunc (symbol *sym)
1231 fprintf(stdout,"print function not yet implemented\n");
1234 /*-----------------------------------------------------------------*/
1235 /* printArrayValue - will print the values of array elements */
1236 /*-----------------------------------------------------------------*/
1237 static void printArrayValue (symbol *sym, char space, unsigned int addr)
1239 link *elem_type = sym->type->next;
1242 fprintf(stdout," { ");
1243 for (i = 0 ; i < DCL_ELEM(sym->type) ; i++) {
1244 if (IS_AGGREGATE(elem_type)) {
1245 printValAggregates(sym,elem_type,space,addr);
1247 printValBasic(sym,addr,space,getSize(elem_type));
1249 addr += getSize(elem_type);
1250 if (i != DCL_ELEM(sym->type) -1)
1251 fprintf(stdout,",");
1254 fprintf(stdout,"}\n");
1257 /*-----------------------------------------------------------------*/
1258 /* printStructValue - prints structures elements */
1259 /*-----------------------------------------------------------------*/
1260 static void printStructValue (symbol *sym,link *type, char space, unsigned int addr)
1262 symbol *fields = SPEC_STRUCT(type)->fields;
1264 fprintf(stdout," { ");
1266 fprintf(stdout,"%s = ",fields->name);
1267 if (IS_AGGREGATE(fields->type)) {
1268 printValAggregates(fields,fields->type,space, addr);
1270 printValBasic(fields,addr,space,getSize(fields->type));
1272 addr += getSize(fields->type);
1273 fields = fields->next;
1275 fprintf(stdout,"}\n");
1278 /*-----------------------------------------------------------------*/
1279 /* printValAggregates - print value of aggregates */
1280 /*-----------------------------------------------------------------*/
1281 static void printValAggregates (symbol *sym, link *type,char space,unsigned int addr)
1284 if (IS_ARRAY(type)) {
1285 printArrayValue(sym, space, addr);
1289 if (IS_STRUCT(type)) {
1290 printStructValue(sym,sym->type,space, addr);
1295 /*-----------------------------------------------------------------*/
1296 /* printSymValue - print value of a symbol */
1297 /*-----------------------------------------------------------------*/
1298 static void printSymValue (symbol *sym, context *cctxt)
1300 static int stack = 1;
1302 /* if it is on stack then compute address & fall thru */
1303 if (sym->isonstack) {
1304 symbol *bp = symLookup("bp",cctxt);
1306 fprintf(stdout,"cannot determine stack frame\n");
1310 sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
1314 /* get the value from the simulator and
1316 fprintf(stdout,"$%d = ",stack++);
1317 /* arrays & structures first */
1318 if (IS_AGGREGATE(sym->type))
1319 printValAggregates(sym,sym->type,sym->addrspace,sym->addr);
1322 if (IS_FUNC(sym->type))
1325 printValBasic(sym,sym->addr,sym->addrspace,sym->size);
1326 fprintf(stdout,"\n");
1330 /*-----------------------------------------------------------------*/
1331 /* printStructInfo - print out structure information */
1332 /*-----------------------------------------------------------------*/
1333 static void printStructInfo (structdef *sdef)
1335 symbol *field = sdef->fields ;
1340 field = field->next;
1343 fprintf(stdout,"%s %s {\n",(i ? "struct" : "union" ), sdef->tag);
1344 field = sdef->fields;
1346 printTypeInfo (field->type);
1347 fprintf(stdout," %s ;\n",field->name);
1348 field = field->next ;
1351 fprintf(stdout,"}\n");
1355 /*-----------------------------------------------------------------*/
1356 /* printTypeInfo - print out the type information */
1357 /*-----------------------------------------------------------------*/
1358 static void printTypeInfo(link *p)
1364 switch (DCL_TYPE(p)) {
1366 printTypeInfo (p->next);
1367 fprintf(stdout,"()");
1370 printTypeInfo (p->next);
1371 fprintf(stdout,"[%d]",DCL_ELEM(p));
1377 printTypeInfo (p->next);
1378 fprintf(stdout,"(_near *)");
1382 printTypeInfo (p->next);
1383 fprintf(stdout,"(_xdata *)");
1387 printTypeInfo( p->next);
1388 fprintf(stdout,"(_code *)");
1392 printTypeInfo( p->next);
1393 fprintf(stdout,"(_generic *)");
1397 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
1399 (IS_LONG(p) ? fputs("long ",stdout) :
1400 ( IS_SHORT(p) ? fputs("short ",stdout) :
1401 fputs("int ",stdout))) ;
1404 fputs("float ",stdout);
1408 fputs ("char ",stdout);
1412 fputs("void ",stdout);
1416 printStructInfo (SPEC_STRUCT(p));
1420 fputs("sbit ",stdout);
1424 fprintf(stdout,": %d" ,SPEC_BLEN(p));
1430 /*-----------------------------------------------------------------*/
1431 /* cmdPrint - print value of variable */
1432 /*-----------------------------------------------------------------*/
1433 int cmdPrint (char *s, context *cctxt)
1436 char *bp = s+strlen(s) -1;
1438 while (isspace(*s)) s++;
1440 while (isspace(*bp)) bp--;
1444 if (!cctxt || !cctxt->func) {
1445 fprintf(stdout,"No symbol \"%s\" in current context.\n",
1449 if ((sym = symLookup(s,cctxt))) {
1450 printSymValue(sym,cctxt);
1453 "No symbol \"%s\" in current context.\n",
1459 /*-----------------------------------------------------------------*/
1460 /* cmdPrintType - print type of a variable */
1461 /*-----------------------------------------------------------------*/
1462 int cmdPrintType (char *s, context *cctxt)
1465 char *bp = s+strlen(s) -1;
1467 while (isspace(*s)) s++;
1469 while (isspace(*bp)) bp--;
1473 if (!cctxt || !cctxt->func) {
1474 fprintf(stdout,"No symbol \"%s\" in current context.\n",
1479 if ((sym = symLookup(s,cctxt))) {
1480 printTypeInfo(sym->type);
1481 fprintf(stdout,"\n");
1484 "No symbol \"%s\" in current context.\n",
1490 /*-----------------------------------------------------------------*/
1491 /* cmdClrUserBp - clear user break point */
1492 /*-----------------------------------------------------------------*/
1493 int cmdClrUserBp (char *s, context *cctxt)
1496 function *func = NULL;
1498 /* clear break point location specification can be of the following
1500 a) <nothing> - break point at current location
1501 b) lineno - number of the current module
1502 c) filename:lineno - line number of the given file
1503 e) filename:function- function X in file Y (useful for static functions)
1504 f) function - function entry point
1508 fprintf(stdout,"No symbol table is loaded. Use the \"file\" command.\n");
1512 /* white space skip */
1513 while (*s && isspace(*s)) s++;
1515 /* null terminate it after stripping trailing blanks*/
1517 while (bp != s && isspace(*bp)) bp--;
1520 /* case a) nothing */
1521 /* if nothing given then current location : we know
1522 the current execution location from the currentContext */
1525 /* if current context is known */
1527 /* clear the break point @ current location */
1528 clearUSERbp (cctxt->addr);
1530 fprintf(stderr,"No default breakpoint address now.\n");
1535 /* case b) lineno */
1536 /* check if line number */
1538 /* get the lineno */
1541 /* if current context not present then we must get the module
1542 which has main & set the break point @ line number provided
1543 of that module : if current context known then set the bp
1544 at the line number given for the current module
1547 if (!cctxt->func->mod) {
1548 if (!applyToSet(functions,funcWithName,"main"))
1549 fprintf(stderr,"Function \"main\" not defined.\n");
1551 clearBPatModLine(func->mod,line);
1553 clearBPatModLine(cctxt->func->mod,line);
1559 if ((bp = strchr(s,':'))) {
1564 if (!applyToSet(modules,moduleWithCName,s,&mod)) {
1565 fprintf (stderr,"No source file named %s.\n",s);
1569 /* case c) filename:lineno */
1570 if (isdigit(*(bp +1))) {
1572 clearBPatModLine (mod,atoi(bp+1));
1576 /* case d) filename:function */
1577 if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func))
1578 fprintf(stderr,"Function \"%s\" not defined.\n",bp+1);
1580 clearBPatModLine (mod,func->entryline);
1585 /* case e) function */
1586 if (!applyToSet(functions,funcWithName,s,&func))
1587 fprintf(stderr,"Function \"%s\" not defined.\n",s);
1589 clearBPatModLine(func->mod,func->entryline);
1596 /*-----------------------------------------------------------------*/
1597 /* cmdSimulator - send command to simulator */
1598 /*-----------------------------------------------------------------*/
1599 int cmdSimulator (char *s, context *cctxt)
1603 if (strlen(s) > 80) {
1604 printf("error 3A\n");
1608 strcat(tmpstr, "\n");
1611 fprintf(stdout,"%s",simResponse());
1615 /*-----------------------------------------------------------------*/
1616 /* cmdFrame - Frame command */
1617 /*-----------------------------------------------------------------*/
1618 int cmdFrame (char *s, context *cctxt)
1622 if ((func = STACK_PEEK(callStack))) {
1623 fprintf(stdout,"#0 %s () at %s:%d\n",
1624 func->sym->name,func->mod->c_name,cctxt->cline);
1626 if (cctxt->cline < func->mod->ncLines)
1627 fprintf(stdout,"%d\t%s",
1629 func->mod->cLines[cctxt->cline]->src);
1631 fprintf(stdout,"No stack.\n");
1635 /*-----------------------------------------------------------------*/
1636 /* cmdFinish - exec till end of current function */
1637 /*-----------------------------------------------------------------*/
1638 int cmdFinish (char *s, context *ctxt)
1640 if (!ctxt || ! ctxt->func) {
1641 fprintf(stdout,"The program is not running.\n");
1645 if (srcMode == SRC_CMODE) {
1646 setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
1647 stepBpCB, ctxt->func->mod->c_name,
1648 ctxt->func->exitline);
1650 setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
1651 stepBpCB, ctxt->func->mod->asm_name,
1652 ctxt->func->aexitline);
1661 /*-----------------------------------------------------------------*/
1662 /* cmdShow - show command */
1663 /*-----------------------------------------------------------------*/
1664 int cmdShow (char *s, context *cctxt)
1666 /* skip white space */
1667 while (*s && isspace(*s)) s++ ;
1669 if (strcmp(s,"copying") == 0) {
1670 fputs(copying,stdout);
1674 if (strcmp(s,"warranty") == 0) {
1675 fputs(warranty,stdout);