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);
34 #if defined(__APPLE__) && defined(__MACH__)
36 {" GNU GENERAL PUBLIC LICENSE Version 2"};
37 static char *warranty=
41 " GNU GENERAL PUBLIC LICENSE
44 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
45 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
46 Everyone is permitted to copy and distribute verbatim copies
47 of this license document, but changing it is not allowed.
51 The licenses for most software are designed to take away your
52 freedom to share and change it. By contrast, the GNU General Public
53 License is intended to guarantee your freedom to share and change free
54 software--to make sure the software is free for all its users. This
55 General Public License applies to most of the Free Software
56 Foundation's software and to any other program whose authors commit to
57 using it. (Some other Free Software Foundation software is covered by
58 the GNU Library General Public License instead.) You can apply it to
61 When we speak of free software, we are referring to freedom, not
62 price. Our General Public Licenses are designed to make sure that you
63 have the freedom to distribute copies of free software (and charge for
64 this service if you wish), that you receive source code or can get it
65 if you want it, that you can change the software or use pieces of it
66 in new free programs; and that you know you can do these things.
68 To protect your rights, we need to make restrictions that forbid
69 anyone to deny you these rights or to ask you to surrender the rights.
70 These restrictions translate to certain responsibilities for you if you
71 distribute copies of the software, or if you modify it.
73 For example, if you distribute copies of such a program, whether
74 gratis or for a fee, you must give the recipients all the rights that
75 you have. You must make sure that they, too, receive or can get the
76 source code. And you must show them these terms so they know their
79 We protect your rights with two steps: (1) copyright the software, and
80 (2) offer you this license which gives you legal permission to copy,
81 distribute and/or modify the software.
83 Also, for each author's protection and ours, we want to make certain
84 that everyone understands that there is no warranty for this free
85 software. If the software is modified by someone else and passed on, we
86 want its recipients to know that what they have is not the original, so
87 that any problems introduced by others will not reflect on the original
90 Finally, any free program is threatened constantly by software
91 patents. We wish to avoid the danger that redistributors of a free
92 program will individually obtain patent licenses, in effect making the
93 program proprietary. To prevent this, we have made it clear that any
94 patent must be licensed for everyone's free use or not licensed at all.
96 The precise terms and conditions for copying, distribution and
99 GNU GENERAL PUBLIC LICENSE
100 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
102 0. This License applies to any program or other work which contains
103 a notice placed by the copyright holder saying it may be distributed
104 under the terms of this General Public License. The \"Program\", below,
105 refers to any such program or work, and a \"work based on the Program\"
106 means either the Program or any derivative work under copyright law:
107 that is to say, a work containing the Program or a portion of it,
108 either verbatim or with modifications and/or translated into another
109 language. (Hereinafter, translation is included without limitation in
110 the term \"modification\".) Each licensee is addressed as \"you\".
112 Activities other than copying, distribution and modification are not
113 covered by this License; they are outside its scope. The act of
114 running the Program is not restricted, and the output from the Program
115 is covered only if its contents constitute a work based on the
116 Program (independent of having been made by running the Program).
117 Whether that is true depends on what the Program does.
119 1. You may copy and distribute verbatim copies of the Program's
120 source code as you receive it, in any medium, provided that you
121 conspicuously and appropriately publish on each copy an appropriate
122 copyright notice and disclaimer of warranty; keep intact all the
123 notices that refer to this License and to the absence of any warranty;
124 and give any other recipients of the Program a copy of this License
125 along with the Program.
127 You may charge a fee for the physical act of transferring a copy, and
128 you may at your option offer warranty protection in exchange for a fee.
130 2. You may modify your copy or copies of the Program or any portion
131 of it, thus forming a work based on the Program, and copy and
132 distribute such modifications or work under the terms of Section 1
133 above, provided that you also meet all of these conditions:
135 a) You must cause the modified files to carry prominent notices
136 stating that you changed the files and the date of any change.
138 b) You must cause any work that you distribute or publish, that in
139 whole or in part contains or is derived from the Program or any
140 part thereof, to be licensed as a whole at no charge to all third
141 parties under the terms of this License.
143 c) If the modified program normally reads commands interactively
144 when run, you must cause it, when started running for such
145 interactive use in the most ordinary way, to print or display an
146 announcement including an appropriate copyright notice and a
147 notice that there is no warranty (or else, saying that you provide
148 a warranty) and that users may redistribute the program under
149 these conditions, and telling the user how to view a copy of this
150 License. (Exception: if the Program itself is interactive but
151 does not normally print such an announcement, your work based on
152 the Program is not required to print an announcement.)
154 These requirements apply to the modified work as a whole. If
155 identifiable sections of that work are not derived from the Program,
156 and can be reasonably considered independent and separate works in
157 themselves, then this License, and its terms, do not apply to those
158 sections when you distribute them as separate works. But when you
159 distribute the same sections as part of a whole which is a work based
160 on the Program, the distribution of the whole must be on the terms of
161 this License, whose permissions for other licensees extend to the
162 entire whole, and thus to each and every part regardless of who wrote it.
164 Thus, it is not the intent of this section to claim rights or contest
165 your rights to work written entirely by you; rather, the intent is to
166 exercise the right to control the distribution of derivative or
167 collective works based on the Program.
169 In addition, mere aggregation of another work not based on the Program
170 with the Program (or with a work based on the Program) on a volume of
171 a storage or distribution medium does not bring the other work under
172 the scope of this License.
174 3. You may copy and distribute the Program (or a work based on it,
175 under Section 2) in object code or executable form under the terms of
176 Sections 1 and 2 above provided that you also do one of the following:
178 a) Accompany it with the complete corresponding machine-readable
179 source code, which must be distributed under the terms of Sections
180 1 and 2 above on a medium customarily used for software interchange; or,
182 b) Accompany it with a written offer, valid for at least three
183 years, to give any third party, for a charge no more than your
184 cost of physically performing source distribution, a complete
185 machine-readable copy of the corresponding source code, to be
186 distributed under the terms of Sections 1 and 2 above on a medium
187 customarily used for software interchange; or,
189 c) Accompany it with the information you received as to the offer
190 to distribute corresponding source code. (This alternative is
191 allowed only for noncommercial distribution and only if you
192 received the program in object code or executable form with such
193 an offer, in accord with Subsection b above.)
195 The source code for a work means the preferred form of the work for
196 making modifications to it. For an executable work, complete source
197 code means all the source code for all modules it contains, plus any
198 associated interface definition files, plus the scripts used to
199 control compilation and installation of the executable. However, as a
200 special exception, the source code distributed need not include
201 anything that is normally distributed (in either source or binary
202 form) with the major components (compiler, kernel, and so on) of the
203 operating system on which the executable runs, unless that component
204 itself accompanies the executable.
206 If distribution of executable or object code is made by offering
207 access to copy from a designated place, then offering equivalent
208 access to copy the source code from the same place counts as
209 distribution of the source code, even though third parties are not
210 compelled to copy the source along with the object code.
212 4. You may not copy, modify, sublicense, or distribute the Program
213 except as expressly provided under this License. Any attempt
214 otherwise to copy, modify, sublicense or distribute the Program is
215 void, and will automatically terminate your rights under this License.
216 However, parties who have received copies, or rights, from you under
217 this License will not have their licenses terminated so long as such
218 parties remain in full compliance.
220 5. You are not required to accept this License, since you have not
221 signed it. However, nothing else grants you permission to modify or
222 distribute the Program or its derivative works. These actions are
223 prohibited by law if you do not accept this License. Therefore, by
224 modifying or distributing the Program (or any work based on the
225 Program), you indicate your acceptance of this License to do so, and
226 all its terms and conditions for copying, distributing or modifying
227 the Program or works based on it.
229 6. Each time you redistribute the Program (or any work based on the
230 Program), the recipient automatically receives a license from the
231 original licensor to copy, distribute or modify the Program subject to
232 these terms and conditions. You may not impose any further
233 restrictions on the recipients' exercise of the rights granted herein.
234 You are not responsible for enforcing compliance by third parties to
237 7. If, as a consequence of a court judgment or allegation of patent
238 infringement or for any other reason (not limited to patent issues),
239 conditions are imposed on you (whether by court order, agreement or
240 otherwise) that contradict the conditions of this License, they do not
241 excuse you from the conditions of this License. If you cannot
242 distribute so as to satisfy simultaneously your obligations under this
243 License and any other pertinent obligations, then as a consequence you
244 may not distribute the Program at all. For example, if a patent
245 license would not permit royalty-free redistribution of the Program by
246 all those who receive copies directly or indirectly through you, then
247 the only way you could satisfy both it and this License would be to
248 refrain entirely from distribution of the Program.
250 If any portion of this section is held invalid or unenforceable under
251 any particular circumstance, the balance of the section is intended to
252 apply and the section as a whole is intended to apply in other
255 It is not the purpose of this section to induce you to infringe any
256 patents or other property right claims or to contest validity of any
257 such claims; this section has the sole purpose of protecting the
258 integrity of the free software distribution system, which is
259 implemented by public license practices. Many people have made
260 generous contributions to the wide range of software distributed
261 through that system in reliance on consistent application of that
262 system; it is up to the author/donor to decide if he or she is willing
263 to distribute software through any other system and a licensee cannot
266 This section is intended to make thoroughly clear what is believed to
267 be a consequence of the rest of this License.
269 8. If the distribution and/or use of the Program is restricted in
270 certain countries either by patents or by copyrighted interfaces, the
271 original copyright holder who places the Program under this License
272 may add an explicit geographical distribution limitation excluding
273 those countries, so that distribution is permitted only in or among
274 countries not thus excluded. In such case, this License incorporates
275 the limitation as if written in the body of this License.
277 9. The Free Software Foundation may publish revised and/or new versions
278 of the General Public License from time to time. Such new versions will
279 be similar in spirit to the present version, but may differ in detail to
280 address new problems or concerns.
282 Each version is given a distinguishing version number. If the Program
283 specifies a version number of this License which applies to it and \"any
284 later version\", you have the option of following the terms and conditions
285 either of that version or of any later version published by the Free
286 Software Foundation. If the Program does not specify a version number of
287 this License, you may choose any version ever published by the Free Software
290 10. If you wish to incorporate parts of the Program into other free
291 programs whose distribution conditions are different, write to the author
292 to ask for permission. For software which is copyrighted by the Free
293 Software Foundation, write to the Free Software Foundation; we sometimes
294 make exceptions for this. Our decision will be guided by the two goals
295 of preserving the free status of all derivatives of our free software and
296 of promoting the sharing and reuse of software generally.
298 static char *warranty=
301 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
302 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
303 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
304 PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
305 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
306 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
307 TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
308 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
309 REPAIR OR CORRECTION.
311 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
312 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
313 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
314 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
315 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
316 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
317 YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
318 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
319 POSSIBILITY OF SUCH DAMAGES.
323 static void printTypeInfo(link *);
324 static void printValAggregates (symbol *,link *,char,unsigned int);
326 int srcMode = SRC_CMODE ;
328 /*-----------------------------------------------------------------*/
329 /* funcWithName - returns function with name */
330 /*-----------------------------------------------------------------*/
331 DEFSETFUNC(funcWithName)
333 function *func = item;
335 V_ARG(function **,funcp);
340 if (strcmp(func->sym->name,name) == 0) {
348 /*-----------------------------------------------------------------*/
349 /* setBPatModLine - set break point at the line specified for the */
350 /*-----------------------------------------------------------------*/
351 static void setBPatModLine (module *mod, int line)
353 /* look for the first executable line after the line
354 specified & get the break point there */
355 if (srcMode == SRC_CMODE && line > mod->ncLines) {
356 fprintf(stderr,"No line %d in file \"%s\".\n",
361 if (srcMode == SRC_AMODE && line > mod->nasmLines) {
362 fprintf(stderr,"No line %d in file \"%s\".\n",
367 for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ;
369 if (srcMode == SRC_CMODE) {
370 if (mod->cLines[line]->addr) {
371 setBreakPoint (mod->cLines[line]->addr, CODE, USER,
372 userBpCB, mod->c_name, line);
377 if (mod->asmLines[line]->addr) {
378 setBreakPoint (mod->asmLines[line]->addr, CODE, USER,
379 userBpCB, mod->asm_name, line);
388 /*-----------------------------------------------------------------*/
389 /* clearBPatModLine - clr break point at the line specified */
390 /*-----------------------------------------------------------------*/
391 static void clearBPatModLine (module *mod, int line)
393 /* look for the first executable line after the line
394 specified & get the break point there */
395 if (srcMode == SRC_CMODE && line > mod->ncLines) {
396 fprintf(stderr,"No line %d in file \"%s\".\n",
401 if (srcMode == SRC_AMODE && line > mod->ncLines) {
402 fprintf(stderr,"No line %d in file \"%s\".\n",
407 for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ;
409 if (srcMode == SRC_CMODE)
410 if (mod->cLines[line]->addr) {
411 clearUSERbp (mod->cLines[line]->addr);
415 if (mod->asmLines[line]->addr) {
416 clearUSERbp (mod->asmLines[line]->addr);
424 /*-----------------------------------------------------------------*/
425 /* funcWithNameModule - returns functions with a name module combo */
426 /*-----------------------------------------------------------------*/
427 DEFSETFUNC(funcWithNameModule)
429 function *func = item;
432 V_ARG(function **,funcp);
437 if (strcmp(func->sym->name,fname) == 0 &&
438 strcmp(func->mod->c_name,mname) == 0) {
446 /*-----------------------------------------------------------------*/
447 /* funcInAddr - given an address returns the function */
448 /*-----------------------------------------------------------------*/
449 DEFSETFUNC(funcInAddr)
451 function *func = item;
452 V_ARG(unsigned int,addr);
453 V_ARG(function **,funcp);
458 /* in the address range */
459 if (func->sym->addr <= addr &&
460 func->sym->eaddr >= addr) {
469 /*-----------------------------------------------------------------*/
470 /* setStepBp - will set STEP Bp @ function entry points */
471 /*-----------------------------------------------------------------*/
472 DEFSETFUNC(setStepBp)
474 function *func = item;
476 if (func->sym && func->sym->addr ) {
478 /* set the entry break point */
479 setBreakPoint (func->sym->addr , CODE , STEP ,
480 stepBpCB ,func->mod->c_name , func->entryline);
488 /*-----------------------------------------------------------------*/
489 /* setStepEPBp - sets a given type of bp @ the execution point */
490 /*-----------------------------------------------------------------*/
491 DEFSETFUNC(setStepEPBp)
497 setBreakPoint (ep->addr, CODE, bptype,
498 stepBpCB, mname, ep->line);
502 /*-----------------------------------------------------------------*/
503 /* setNextEPBp - sets a given type of bp @ the execution point */
504 /*-----------------------------------------------------------------*/
505 DEFSETFUNC(setNextEPBp)
511 setBreakPoint (ep->addr, CODE, bptype,
512 nextBpCB, mname, ep->line);
516 /*-----------------------------------------------------------------*/
517 /* lineAtAddr - for execution points returns the one with addr */
518 /*-----------------------------------------------------------------*/
519 DEFSETFUNC(lineAtAddr)
522 V_ARG(unsigned int,addr);
527 /* address must be an exact match */
528 if (ep->addr == addr) {
541 /*-----------------------------------------------------------------*/
542 /* discoverContext - find out the current context of the bp */
543 /*-----------------------------------------------------------------*/
544 context *discoverContext (unsigned addr)
546 function *func = NULL;
549 /* find the function we are in */
550 if (!applyToSet(functions,funcInAddr,addr,&func)) {
551 fprintf(stderr, "Error?:discoverContext: cannot apply to set!\n");
555 currCtxt->func = func;
556 currCtxt->addr = func->laddr = addr;
557 currCtxt->modName = func->modName;
559 /* find the c line number */
560 if(applyToSet(func->cfpoints,lineAtAddr,addr,
561 &line,&currCtxt->block,&currCtxt->level))
562 currCtxt->cline = func->lline = line;
564 currCtxt->cline = func->exitline;
566 /* find the asm line number */
568 if (applyToSet(func->afpoints,lineAtAddr,addr,
570 currCtxt->asmline = line;
572 currCtxt->asmline = -1;
578 /*-----------------------------------------------------------------*/
579 /* simGo - send 'go' cmd to simulator and wait till a break occurs */
580 /*-----------------------------------------------------------------*/
581 void simGo (unsigned int gaddr)
586 static int initial_break_flag = 0;
589 addr = simGoTillBp (gaddr);
591 /* got the pc for the break point now first
592 discover the program context i.e. module, function
593 linenumber of the source etc, etc etc */
594 ctxt = discoverContext (addr);
596 /* dispatch all the break point call back functions */
597 rv = dispatchCB (addr,ctxt);
601 /* the dispatch call back function will return
602 non-zero if an user break point has been hit
603 if not then we continue with the execution
606 if (!initial_break_flag) {
607 initial_break_flag = 1; // kludge to stop only at first run
608 fprintf(stdout, "Stopping at entry. You can now list and set breakpoints\n");
616 // I took this out, after running "run" it would just keep re-running
617 // even after a lot of break points hit. For some reason above code
618 // not triggering(dispatchCB). This seems to be by design, startup adds
619 // a bunch of breakpoints-but they are not USER breakpoints. Perhaps the
620 // debugger changed with its implementation of "go"("run"). It seems we
621 // need to add a "next" or "step" followed by a "run"...
622 // I added a "step" in simi.c when we want a resume function, this seems
625 // still there is question of how do we stop it initially, since
626 // it must be started before it can get a context. If so, we would
627 // want it to just run up to an initial entry point you'd think...
628 // I don't see why we can't set breakpoints before an initial run,
629 // this does not seem right to me.
631 // line #'s are a bit off too.
641 /*-----------------------------------------------------------------*/
642 /* cmdSetUserBp - set break point at the user specified location */
643 /*-----------------------------------------------------------------*/
644 int cmdSetUserBp (char *s, context *cctxt)
647 function *func = NULL;
649 /* user break point location specification can be of the following
651 a) <nothing> - break point at current location
652 b) lineno - number of the current module
653 c) filename:lineno - line number of the given file
654 e) filename:function- function X in file Y (useful for static functions)
655 f) function - function entry point
659 fprintf(stdout,"No symbol table is loaded. Use the \"file\" command.\n");
662 /* white space skip */
663 while (*s && isspace(*s)) s++;
665 /* null terminate it after stripping trailing blanks*/
667 while (bp != s && isspace(*bp)) bp--;
670 /* case a) nothing */
671 /* if nothing given then current location : we know
672 the current execution location from the currentContext */
675 /* if current context is known */
677 if (srcMode == SRC_CMODE)
678 /* set the break point */
679 setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
680 cctxt->func->mod->c_name, cctxt->cline);
682 setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
683 cctxt->func->mod->asm_name, cctxt->asmline);
687 fprintf(stderr,"No default breakpoint address now.\n");
693 /* check if line number */
698 /* if current context not present then we must get the module
699 which has main & set the break point @ line number provided
700 of that module : if current context known then set the bp
701 at the line number given for the current module
704 if (!cctxt->func->mod) {
705 if (!applyToSet(functions,funcWithName,"main"))
706 fprintf(stderr,"Function \"main\" not defined.\n");
708 setBPatModLine(func->mod,line);
710 setBPatModLine(cctxt->func->mod,line);
712 fprintf(stdout,"No symbol information currently\n");
718 if ((bp = strchr(s,':'))) {
723 if (srcMode == SRC_CMODE) {
724 if (!applyToSet(modules,moduleWithCName,s,&mod)) {
725 fprintf (stderr,"No source file named %s.\n",s);
729 if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
730 fprintf (stderr,"No source file named %s.\n",s);
735 /* case c) filename:lineno */
736 if (isdigit(*(bp +1))) {
738 setBPatModLine (mod,atoi(bp+1));
742 /* case d) filename:function */
743 if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func))
744 fprintf(stderr,"Function \"%s\" not defined.\n",bp+1);
747 (srcMode == SRC_CMODE ?
754 /* case e) function */
755 if (!applyToSet(functions,funcWithName,s,&func))
756 fprintf(stderr,"Function \"%s\" not defined.\n",s);
758 setBPatModLine(func->mod,
759 (srcMode == SRC_CMODE ?
767 /*-----------------------------------------------------------------*/
768 /* cmdListAsm - list assembler source code */
769 /*-----------------------------------------------------------------*/
770 int cmdListAsm (char *s, context *cctxt)
772 fprintf(stderr,"'listasm' command not yet implemented\n");
776 /*-----------------------------------------------------------------*/
777 /* cmdSetOption - set debugger options */
778 /*-----------------------------------------------------------------*/
779 int cmdSetOption (char *s, context *cctxt)
781 while (*s && isspace(*s)) s++;
782 if (strncmp(s,"srcmode",7) == 0 ) {
783 if (srcMode == SRC_CMODE)
787 fprintf(stderr,"source mode set to '%s'\n",
788 (srcMode == SRC_CMODE ? "C" : "asm"));
792 fprintf(stderr,"'set %s' command not yet implemented\n",s);
796 /*-----------------------------------------------------------------*/
797 /* cmdContinue - continue till next break point */
798 /*-----------------------------------------------------------------*/
799 int cmdContinue (char *s, context *cctxt)
801 if (!cctxt || !cctxt->func) {
802 fprintf(stdout,"The program is not being run.\n");
806 fprintf(stdout,"Continuing.\n");
811 /*-----------------------------------------------------------------*/
812 /* cmdDelUserBp - delete user break point */
813 /*-----------------------------------------------------------------*/
814 int cmdDelUserBp (char *s, context *cctxt)
817 while (isspace(*s)) s++;
822 fprintf (stdout,"Delete all breakpoints? (y or n) ");
824 fgets(buffer,sizeof(buffer),stdin);
825 if (toupper(buffer[0]) == 'Y')
831 /* determine the break point number */
832 if (sscanf(s,"%d",&bpnum) == 1)
838 /*-----------------------------------------------------------------*/
839 /* cmdStep - single step thru C source file */
840 /*-----------------------------------------------------------------*/
841 int cmdStep (char *s, context *cctxt)
843 function *func = NULL;
845 if (!cctxt || !cctxt->func || !cctxt->func->mod)
846 fprintf(stdout,"The program is not being run.\n");
848 /* if we are @ the end of a function then set
849 break points at execution points of the
850 function in the call stack... */
851 if (cctxt->addr == cctxt->func->sym->eaddr) {
852 if ((func = STACK_PEEK(callStack))) {
853 if (srcMode == SRC_CMODE)
854 applyToSet (func->cfpoints,setStepEPBp,STEP,
857 applyToSet (func->afpoints,setStepEPBp,STEP,
858 func->mod->asm_name);
861 /* set breakpoints at all function entry points
862 and all exepoints of this functions & for
863 all functions one up in the call stack */
865 /* all function entry points */
866 applyToSet(functions,setStepBp);
868 if (srcMode == SRC_CMODE) {
869 /* for all execution points in this function */
870 applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP,
871 cctxt->func->mod->c_name);
873 /* set a break point @ the current function's
875 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP ,
876 stepBpCB, cctxt->func->mod->c_name,
877 cctxt->func->exitline);
879 /* now break point @ callers execution points */
880 if ((func = STACK_PPEEK(callStack))) {
881 applyToSet (func->cfpoints,setStepEPBp,STEP,
883 /* set bp @ callers exit point */
884 setBreakPoint (func->sym->eaddr, CODE, STEP ,
885 stepBpCB, func->mod->c_name,
889 /* for all execution points in this function */
890 applyToSet(cctxt->func->afpoints,setStepEPBp,STEP,
891 cctxt->func->mod->asm_name);
893 /* set a break point @ the current function's
895 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP ,
896 stepBpCB, cctxt->func->mod->asm_name,
897 cctxt->func->aexitline);
899 /* now break point @ callers execution points */
900 if ((func = STACK_PPEEK(callStack))) {
902 applyToSet (func->afpoints,setStepEPBp,STEP,
903 func->mod->asm_name);
905 /* set bp @ callers exit point */
906 setBreakPoint (func->sym->eaddr, CODE, STEP ,
907 stepBpCB, func->mod->asm_name,
918 /*-----------------------------------------------------------------*/
919 /* cmdNext - next executable C statement file */
920 /*-----------------------------------------------------------------*/
921 int cmdNext (char *s, context *cctxt)
923 function *func = NULL;
924 /* next is almost the same as step except we don't
925 we don't set break point for all function entry
927 if (!cctxt || !cctxt->func || !cctxt->func->mod)
928 fprintf(stdout,"The program is not being run.\n");
931 /* if we are @ the end of a function then set
932 break points at execution points of the
933 function in the call stack... */
934 if (cctxt->addr == cctxt->func->sym->eaddr) {
935 if ((func = STACK_PEEK(callStack))) {
936 if (srcMode == SRC_CMODE)
937 applyToSet (func->cfpoints,setStepEPBp,STEP,
940 applyToSet (func->afpoints,setStepEPBp,STEP,
941 func->mod->asm_name);
944 if (srcMode == SRC_CMODE) {
945 /* for all execution points in this function */
946 applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT,
947 cctxt->func->mod->c_name);
948 /* set a break point @ the current function's
950 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT ,
951 nextBpCB, cctxt->func->mod->c_name,
952 cctxt->func->exitline);
954 /* now break point @ callers execution points */
955 if ((func = STACK_PPEEK(callStack))) {
956 applyToSet (func->cfpoints,setNextEPBp,NEXT ,
958 /* set bp @ callers exit point */
959 setBreakPoint (func->sym->eaddr, CODE, NEXT ,
960 stepBpCB, func->mod->c_name,
964 /* for all execution points in this function */
965 applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT,
966 cctxt->func->mod->asm_name);
967 /* set a break point @ the current function's
969 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT ,
970 nextBpCB, cctxt->func->mod->asm_name,
971 cctxt->func->aexitline);
973 /* now break point @ callers execution points */
974 if ((func = STACK_PPEEK(callStack))) {
975 applyToSet (func->cfpoints,setNextEPBp,NEXT ,
976 func->mod->asm_name);
977 /* set bp @ callers exit point */
978 setBreakPoint (func->sym->eaddr, CODE, NEXT ,
979 stepBpCB, func->mod->asm_name,
989 /*-----------------------------------------------------------------*/
990 /* cmdRun - run till next break point */
991 /*-----------------------------------------------------------------*/
992 int cmdRun (char *s, context *cctxt)
995 if (!cctxt || !cctxt->func || !cctxt->func->mod) {
996 fprintf(stdout,"Starting program\n");
1001 "The program being debugged has been started already.\n");
1002 fprintf(stdout,"Start it from the beginning? (y or n) ");
1005 fgets(buff,sizeof(buff),stdin);
1006 if (toupper(buff[0]) == 'Y') {
1015 /*-----------------------------------------------------------------*/
1016 /* infoStack - print call stack information */
1017 /*-----------------------------------------------------------------*/
1018 static void infoStack(context *ctxt)
1023 STACK_STARTWALK(callStack) ;
1024 while ((func = STACK_WALK(callStack))) {
1026 fprintf(stdout,"#%d 0x%04x %s () at %s:%d\n",i++,
1027 func->laddr,func->sym->name,
1028 func->mod->c_name,func->lline);
1033 /*-----------------------------------------------------------------*/
1034 /* cmdInfo - info command */
1035 /*-----------------------------------------------------------------*/
1036 int cmdInfo (char *s, context *cctxt)
1038 while (isspace(*s)) s++;
1040 /* list all break points */
1041 if (strcmp(s,"break") == 0) {
1046 /* info frame same as frame */
1047 if (strcmp(s,"frame") == 0) {
1052 /* info stack display call stack */
1053 if (strcmp(s,"stack") == 0) {
1058 /* info stack display call stack */
1059 if (strcmp(s,"registers") == 0) {
1060 fprintf(stdout,"%s",simRegs());
1064 fprintf(stdout,"Undefined info command: \"%s\". Try \"help\n",s);
1069 /*-----------------------------------------------------------------*/
1070 /* cmdQuit - quit debugging */
1071 /*-----------------------------------------------------------------*/
1072 int cmdQuit (char *s, context *cctxt)
1079 /*-----------------------------------------------------------------*/
1080 /* cmdListSrc - list src */
1081 /*-----------------------------------------------------------------*/
1082 int cmdListSrc (char *s, context *cctxt)
1084 static int currline = 0;
1087 static module *mod = NULL;
1088 int llines = listLines;
1090 while (*s && isspace(*s)) s++;
1092 /* if the user has spcified line numer then the line number
1093 can be of the following formats
1094 LINE - just line number
1095 FILE:LINE - filename line number
1096 FUNCTION - list a function
1097 FILE:FUNCTION - function in file */
1098 if (!cctxt || !cctxt->func || !cctxt->func->mod) {
1099 fprintf(stdout,"No symbol table is loaded. Use the \"file\" command.\n");
1105 sscanf(s,"%d",&pline);
1106 mod = cctxt->func->mod;
1110 function *func = NULL;
1112 /* if ':' present then FILE:LINE || FILE:FUNCTION */
1113 if ((bp = strchr(s,':'))) {
1118 if (srcMode == SRC_CMODE) {
1119 if (!applyToSet(modules,moduleWithCName,s,&mod)) {
1120 fprintf (stderr,"No source file named %s.\n",s);
1124 if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
1125 fprintf (stderr,"No source file named %s.\n",s);
1129 sscanf(bp,"%d",&pline);
1132 if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) {
1133 fprintf(stdout,"Function \"%s\" not defined.\n",bp);
1137 if (srcMode == SRC_CMODE) {
1138 pline = func->entryline;
1139 llines = func->exitline - func->entryline + 1;
1141 pline = func->aentryline;
1142 llines = func->aexitline - func->aentryline + 1;
1148 if (!applyToSet(functions,funcWithName,s,&func)) {
1149 fprintf(stderr,"Function \"%s\" not defined.\n",s);
1154 if (srcMode == SRC_CMODE) {
1155 pline = func->entryline;
1156 llines = func->exitline - func->entryline + 1;
1158 pline = func->aentryline;
1159 llines = func->aexitline - func->aentryline + 1;
1165 /* if no line specified & we had listed
1166 before then continue from that listing */
1170 mod = cctxt->func->mod;
1171 if (srcMode == SRC_CMODE)
1172 pline = cctxt->cline;
1174 pline = cctxt->asmline;
1178 for ( i = 0 ; i < llines ; i++ ) {
1179 if (srcMode == SRC_CMODE) {
1180 if ( (pline + i) >= mod->ncLines )
1182 fprintf(stdout,"%d\t%s",pline + i,
1183 mod->cLines[pline +i]->src);
1185 if ( (pline + i) >= mod->nasmLines )
1187 fprintf(stdout,"%d\t%s",pline + i,
1188 mod->asmLines[pline +i]->src);
1191 currline = pline + i ;
1195 /*-----------------------------------------------------------------*/
1196 /* printValBasic - print value of basic types */
1197 /*-----------------------------------------------------------------*/
1198 static void printValBasic(symbol *sym,unsigned addr,char mem, int size)
1214 v.val = simGetValue(addr,mem,size);
1215 /* if this a floating point number then */
1216 if (IS_FLOAT(sym->type))
1217 fprintf(stdout,"%f",v.f);
1219 if (IS_PTR(sym->type))
1220 fprintf(stdout,"0x%x",v.val);
1222 if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) {
1223 if (IS_CHAR(sym->etype))
1224 fprintf(stdout,"'%c' %d 0x%x",v.val,v.val,v.val);
1226 if (IS_INT(sym->etype))
1227 if (IS_LONG(sym->etype))
1228 if (SPEC_USIGN(sym->etype))
1229 fprintf(stdout,"%d 0x%x",v.val,v.val);
1231 fprintf(stdout,"%d 0x%x",v.sval,v.sval);
1233 fprintf(stdout,"%d 0x%x",v.i.lo,v.i.lo);
1235 fprintf(stdout,"0x%x",v.val);
1237 fprintf(stdout,"0x%x",v.val);
1242 /*-----------------------------------------------------------------*/
1243 /* printValFunc - prints function values */
1244 /*-----------------------------------------------------------------*/
1245 static void printValFunc (symbol *sym)
1247 fprintf(stdout,"print function not yet implemented\n");
1250 /*-----------------------------------------------------------------*/
1251 /* printArrayValue - will print the values of array elements */
1252 /*-----------------------------------------------------------------*/
1253 static void printArrayValue (symbol *sym, char space, unsigned int addr)
1255 link *elem_type = sym->type->next;
1258 fprintf(stdout," { ");
1259 for (i = 0 ; i < DCL_ELEM(sym->type) ; i++) {
1260 if (IS_AGGREGATE(elem_type)) {
1261 printValAggregates(sym,elem_type,space,addr);
1263 printValBasic(sym,addr,space,getSize(elem_type));
1265 addr += getSize(elem_type);
1266 if (i != DCL_ELEM(sym->type) -1)
1267 fprintf(stdout,",");
1270 fprintf(stdout,"}\n");
1273 /*-----------------------------------------------------------------*/
1274 /* printStructValue - prints structures elements */
1275 /*-----------------------------------------------------------------*/
1276 static void printStructValue (symbol *sym,link *type, char space, unsigned int addr)
1278 symbol *fields = SPEC_STRUCT(type)->fields;
1280 fprintf(stdout," { ");
1282 fprintf(stdout,"%s = ",fields->name);
1283 if (IS_AGGREGATE(fields->type)) {
1284 printValAggregates(fields,fields->type,space, addr);
1286 printValBasic(fields,addr,space,getSize(fields->type));
1288 addr += getSize(fields->type);
1289 fields = fields->next;
1291 fprintf(stdout,"}\n");
1294 /*-----------------------------------------------------------------*/
1295 /* printValAggregates - print value of aggregates */
1296 /*-----------------------------------------------------------------*/
1297 static void printValAggregates (symbol *sym, link *type,char space,unsigned int addr)
1300 if (IS_ARRAY(type)) {
1301 printArrayValue(sym, space, addr);
1305 if (IS_STRUCT(type)) {
1306 printStructValue(sym,sym->type,space, addr);
1311 /*-----------------------------------------------------------------*/
1312 /* printSymValue - print value of a symbol */
1313 /*-----------------------------------------------------------------*/
1314 static void printSymValue (symbol *sym, context *cctxt)
1316 static int stack = 1;
1318 /* if it is on stack then compute address & fall thru */
1319 if (sym->isonstack) {
1320 symbol *bp = symLookup("bp",cctxt);
1322 fprintf(stdout,"cannot determine stack frame\n");
1326 sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
1330 /* get the value from the simulator and
1332 fprintf(stdout,"$%d = ",stack++);
1333 /* arrays & structures first */
1334 if (IS_AGGREGATE(sym->type))
1335 printValAggregates(sym,sym->type,sym->addrspace,sym->addr);
1338 if (IS_FUNC(sym->type))
1341 printValBasic(sym,sym->addr,sym->addrspace,sym->size);
1342 fprintf(stdout,"\n");
1346 /*-----------------------------------------------------------------*/
1347 /* printStructInfo - print out structure information */
1348 /*-----------------------------------------------------------------*/
1349 static void printStructInfo (structdef *sdef)
1351 symbol *field = sdef->fields ;
1356 field = field->next;
1359 fprintf(stdout,"%s %s {\n",(i ? "struct" : "union" ), sdef->tag);
1360 field = sdef->fields;
1362 printTypeInfo (field->type);
1363 fprintf(stdout," %s ;\n",field->name);
1364 field = field->next ;
1367 fprintf(stdout,"}\n");
1371 /*-----------------------------------------------------------------*/
1372 /* printTypeInfo - print out the type information */
1373 /*-----------------------------------------------------------------*/
1374 static void printTypeInfo(link *p)
1380 switch (DCL_TYPE(p)) {
1382 printTypeInfo (p->next);
1383 fprintf(stdout,"()");
1386 printTypeInfo (p->next);
1387 fprintf(stdout,"[%d]",DCL_ELEM(p));
1393 printTypeInfo (p->next);
1394 fprintf(stdout,"(_near *)");
1398 printTypeInfo (p->next);
1399 fprintf(stdout,"(_xdata *)");
1403 printTypeInfo( p->next);
1404 fprintf(stdout,"(_code *)");
1408 printTypeInfo( p->next);
1409 fprintf(stdout,"(_generic *)");
1413 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
1415 (IS_LONG(p) ? fputs("long ",stdout) :
1416 ( IS_SHORT(p) ? fputs("short ",stdout) :
1417 fputs("int ",stdout))) ;
1420 fputs("float ",stdout);
1424 fputs ("char ",stdout);
1428 fputs("void ",stdout);
1432 printStructInfo (SPEC_STRUCT(p));
1436 fputs("sbit ",stdout);
1440 fprintf(stdout,": %d" ,SPEC_BLEN(p));
1446 /*-----------------------------------------------------------------*/
1447 /* cmdPrint - print value of variable */
1448 /*-----------------------------------------------------------------*/
1449 int cmdPrint (char *s, context *cctxt)
1452 char *bp = s+strlen(s) -1;
1454 while (isspace(*s)) s++;
1456 while (isspace(*bp)) bp--;
1460 if (!cctxt || !cctxt->func) {
1461 fprintf(stdout,"No symbol \"%s\" in current context.\n",
1465 if ((sym = symLookup(s,cctxt))) {
1466 printSymValue(sym,cctxt);
1469 "No symbol \"%s\" in current context.\n",
1475 /*-----------------------------------------------------------------*/
1476 /* cmdPrintType - print type of a variable */
1477 /*-----------------------------------------------------------------*/
1478 int cmdPrintType (char *s, context *cctxt)
1481 char *bp = s+strlen(s) -1;
1483 while (isspace(*s)) s++;
1485 while (isspace(*bp)) bp--;
1489 if (!cctxt || !cctxt->func) {
1490 fprintf(stdout,"No symbol \"%s\" in current context.\n",
1495 if ((sym = symLookup(s,cctxt))) {
1496 printTypeInfo(sym->type);
1497 fprintf(stdout,"\n");
1500 "No symbol \"%s\" in current context.\n",
1506 /*-----------------------------------------------------------------*/
1507 /* cmdClrUserBp - clear user break point */
1508 /*-----------------------------------------------------------------*/
1509 int cmdClrUserBp (char *s, context *cctxt)
1512 function *func = NULL;
1514 /* clear break point location specification can be of the following
1516 a) <nothing> - break point at current location
1517 b) lineno - number of the current module
1518 c) filename:lineno - line number of the given file
1519 e) filename:function- function X in file Y (useful for static functions)
1520 f) function - function entry point
1524 fprintf(stdout,"No symbol table is loaded. Use the \"file\" command.\n");
1528 /* white space skip */
1529 while (*s && isspace(*s)) s++;
1531 /* null terminate it after stripping trailing blanks*/
1533 while (bp != s && isspace(*bp)) bp--;
1536 /* case a) nothing */
1537 /* if nothing given then current location : we know
1538 the current execution location from the currentContext */
1541 /* if current context is known */
1543 /* clear the break point @ current location */
1544 clearUSERbp (cctxt->addr);
1546 fprintf(stderr,"No default breakpoint address now.\n");
1551 /* case b) lineno */
1552 /* check if line number */
1554 /* get the lineno */
1557 /* if current context not present then we must get the module
1558 which has main & set the break point @ line number provided
1559 of that module : if current context known then set the bp
1560 at the line number given for the current module
1563 if (!cctxt->func->mod) {
1564 if (!applyToSet(functions,funcWithName,"main"))
1565 fprintf(stderr,"Function \"main\" not defined.\n");
1567 clearBPatModLine(func->mod,line);
1569 clearBPatModLine(cctxt->func->mod,line);
1575 if ((bp = strchr(s,':'))) {
1580 if (!applyToSet(modules,moduleWithCName,s,&mod)) {
1581 fprintf (stderr,"No source file named %s.\n",s);
1585 /* case c) filename:lineno */
1586 if (isdigit(*(bp +1))) {
1588 clearBPatModLine (mod,atoi(bp+1));
1592 /* case d) filename:function */
1593 if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func))
1594 fprintf(stderr,"Function \"%s\" not defined.\n",bp+1);
1596 clearBPatModLine (mod,func->entryline);
1601 /* case e) function */
1602 if (!applyToSet(functions,funcWithName,s,&func))
1603 fprintf(stderr,"Function \"%s\" not defined.\n",s);
1605 clearBPatModLine(func->mod,func->entryline);
1612 /*-----------------------------------------------------------------*/
1613 /* cmdSimulator - send command to simulator */
1614 /*-----------------------------------------------------------------*/
1615 int cmdSimulator (char *s, context *cctxt)
1619 if (strlen(s) > 80) {
1620 printf("error 3A\n");
1624 strcat(tmpstr, "\n");
1627 fprintf(stdout,"%s",simResponse());
1631 /*-----------------------------------------------------------------*/
1632 /* cmdFrame - Frame command */
1633 /*-----------------------------------------------------------------*/
1634 int cmdFrame (char *s, context *cctxt)
1638 if ((func = STACK_PEEK(callStack))) {
1639 fprintf(stdout,"#0 %s () at %s:%d\n",
1640 func->sym->name,func->mod->c_name,cctxt->cline);
1642 if (cctxt->cline < func->mod->ncLines)
1643 fprintf(stdout,"%d\t%s",
1645 func->mod->cLines[cctxt->cline]->src);
1647 fprintf(stdout,"No stack.\n");
1651 /*-----------------------------------------------------------------*/
1652 /* cmdFinish - exec till end of current function */
1653 /*-----------------------------------------------------------------*/
1654 int cmdFinish (char *s, context *ctxt)
1656 if (!ctxt || ! ctxt->func) {
1657 fprintf(stdout,"The program is not running.\n");
1661 if (srcMode == SRC_CMODE) {
1662 setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
1663 stepBpCB, ctxt->func->mod->c_name,
1664 ctxt->func->exitline);
1666 setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
1667 stepBpCB, ctxt->func->mod->asm_name,
1668 ctxt->func->aexitline);
1677 /*-----------------------------------------------------------------*/
1678 /* cmdShow - show command */
1679 /*-----------------------------------------------------------------*/
1680 int cmdShow (char *s, context *cctxt)
1682 /* skip white space */
1683 while (*s && isspace(*s)) s++ ;
1685 if (strcmp(s,"copying") == 0) {
1686 fputs(copying,stdout);
1690 if (strcmp(s,"warranty") == 0) {
1691 fputs(warranty,stdout);