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)
579 static int initial_break_flag = 0;
582 addr = simGoTillBp (gaddr);
584 /* got the pc for the break point now first
585 discover the program context i.e. module, function
586 linenumber of the source etc, etc etc */
587 ctxt = discoverContext (addr);
589 /* dispatch all the break point call back functions */
590 rv = dispatchCB (addr,ctxt);
594 /* the dispatch call back function will return
595 non-zero if an user break point has been hit
596 if not then we continue with the execution
599 if (!initial_break_flag) {
600 initial_break_flag = 1; // kludge to stop only at first run
601 fprintf(stdout, "Stopping at entry. You can now list and set breakpoints\n");
609 // I took this out, after running "run" it would just keep re-running
610 // even after a lot of break points hit. For some reason above code
611 // not triggering(dispatchCB). This seems to be by design, startup adds
612 // a bunch of breakpoints-but they are not USER breakpoints. Perhaps the
613 // debugger changed with its implementation of "go"("run"). It seems we
614 // need to add a "next" or "step" followed by a "run"...
615 // I added a "step" in simi.c when we want a resume function, this seems
618 // still there is question of how do we stop it initially, since
619 // it must be started before it can get a context. If so, we would
620 // want it to just run up to an initial entry point you'd think...
621 // I don't see why we can't set breakpoints before an initial run,
622 // this does not seem right to me.
624 // line #'s are a bit off too.
634 /*-----------------------------------------------------------------*/
635 /* cmdSetUserBp - set break point at the user specified location */
636 /*-----------------------------------------------------------------*/
637 int cmdSetUserBp (char *s, context *cctxt)
640 function *func = NULL;
642 /* user break point location specification can be of the following
644 a) <nothing> - break point at current location
645 b) lineno - number of the current module
646 c) filename:lineno - line number of the given file
647 e) filename:function- function X in file Y (useful for static functions)
648 f) function - function entry point
652 fprintf(stdout,"No symbol table is loaded. Use the \"file\" command.\n");
655 /* white space skip */
656 while (*s && isspace(*s)) s++;
658 /* null terminate it after stripping trailing blanks*/
660 while (bp != s && isspace(*bp)) bp--;
663 /* case a) nothing */
664 /* if nothing given then current location : we know
665 the current execution location from the currentContext */
668 /* if current context is known */
670 if (srcMode == SRC_CMODE)
671 /* set the break point */
672 setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
673 cctxt->func->mod->c_name, cctxt->cline);
675 setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
676 cctxt->func->mod->asm_name, cctxt->asmline);
680 fprintf(stderr,"No default breakpoint address now.\n");
686 /* check if line number */
691 /* if current context not present then we must get the module
692 which has main & set the break point @ line number provided
693 of that module : if current context known then set the bp
694 at the line number given for the current module
697 if (!cctxt->func->mod) {
698 if (!applyToSet(functions,funcWithName,"main"))
699 fprintf(stderr,"Function \"main\" not defined.\n");
701 setBPatModLine(func->mod,line);
703 setBPatModLine(cctxt->func->mod,line);
705 fprintf(stdout,"No symbol information currently\n");
711 if ((bp = strchr(s,':'))) {
716 if (srcMode == SRC_CMODE) {
717 if (!applyToSet(modules,moduleWithCName,s,&mod)) {
718 fprintf (stderr,"No source file named %s.\n",s);
722 if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
723 fprintf (stderr,"No source file named %s.\n",s);
728 /* case c) filename:lineno */
729 if (isdigit(*(bp +1))) {
731 setBPatModLine (mod,atoi(bp+1));
735 /* case d) filename:function */
736 if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func))
737 fprintf(stderr,"Function \"%s\" not defined.\n",bp+1);
740 (srcMode == SRC_CMODE ?
747 /* case e) function */
748 if (!applyToSet(functions,funcWithName,s,&func))
749 fprintf(stderr,"Function \"%s\" not defined.\n",s);
751 setBPatModLine(func->mod,
752 (srcMode == SRC_CMODE ?
760 /*-----------------------------------------------------------------*/
761 /* cmdListAsm - list assembler source code */
762 /*-----------------------------------------------------------------*/
763 int cmdListAsm (char *s, context *cctxt)
765 fprintf(stderr,"'listasm' command not yet implemented\n");
769 /*-----------------------------------------------------------------*/
770 /* cmdSetOption - set debugger options */
771 /*-----------------------------------------------------------------*/
772 int cmdSetOption (char *s, context *cctxt)
774 while (*s && isspace(*s)) s++;
775 if (strncmp(s,"srcmode",7) == 0 ) {
776 if (srcMode == SRC_CMODE)
780 fprintf(stderr,"source mode set to '%s'\n",
781 (srcMode == SRC_CMODE ? "C" : "asm"));
785 fprintf(stderr,"'set %s' command not yet implemented\n",s);
789 /*-----------------------------------------------------------------*/
790 /* cmdContinue - continue till next break point */
791 /*-----------------------------------------------------------------*/
792 int cmdContinue (char *s, context *cctxt)
794 if (!cctxt || !cctxt->func) {
795 fprintf(stdout,"The program is not being run.\n");
799 fprintf(stdout,"Continuing.\n");
804 /*-----------------------------------------------------------------*/
805 /* cmdDelUserBp - delete user break point */
806 /*-----------------------------------------------------------------*/
807 int cmdDelUserBp (char *s, context *cctxt)
810 while (isspace(*s)) s++;
815 fprintf (stdout,"Delete all breakpoints? (y or n) ");
817 fgets(buffer,sizeof(buffer),stdin);
818 if (toupper(buffer[0]) == 'Y')
824 /* determine the break point number */
825 if (sscanf(s,"%d",&bpnum) == 1)
831 /*-----------------------------------------------------------------*/
832 /* cmdStep - single step thru C source file */
833 /*-----------------------------------------------------------------*/
834 int cmdStep (char *s, context *cctxt)
836 function *func = NULL;
838 if (!cctxt || !cctxt->func || !cctxt->func->mod)
839 fprintf(stdout,"The program is not being run.\n");
841 /* if we are @ the end of a function then set
842 break points at execution points of the
843 function in the call stack... */
844 if (cctxt->addr == cctxt->func->sym->eaddr) {
845 if ((func = STACK_PEEK(callStack))) {
846 if (srcMode == SRC_CMODE)
847 applyToSet (func->cfpoints,setStepEPBp,STEP,
850 applyToSet (func->afpoints,setStepEPBp,STEP,
851 func->mod->asm_name);
854 /* set breakpoints at all function entry points
855 and all exepoints of this functions & for
856 all functions one up in the call stack */
858 /* all function entry points */
859 applyToSet(functions,setStepBp);
861 if (srcMode == SRC_CMODE) {
862 /* for all execution points in this function */
863 applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP,
864 cctxt->func->mod->c_name);
866 /* set a break point @ the current function's
868 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP ,
869 stepBpCB, cctxt->func->mod->c_name,
870 cctxt->func->exitline);
872 /* now break point @ callers execution points */
873 if ((func = STACK_PPEEK(callStack))) {
874 applyToSet (func->cfpoints,setStepEPBp,STEP,
876 /* set bp @ callers exit point */
877 setBreakPoint (func->sym->eaddr, CODE, STEP ,
878 stepBpCB, func->mod->c_name,
882 /* for all execution points in this function */
883 applyToSet(cctxt->func->afpoints,setStepEPBp,STEP,
884 cctxt->func->mod->asm_name);
886 /* set a break point @ the current function's
888 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP ,
889 stepBpCB, cctxt->func->mod->asm_name,
890 cctxt->func->aexitline);
892 /* now break point @ callers execution points */
893 if ((func = STACK_PPEEK(callStack))) {
895 applyToSet (func->afpoints,setStepEPBp,STEP,
896 func->mod->asm_name);
898 /* set bp @ callers exit point */
899 setBreakPoint (func->sym->eaddr, CODE, STEP ,
900 stepBpCB, func->mod->asm_name,
911 /*-----------------------------------------------------------------*/
912 /* cmdNext - next executable C statement file */
913 /*-----------------------------------------------------------------*/
914 int cmdNext (char *s, context *cctxt)
916 function *func = NULL;
917 /* next is almost the same as step except we don't
918 we don't set break point for all function entry
920 if (!cctxt || !cctxt->func || !cctxt->func->mod)
921 fprintf(stdout,"The program is not being run.\n");
924 /* if we are @ the end of a function then set
925 break points at execution points of the
926 function in the call stack... */
927 if (cctxt->addr == cctxt->func->sym->eaddr) {
928 if ((func = STACK_PEEK(callStack))) {
929 if (srcMode == SRC_CMODE)
930 applyToSet (func->cfpoints,setStepEPBp,STEP,
933 applyToSet (func->afpoints,setStepEPBp,STEP,
934 func->mod->asm_name);
937 if (srcMode == SRC_CMODE) {
938 /* for all execution points in this function */
939 applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT,
940 cctxt->func->mod->c_name);
941 /* set a break point @ the current function's
943 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT ,
944 nextBpCB, cctxt->func->mod->c_name,
945 cctxt->func->exitline);
947 /* now break point @ callers execution points */
948 if ((func = STACK_PPEEK(callStack))) {
949 applyToSet (func->cfpoints,setNextEPBp,NEXT ,
951 /* set bp @ callers exit point */
952 setBreakPoint (func->sym->eaddr, CODE, NEXT ,
953 stepBpCB, func->mod->c_name,
957 /* for all execution points in this function */
958 applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT,
959 cctxt->func->mod->asm_name);
960 /* set a break point @ the current function's
962 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT ,
963 nextBpCB, cctxt->func->mod->asm_name,
964 cctxt->func->aexitline);
966 /* now break point @ callers execution points */
967 if ((func = STACK_PPEEK(callStack))) {
968 applyToSet (func->cfpoints,setNextEPBp,NEXT ,
969 func->mod->asm_name);
970 /* set bp @ callers exit point */
971 setBreakPoint (func->sym->eaddr, CODE, NEXT ,
972 stepBpCB, func->mod->asm_name,
982 /*-----------------------------------------------------------------*/
983 /* cmdRun - run till next break point */
984 /*-----------------------------------------------------------------*/
985 int cmdRun (char *s, context *cctxt)
988 if (!cctxt || !cctxt->func || !cctxt->func->mod) {
989 fprintf(stdout,"Starting program\n");
994 "The program being debugged has been started already.\n");
995 fprintf(stdout,"Start it from the beginning? (y or n) ");
998 fgets(buff,sizeof(buff),stdin);
999 if (toupper(buff[0]) == 'Y') {
1008 /*-----------------------------------------------------------------*/
1009 /* infoStack - print call stack information */
1010 /*-----------------------------------------------------------------*/
1011 static void infoStack(context *ctxt)
1016 STACK_STARTWALK(callStack) ;
1017 while ((func = STACK_WALK(callStack))) {
1019 fprintf(stdout,"#%d 0x%04x %s () at %s:%d\n",i++,
1020 func->laddr,func->sym->name,
1021 func->mod->c_name,func->lline);
1026 /*-----------------------------------------------------------------*/
1027 /* cmdInfo - info command */
1028 /*-----------------------------------------------------------------*/
1029 int cmdInfo (char *s, context *cctxt)
1031 while (isspace(*s)) s++;
1033 /* list all break points */
1034 if (strcmp(s,"break") == 0) {
1039 /* info frame same as frame */
1040 if (strcmp(s,"frame") == 0) {
1045 /* info stack display call stack */
1046 if (strcmp(s,"stack") == 0) {
1051 /* info stack display call stack */
1052 if (strcmp(s,"registers") == 0) {
1053 fprintf(stdout,"%s",simRegs());
1057 fprintf(stdout,"Undefined info command: \"%s\". Try \"help\n",s);
1062 /*-----------------------------------------------------------------*/
1063 /* cmdQuit - quit debugging */
1064 /*-----------------------------------------------------------------*/
1065 int cmdQuit (char *s, context *cctxt)
1072 /*-----------------------------------------------------------------*/
1073 /* cmdListSrc - list src */
1074 /*-----------------------------------------------------------------*/
1075 int cmdListSrc (char *s, context *cctxt)
1077 static int currline = 0;
1080 static module *mod = NULL;
1081 int llines = listLines;
1083 while (*s && isspace(*s)) s++;
1085 /* if the user has spcified line numer then the line number
1086 can be of the following formats
1087 LINE - just line number
1088 FILE:LINE - filename line number
1089 FUNCTION - list a function
1090 FILE:FUNCTION - function in file */
1091 if (!cctxt || !cctxt->func || !cctxt->func->mod) {
1092 fprintf(stdout,"No symbol table is loaded. Use the \"file\" command.\n");
1098 sscanf(s,"%d",&pline);
1099 mod = cctxt->func->mod;
1103 function *func = NULL;
1105 /* if ':' present then FILE:LINE || FILE:FUNCTION */
1106 if ((bp = strchr(s,':'))) {
1111 if (srcMode == SRC_CMODE) {
1112 if (!applyToSet(modules,moduleWithCName,s,&mod)) {
1113 fprintf (stderr,"No source file named %s.\n",s);
1117 if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
1118 fprintf (stderr,"No source file named %s.\n",s);
1122 sscanf(bp,"%d",&pline);
1125 if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) {
1126 fprintf(stdout,"Function \"%s\" not defined.\n",bp);
1130 if (srcMode == SRC_CMODE) {
1131 pline = func->entryline;
1132 llines = func->exitline - func->entryline + 1;
1134 pline = func->aentryline;
1135 llines = func->aexitline - func->aentryline + 1;
1141 if (!applyToSet(functions,funcWithName,s,&func)) {
1142 fprintf(stderr,"Function \"%s\" not defined.\n",s);
1147 if (srcMode == SRC_CMODE) {
1148 pline = func->entryline;
1149 llines = func->exitline - func->entryline + 1;
1151 pline = func->aentryline;
1152 llines = func->aexitline - func->aentryline + 1;
1158 /* if no line specified & we had listed
1159 before then continue from that listing */
1163 mod = cctxt->func->mod;
1164 if (srcMode == SRC_CMODE)
1165 pline = cctxt->cline;
1167 pline = cctxt->asmline;
1171 for ( i = 0 ; i < llines ; i++ ) {
1172 if (srcMode == SRC_CMODE) {
1173 if ( (pline + i) >= mod->ncLines )
1175 fprintf(stdout,"%d\t%s",pline + i,
1176 mod->cLines[pline +i]->src);
1178 if ( (pline + i) >= mod->nasmLines )
1180 fprintf(stdout,"%d\t%s",pline + i,
1181 mod->asmLines[pline +i]->src);
1184 currline = pline + i ;
1188 /*-----------------------------------------------------------------*/
1189 /* printValBasic - print value of basic types */
1190 /*-----------------------------------------------------------------*/
1191 static void printValBasic(symbol *sym,unsigned addr,char mem, int size)
1207 v.val = simGetValue(addr,mem,size);
1208 /* if this a floating point number then */
1209 if (IS_FLOAT(sym->type))
1210 fprintf(stdout,"%f",v.f);
1212 if (IS_PTR(sym->type))
1213 fprintf(stdout,"0x%x",v.val);
1215 if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) {
1216 if (IS_CHAR(sym->etype))
1217 fprintf(stdout,"'%c' %d 0x%x",v.val,v.val,v.val);
1219 if (IS_INT(sym->etype))
1220 if (IS_LONG(sym->etype))
1221 if (SPEC_USIGN(sym->etype))
1222 fprintf(stdout,"%d 0x%x",v.val,v.val);
1224 fprintf(stdout,"%d 0x%x",v.sval,v.sval);
1226 fprintf(stdout,"%d 0x%x",v.i.lo,v.i.lo);
1228 fprintf(stdout,"0x%x",v.val);
1230 fprintf(stdout,"0x%x",v.val);
1235 /*-----------------------------------------------------------------*/
1236 /* printValFunc - prints function values */
1237 /*-----------------------------------------------------------------*/
1238 static void printValFunc (symbol *sym)
1240 fprintf(stdout,"print function not yet implemented\n");
1243 /*-----------------------------------------------------------------*/
1244 /* printArrayValue - will print the values of array elements */
1245 /*-----------------------------------------------------------------*/
1246 static void printArrayValue (symbol *sym, char space, unsigned int addr)
1248 link *elem_type = sym->type->next;
1251 fprintf(stdout," { ");
1252 for (i = 0 ; i < DCL_ELEM(sym->type) ; i++) {
1253 if (IS_AGGREGATE(elem_type)) {
1254 printValAggregates(sym,elem_type,space,addr);
1256 printValBasic(sym,addr,space,getSize(elem_type));
1258 addr += getSize(elem_type);
1259 if (i != DCL_ELEM(sym->type) -1)
1260 fprintf(stdout,",");
1263 fprintf(stdout,"}\n");
1266 /*-----------------------------------------------------------------*/
1267 /* printStructValue - prints structures elements */
1268 /*-----------------------------------------------------------------*/
1269 static void printStructValue (symbol *sym,link *type, char space, unsigned int addr)
1271 symbol *fields = SPEC_STRUCT(type)->fields;
1273 fprintf(stdout," { ");
1275 fprintf(stdout,"%s = ",fields->name);
1276 if (IS_AGGREGATE(fields->type)) {
1277 printValAggregates(fields,fields->type,space, addr);
1279 printValBasic(fields,addr,space,getSize(fields->type));
1281 addr += getSize(fields->type);
1282 fields = fields->next;
1284 fprintf(stdout,"}\n");
1287 /*-----------------------------------------------------------------*/
1288 /* printValAggregates - print value of aggregates */
1289 /*-----------------------------------------------------------------*/
1290 static void printValAggregates (symbol *sym, link *type,char space,unsigned int addr)
1293 if (IS_ARRAY(type)) {
1294 printArrayValue(sym, space, addr);
1298 if (IS_STRUCT(type)) {
1299 printStructValue(sym,sym->type,space, addr);
1304 /*-----------------------------------------------------------------*/
1305 /* printSymValue - print value of a symbol */
1306 /*-----------------------------------------------------------------*/
1307 static void printSymValue (symbol *sym, context *cctxt)
1309 static int stack = 1;
1311 /* if it is on stack then compute address & fall thru */
1312 if (sym->isonstack) {
1313 symbol *bp = symLookup("bp",cctxt);
1315 fprintf(stdout,"cannot determine stack frame\n");
1319 sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
1323 /* get the value from the simulator and
1325 fprintf(stdout,"$%d = ",stack++);
1326 /* arrays & structures first */
1327 if (IS_AGGREGATE(sym->type))
1328 printValAggregates(sym,sym->type,sym->addrspace,sym->addr);
1331 if (IS_FUNC(sym->type))
1334 printValBasic(sym,sym->addr,sym->addrspace,sym->size);
1335 fprintf(stdout,"\n");
1339 /*-----------------------------------------------------------------*/
1340 /* printStructInfo - print out structure information */
1341 /*-----------------------------------------------------------------*/
1342 static void printStructInfo (structdef *sdef)
1344 symbol *field = sdef->fields ;
1349 field = field->next;
1352 fprintf(stdout,"%s %s {\n",(i ? "struct" : "union" ), sdef->tag);
1353 field = sdef->fields;
1355 printTypeInfo (field->type);
1356 fprintf(stdout," %s ;\n",field->name);
1357 field = field->next ;
1360 fprintf(stdout,"}\n");
1364 /*-----------------------------------------------------------------*/
1365 /* printTypeInfo - print out the type information */
1366 /*-----------------------------------------------------------------*/
1367 static void printTypeInfo(link *p)
1373 switch (DCL_TYPE(p)) {
1375 printTypeInfo (p->next);
1376 fprintf(stdout,"()");
1379 printTypeInfo (p->next);
1380 fprintf(stdout,"[%d]",DCL_ELEM(p));
1386 printTypeInfo (p->next);
1387 fprintf(stdout,"(_near *)");
1391 printTypeInfo (p->next);
1392 fprintf(stdout,"(_xdata *)");
1396 printTypeInfo( p->next);
1397 fprintf(stdout,"(_code *)");
1401 printTypeInfo( p->next);
1402 fprintf(stdout,"(_generic *)");
1406 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
1408 (IS_LONG(p) ? fputs("long ",stdout) :
1409 ( IS_SHORT(p) ? fputs("short ",stdout) :
1410 fputs("int ",stdout))) ;
1413 fputs("float ",stdout);
1417 fputs ("char ",stdout);
1421 fputs("void ",stdout);
1425 printStructInfo (SPEC_STRUCT(p));
1429 fputs("sbit ",stdout);
1433 fprintf(stdout,": %d" ,SPEC_BLEN(p));
1439 /*-----------------------------------------------------------------*/
1440 /* cmdPrint - print value of variable */
1441 /*-----------------------------------------------------------------*/
1442 int cmdPrint (char *s, context *cctxt)
1445 char *bp = s+strlen(s) -1;
1447 while (isspace(*s)) s++;
1449 while (isspace(*bp)) bp--;
1453 if (!cctxt || !cctxt->func) {
1454 fprintf(stdout,"No symbol \"%s\" in current context.\n",
1458 if ((sym = symLookup(s,cctxt))) {
1459 printSymValue(sym,cctxt);
1462 "No symbol \"%s\" in current context.\n",
1468 /*-----------------------------------------------------------------*/
1469 /* cmdPrintType - print type of a variable */
1470 /*-----------------------------------------------------------------*/
1471 int cmdPrintType (char *s, context *cctxt)
1474 char *bp = s+strlen(s) -1;
1476 while (isspace(*s)) s++;
1478 while (isspace(*bp)) bp--;
1482 if (!cctxt || !cctxt->func) {
1483 fprintf(stdout,"No symbol \"%s\" in current context.\n",
1488 if ((sym = symLookup(s,cctxt))) {
1489 printTypeInfo(sym->type);
1490 fprintf(stdout,"\n");
1493 "No symbol \"%s\" in current context.\n",
1499 /*-----------------------------------------------------------------*/
1500 /* cmdClrUserBp - clear user break point */
1501 /*-----------------------------------------------------------------*/
1502 int cmdClrUserBp (char *s, context *cctxt)
1505 function *func = NULL;
1507 /* clear break point location specification can be of the following
1509 a) <nothing> - break point at current location
1510 b) lineno - number of the current module
1511 c) filename:lineno - line number of the given file
1512 e) filename:function- function X in file Y (useful for static functions)
1513 f) function - function entry point
1517 fprintf(stdout,"No symbol table is loaded. Use the \"file\" command.\n");
1521 /* white space skip */
1522 while (*s && isspace(*s)) s++;
1524 /* null terminate it after stripping trailing blanks*/
1526 while (bp != s && isspace(*bp)) bp--;
1529 /* case a) nothing */
1530 /* if nothing given then current location : we know
1531 the current execution location from the currentContext */
1534 /* if current context is known */
1536 /* clear the break point @ current location */
1537 clearUSERbp (cctxt->addr);
1539 fprintf(stderr,"No default breakpoint address now.\n");
1544 /* case b) lineno */
1545 /* check if line number */
1547 /* get the lineno */
1550 /* if current context not present then we must get the module
1551 which has main & set the break point @ line number provided
1552 of that module : if current context known then set the bp
1553 at the line number given for the current module
1556 if (!cctxt->func->mod) {
1557 if (!applyToSet(functions,funcWithName,"main"))
1558 fprintf(stderr,"Function \"main\" not defined.\n");
1560 clearBPatModLine(func->mod,line);
1562 clearBPatModLine(cctxt->func->mod,line);
1568 if ((bp = strchr(s,':'))) {
1573 if (!applyToSet(modules,moduleWithCName,s,&mod)) {
1574 fprintf (stderr,"No source file named %s.\n",s);
1578 /* case c) filename:lineno */
1579 if (isdigit(*(bp +1))) {
1581 clearBPatModLine (mod,atoi(bp+1));
1585 /* case d) filename:function */
1586 if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func))
1587 fprintf(stderr,"Function \"%s\" not defined.\n",bp+1);
1589 clearBPatModLine (mod,func->entryline);
1594 /* case e) function */
1595 if (!applyToSet(functions,funcWithName,s,&func))
1596 fprintf(stderr,"Function \"%s\" not defined.\n",s);
1598 clearBPatModLine(func->mod,func->entryline);
1605 /*-----------------------------------------------------------------*/
1606 /* cmdSimulator - send command to simulator */
1607 /*-----------------------------------------------------------------*/
1608 int cmdSimulator (char *s, context *cctxt)
1612 if (strlen(s) > 80) {
1613 printf("error 3A\n");
1617 strcat(tmpstr, "\n");
1620 fprintf(stdout,"%s",simResponse());
1624 /*-----------------------------------------------------------------*/
1625 /* cmdFrame - Frame command */
1626 /*-----------------------------------------------------------------*/
1627 int cmdFrame (char *s, context *cctxt)
1631 if ((func = STACK_PEEK(callStack))) {
1632 fprintf(stdout,"#0 %s () at %s:%d\n",
1633 func->sym->name,func->mod->c_name,cctxt->cline);
1635 if (cctxt->cline < func->mod->ncLines)
1636 fprintf(stdout,"%d\t%s",
1638 func->mod->cLines[cctxt->cline]->src);
1640 fprintf(stdout,"No stack.\n");
1644 /*-----------------------------------------------------------------*/
1645 /* cmdFinish - exec till end of current function */
1646 /*-----------------------------------------------------------------*/
1647 int cmdFinish (char *s, context *ctxt)
1649 if (!ctxt || ! ctxt->func) {
1650 fprintf(stdout,"The program is not running.\n");
1654 if (srcMode == SRC_CMODE) {
1655 setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
1656 stepBpCB, ctxt->func->mod->c_name,
1657 ctxt->func->exitline);
1659 setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
1660 stepBpCB, ctxt->func->mod->asm_name,
1661 ctxt->func->aexitline);
1670 /*-----------------------------------------------------------------*/
1671 /* cmdShow - show command */
1672 /*-----------------------------------------------------------------*/
1673 int cmdShow (char *s, context *cctxt)
1675 /* skip white space */
1676 while (*s && isspace(*s)) s++ ;
1678 if (strcmp(s,"copying") == 0) {
1679 fputs(copying,stdout);
1683 if (strcmp(s,"warranty") == 0) {
1684 fputs(warranty,stdout);