* src/SDCCsymt.c (initCSupport): fix compile warning on Cygwin
[fw/sdcc] / debugger / mcs51 / cmd.c
1 /*-------------------------------------------------------------------------
2     cmd.c - source  file for debugger command execution
3
4               Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
5
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
9    later version.
10    
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.
15    
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.
19    
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 -------------------------------------------------------------------------*/
24
25 #include "sdcdb.h"
26 #include "symtab.h"
27 #include "simi.h"
28 #include "break.h"
29 #include "cmd.h"
30
31 /* default number of lines to list out */
32 int listLines = 16;
33
34 /* mainly used to retain a reference to the active module being
35    listed.  May be used as a general context for other commands if
36    no better context is available */
37 static module *list_mod = NULL;
38
39 EXTERN_STACK_DCL(callStack,function *,1024);
40
41 #if defined(__APPLE__) && defined(__MACH__)
42 static char *copying=
43 {" GNU GENERAL PUBLIC LICENSE Version 2"};
44 static char *warranty=
45 {" NO WARRANTY"};
46 #else
47 static char *copying=
48 "                   GNU GENERAL PUBLIC LICENSE\n"
49 "                       Version 2, June 1991\n"
50 "\n"
51 " Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n"
52 " 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
53 " Everyone is permitted to copy and distribute verbatim copies\n"
54 " of this license document, but changing it is not allowed.\n"
55 "\n"
56 "                            Preamble\n"
57 "\n"
58 "  The licenses for most software are designed to take away your\n"
59 "freedom to share and change it.  By contrast, the GNU General Public\n"
60 "License is intended to guarantee your freedom to share and change free\n"
61 "software--to make sure the software is free for all its users.  This\n"
62 "General Public License applies to most of the Free Software\n"
63 "Foundation's software and to any other program whose authors commit to\n"
64 "using it.  (Some other Free Software Foundation software is covered by\n"
65 "the GNU Library General Public License instead.)  You can apply it to\n"
66 "your programs, too.\n"
67 "\n"
68 "  When we speak of free software, we are referring to freedom, not\n"
69 "price.  Our General Public Licenses are designed to make sure that you\n"
70 "have the freedom to distribute copies of free software (and charge for\n"
71 "this service if you wish), that you receive source code or can get it\n"
72 "if you want it, that you can change the software or use pieces of it\n"
73 "in new free programs; and that you know you can do these things.\n"
74 "\n"
75 "  To protect your rights, we need to make restrictions that forbid\n"
76 "anyone to deny you these rights or to ask you to surrender the rights.\n"
77 "These restrictions translate to certain responsibilities for you if you\n"
78 "distribute copies of the software, or if you modify it.\n"
79 "\n"
80 "  For example, if you distribute copies of such a program, whether\n"
81 "gratis or for a fee, you must give the recipients all the rights that\n"
82 "you have.  You must make sure that they, too, receive or can get the\n"
83 "source code.  And you must show them these terms so they know their\n"
84 "rights.\n"
85 "\n"
86 "  We protect your rights with two steps: (1) copyright the software, and\n"
87 "(2) offer you this license which gives you legal permission to copy,\n"
88 "distribute and/or modify the software.\n"
89 "\n"
90 "  Also, for each author's protection and ours, we want to make certain\n"
91 "that everyone understands that there is no warranty for this free\n"
92 "software.  If the software is modified by someone else and passed on, we\n"
93 "want its recipients to know that what they have is not the original, so\n"
94 "that any problems introduced by others will not reflect on the original\n"
95 "authors' reputations.\n"
96 "\n"
97 "  Finally, any free program is threatened constantly by software\n"
98 "patents.  We wish to avoid the danger that redistributors of a free\n"
99 "program will individually obtain patent licenses, in effect making the\n"
100 "program proprietary.  To prevent this, we have made it clear that any\n"
101 "patent must be licensed for everyone's free use or not licensed at all.\n"
102 "\n"
103 "  The precise terms and conditions for copying, distribution and\n"
104 "modification follow.\n"
105 "^L\n"
106 "                    GNU GENERAL PUBLIC LICENSE\n"
107 "   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n"
108 "\n"
109 "  0. This License applies to any program or other work which contains\n"
110 "a notice placed by the copyright holder saying it may be distributed\n"
111 "under the terms of this General Public License.  The \"Program\", below,\n"
112 "refers to any such program or work, and a \"work based on the Program\"\n"
113 "means either the Program or any derivative work under copyright law:\n"
114 "that is to say, a work containing the Program or a portion of it,\n"
115 "either verbatim or with modifications and/or translated into another\n"
116 "language.  (Hereinafter, translation is included without limitation in\n"
117 "the term \"modification\".)  Each licensee is addressed as \"you\".\n"
118 "\n"
119 "Activities other than copying, distribution and modification are not\n"
120 "covered by this License; they are outside its scope.  The act of\n"
121 "running the Program is not restricted, and the output from the Program\n"
122 "is covered only if its contents constitute a work based on the\n"
123 "Program (independent of having been made by running the Program).\n"
124 "Whether that is true depends on what the Program does.\n"
125 "\n"
126 "  1. You may copy and distribute verbatim copies of the Program's\n"
127 "source code as you receive it, in any medium, provided that you\n"
128 "conspicuously and appropriately publish on each copy an appropriate\n"
129 "copyright notice and disclaimer of warranty; keep intact all the\n"
130 "notices that refer to this License and to the absence of any warranty;\n"
131 "and give any other recipients of the Program a copy of this License\n"
132 "along with the Program.\n"
133 "\n"
134 "You may charge a fee for the physical act of transferring a copy, and\n"
135 "you may at your option offer warranty protection in exchange for a fee.\n"
136 "\n"
137 "  2. You may modify your copy or copies of the Program or any portion\n"
138 "of it, thus forming a work based on the Program, and copy and\n"
139 "distribute such modifications or work under the terms of Section 1\n"
140 "above, provided that you also meet all of these conditions:\n"
141 "\n"
142 "    a) You must cause the modified files to carry prominent notices\n"
143 "    stating that you changed the files and the date of any change.\n"
144 "\n"
145 "    b) You must cause any work that you distribute or publish, that in\n"
146 "    whole or in part contains or is derived from the Program or any\n"
147 "    part thereof, to be licensed as a whole at no charge to all third\n"
148 "    parties under the terms of this License.\n"
149 "\n"
150 "    c) If the modified program normally reads commands interactively\n"
151 "    when run, you must cause it, when started running for such\n"
152 "    interactive use in the most ordinary way, to print or display an\n"
153 "    announcement including an appropriate copyright notice and a\n"
154 "    notice that there is no warranty (or else, saying that you provide\n"
155 "    a warranty) and that users may redistribute the program under\n"
156 "    these conditions, and telling the user how to view a copy of this\n"
157 "    License.  (Exception: if the Program itself is interactive but\n"
158 "    does not normally print such an announcement, your work based on\n"
159 "    the Program is not required to print an announcement.)\n"
160 "\n"
161 "These requirements apply to the modified work as a whole.  If\n"
162 "identifiable sections of that work are not derived from the Program,\n"
163 "and can be reasonably considered independent and separate works in\n"
164 "themselves, then this License, and its terms, do not apply to those\n"
165 "sections when you distribute them as separate works.  But when you\n"
166 "distribute the same sections as part of a whole which is a work based\n"
167 "on the Program, the distribution of the whole must be on the terms of\n"
168 "this License, whose permissions for other licensees extend to the\n"
169 "entire whole, and thus to each and every part regardless of who wrote it.\n"
170 "\n"
171 "Thus, it is not the intent of this section to claim rights or contest\n"
172 "your rights to work written entirely by you; rather, the intent is to\n"
173 "exercise the right to control the distribution of derivative or\n"
174 "collective works based on the Program.\n"
175 "\n"
176 "In addition, mere aggregation of another work not based on the Program\n"
177 "with the Program (or with a work based on the Program) on a volume of\n"
178 "a storage or distribution medium does not bring the other work under\n"
179 "the scope of this License.\n"
180 "\n"
181 "  3. You may copy and distribute the Program (or a work based on it,\n"
182 "under Section 2) in object code or executable form under the terms of\n"
183 "Sections 1 and 2 above provided that you also do one of the following:\n"
184 "\n"
185 "    a) Accompany it with the complete corresponding machine-readable\n"
186 "    source code, which must be distributed under the terms of Sections\n"
187 "    1 and 2 above on a medium customarily used for software interchange; or,\n"
188 "\n"
189 "    b) Accompany it with a written offer, valid for at least three\n"
190 "    years, to give any third party, for a charge no more than your\n"
191 "    cost of physically performing source distribution, a complete\n"
192 "    machine-readable copy of the corresponding source code, to be\n"
193 "    distributed under the terms of Sections 1 and 2 above on a medium\n"
194 "    customarily used for software interchange; or,\n"
195 "\n"
196 "    c) Accompany it with the information you received as to the offer\n"
197 "    to distribute corresponding source code.  (This alternative is\n"
198 "    allowed only for noncommercial distribution and only if you\n"
199 "    received the program in object code or executable form with such\n"
200 "    an offer, in accord with Subsection b above.)\n"
201 "\n"
202 "The source code for a work means the preferred form of the work for\n"
203 "making modifications to it.  For an executable work, complete source\n"
204 "code means all the source code for all modules it contains, plus any\n"
205 "associated interface definition files, plus the scripts used to\n"
206 "control compilation and installation of the executable.  However, as a\n"
207 "special exception, the source code distributed need not include\n"
208 "anything that is normally distributed (in either source or binary\n"
209 "form) with the major components (compiler, kernel, and so on) of the\n"
210 "operating system on which the executable runs, unless that component\n"
211 "itself accompanies the executable.\n"
212 "\n"
213 "If distribution of executable or object code is made by offering\n"
214 "access to copy from a designated place, then offering equivalent\n"
215 "access to copy the source code from the same place counts as\n"
216 "distribution of the source code, even though third parties are not\n"
217 "compelled to copy the source along with the object code.\n"
218 "^L\n"
219 "  4. You may not copy, modify, sublicense, or distribute the Program\n"
220 "except as expressly provided under this License.  Any attempt\n"
221 "otherwise to copy, modify, sublicense or distribute the Program is\n"
222 "void, and will automatically terminate your rights under this License.\n"
223 "However, parties who have received copies, or rights, from you under\n"
224 "this License will not have their licenses terminated so long as such\n"
225 "parties remain in full compliance.\n"
226 "\n"
227 "  5. You are not required to accept this License, since you have not\n"
228 "signed it.  However, nothing else grants you permission to modify or\n"
229 "distribute the Program or its derivative works.  These actions are\n"
230 "prohibited by law if you do not accept this License.  Therefore, by\n"
231 "modifying or distributing the Program (or any work based on the\n"
232 "Program), you indicate your acceptance of this License to do so, and\n"
233 "all its terms and conditions for copying, distributing or modifying\n"
234 "the Program or works based on it.\n"
235 "\n"
236 "  6. Each time you redistribute the Program (or any work based on the\n"
237 "Program), the recipient automatically receives a license from the\n"
238 "original licensor to copy, distribute or modify the Program subject to\n"
239 "these terms and conditions.  You may not impose any further\n"
240 "restrictions on the recipients' exercise of the rights granted herein.\n"
241 "You are not responsible for enforcing compliance by third parties to\n"
242 "this License.\n"
243 "\n"
244 "  7. If, as a consequence of a court judgment or allegation of patent\n"
245 "infringement or for any other reason (not limited to patent issues),\n"
246 "conditions are imposed on you (whether by court order, agreement or\n"
247 "otherwise) that contradict the conditions of this License, they do not\n"
248 "excuse you from the conditions of this License.  If you cannot\n"
249 "distribute so as to satisfy simultaneously your obligations under this\n"
250 "License and any other pertinent obligations, then as a consequence you\n"
251 "may not distribute the Program at all.  For example, if a patent\n"
252 "license would not permit royalty-free redistribution of the Program by\n"
253 "all those who receive copies directly or indirectly through you, then\n"
254 "the only way you could satisfy both it and this License would be to\n"
255 "refrain entirely from distribution of the Program.\n"
256 "\n"
257 "If any portion of this section is held invalid or unenforceable under\n"
258 "any particular circumstance, the balance of the section is intended to\n"
259 "apply and the section as a whole is intended to apply in other\n"
260 "circumstances.\n"
261 "\n"
262 "It is not the purpose of this section to induce you to infringe any\n"
263 "patents or other property right claims or to contest validity of any\n"
264 "such claims; this section has the sole purpose of protecting the\n"
265 "integrity of the free software distribution system, which is\n"
266 "implemented by public license practices.  Many people have made\n"
267 "generous contributions to the wide range of software distributed\n"
268 "through that system in reliance on consistent application of that\n"
269 "system; it is up to the author/donor to decide if he or she is willing\n"
270 "to distribute software through any other system and a licensee cannot\n"
271 "impose that choice.\n"
272 "\n"
273 "This section is intended to make thoroughly clear what is believed to\n"
274 "be a consequence of the rest of this License.\n"
275 "\n"
276 "  8. If the distribution and/or use of the Program is restricted in\n"
277 "certain countries either by patents or by copyrighted interfaces, the\n"
278 "original copyright holder who places the Program under this License\n"
279 "may add an explicit geographical distribution limitation excluding\n"
280 "those countries, so that distribution is permitted only in or among\n"
281 "countries not thus excluded.  In such case, this License incorporates\n"
282 "the limitation as if written in the body of this License.\n"
283 "\n"
284 "  9. The Free Software Foundation may publish revised and/or new versions\n"
285 "of the General Public License from time to time.  Such new versions will\n"
286 "be similar in spirit to the present version, but may differ in detail to\n"
287 "address new problems or concerns.\n"
288 "\n"
289 "Each version is given a distinguishing version number.  If the Program\n"
290 "specifies a version number of this License which applies to it and \"any\n"
291 "later version\", you have the option of following the terms and conditions\n"
292 "either of that version or of any later version published by the Free\n"
293 "Software Foundation.  If the Program does not specify a version number of\n"
294 "this License, you may choose any version ever published by the Free Software\n"
295 "Foundation.\n"
296 "\n"
297 "  10. If you wish to incorporate parts of the Program into other free\n"
298 "programs whose distribution conditions are different, write to the author\n"
299 "to ask for permission.  For software which is copyrighted by the Free\n"
300 "Software Foundation, write to the Free Software Foundation; we sometimes\n"
301 "make exceptions for this.  Our decision will be guided by the two goals\n"
302 "of preserving the free status of all derivatives of our free software and\n"
303 "of promoting the sharing and reuse of software generally.\n";
304
305 static char *warranty=
306 "                            NO WARRANTY\n"
307 "\n"
308 "  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"
309 "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n"
310 "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"
311 "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"
312 "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
313 "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n"
314 "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n"
315 "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"
316 "REPAIR OR CORRECTION.\n"
317 "\n"
318 "  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"
319 "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"
320 "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"
321 "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"
322 "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"
323 "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"
324 "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"
325 "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"
326 "POSSIBILITY OF SUCH DAMAGES.\n";
327 #endif
328
329 static void printTypeInfo(link *);
330 static void printValAggregates (symbol *,link *,char,unsigned int);
331
332 int srcMode = SRC_CMODE ;
333
334 /*-----------------------------------------------------------------*/
335 /* funcWithName - returns function with name                       */
336 /*-----------------------------------------------------------------*/
337 DEFSETFUNC(funcWithName)
338 {
339     function *func = item;
340     V_ARG(char *,name);
341     V_ARG(function **,funcp);
342
343     if (*funcp)
344         return 0;
345
346     if (strcmp(func->sym->name,name) == 0) {
347         *funcp = func;
348         return 1;
349     }
350     
351     return 0;
352 }
353
354 /*-----------------------------------------------------------------*/
355 /* setBPatModLine - set break point at the line specified for the  */
356 /*-----------------------------------------------------------------*/
357 static void setBPatModLine (module *mod, int line)
358 {
359   int next_line;
360
361     /* look for the first executable line after the line
362        specified & get the break point there */    
363     if (srcMode == SRC_CMODE && line > mod->ncLines) {
364         fprintf(stderr,"No line %d in file \"%s\".\n",
365                 line,mod->c_name);
366         return ;
367     }
368     
369     if (srcMode == SRC_AMODE && line > mod->nasmLines) {
370         fprintf(stderr,"No line %d in file \"%s\".\n",
371                 line,mod->asm_name);
372         return ;
373     }
374
375     next_line = line;
376     for ( ; next_line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; 
377           next_line++ ) {
378         if (srcMode == SRC_CMODE) {
379             if (mod->cLines[next_line]->addr) {
380                 setBreakPoint (mod->cLines[next_line]->addr, CODE, USER, 
381                                userBpCB, mod->c_name, next_line);
382                 return;
383 //              break;
384             }
385         }
386         else {
387            if (mod->asmLines[next_line]->addr) {
388                setBreakPoint (mod->asmLines[next_line]->addr, CODE, USER, 
389                               userBpCB, mod->asm_name, next_line);
390                 return;
391 //             break;
392            } 
393         }
394     }
395
396         fprintf(stderr,"No line %d or after in file \"%s\"..\n",
397                         line,mod->c_name);
398
399     return;
400 }
401
402 /*-----------------------------------------------------------------*/
403 /* clearBPatModLine - clr break point at the line specified        */
404 /*-----------------------------------------------------------------*/
405 static void clearBPatModLine (module *mod, int line)
406 {
407     /* look for the first executable line after the line
408        specified & get the break point there */
409     if (srcMode == SRC_CMODE && line > mod->ncLines) {
410         fprintf(stderr,"No line %d in file \"%s\".\n",
411                 line,mod->c_name);
412         return ;
413     }
414     
415     if (srcMode == SRC_AMODE && line > mod->ncLines) {
416         fprintf(stderr,"No line %d in file \"%s\".\n",
417                 line,mod->c_name);
418         return ;
419     }    
420     
421     for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; 
422           line++ ) {
423         if (srcMode == SRC_CMODE) 
424             if (mod->cLines[line]->addr) {
425                 clearUSERbp (mod->cLines[line]->addr);                    
426                 break;
427             }
428         else
429             if (mod->asmLines[line]->addr) {
430                 clearUSERbp (mod->asmLines[line]->addr);                          
431                 break;
432             }
433     }
434
435     return;
436 }
437
438 /*-----------------------------------------------------------------*/
439 /* funcWithNameModule - returns functions with a name module combo */
440 /*-----------------------------------------------------------------*/
441 DEFSETFUNC(funcWithNameModule) 
442 {
443     function *func = item;
444     V_ARG(char *,fname);
445     V_ARG(char *,mname);
446     V_ARG(function **,funcp);
447
448     if (*funcp)
449         return 0;
450
451     if (strcmp(func->sym->name,fname) == 0 &&
452         strcmp(func->mod->c_name,mname) == 0) {
453         *funcp = func;
454         return 1;
455     }
456
457     return 0;
458 }
459
460 /*-----------------------------------------------------------------*/
461 /* funcInAddr - given an address returns the function              */
462 /*-----------------------------------------------------------------*/
463 DEFSETFUNC(funcInAddr)
464 {
465     function *func = item;
466     V_ARG(unsigned int,addr);
467     V_ARG(function **,funcp);
468
469     if (*funcp)
470         return 0;
471
472     /* in the address range */
473     if (func->sym->addr <= addr &&
474         func->sym->eaddr >= addr) {
475         
476         *funcp = func;
477         return 1;
478     }
479
480     return 0;       
481 }
482
483 /*-----------------------------------------------------------------*/
484 /* setStepBp - will set STEP Bp @ function entry points            */
485 /*-----------------------------------------------------------------*/
486 DEFSETFUNC(setStepBp)
487 {
488     function *func = item;
489     
490     if (func->sym && func->sym->addr ) {
491         
492         /* set the entry break point */
493         setBreakPoint (func->sym->addr , CODE , STEP , 
494                        stepBpCB ,func->mod->c_name , func->entryline);
495
496         return 1;
497     }
498
499     return 0;
500 }
501
502 /*-----------------------------------------------------------------*/
503 /* setStepEPBp - sets a given type of bp @ the execution point     */
504 /*-----------------------------------------------------------------*/
505 DEFSETFUNC(setStepEPBp)
506 {
507     exePoint *ep = item;
508     V_ARG(int,bptype);
509     V_ARG(char *,mname);
510    
511     setBreakPoint (ep->addr, CODE, bptype, 
512                    stepBpCB, mname, ep->line);
513     return 1;
514 }
515
516 /*-----------------------------------------------------------------*/
517 /* setNextEPBp - sets a given type of bp @ the execution point     */
518 /*-----------------------------------------------------------------*/
519 DEFSETFUNC(setNextEPBp)
520 {
521     exePoint *ep = item;
522     V_ARG(int,bptype);
523     V_ARG(char *,mname);
524    
525     setBreakPoint (ep->addr, CODE, bptype, 
526                    nextBpCB, mname, ep->line);
527     return 1;
528 }
529
530 /*-----------------------------------------------------------------*/
531 /* lineAtAddr - for execution points returns the one with addr     */
532 /*-----------------------------------------------------------------*/
533 DEFSETFUNC(lineAtAddr)
534 {
535     exePoint *ep = item;
536     V_ARG(unsigned int,addr);
537     V_ARG(int *,line);
538     V_ARG(int *,block);
539     V_ARG(int *,level);
540
541     /* address must be an exact match */
542     if (ep->addr == addr) {
543         *line = ep->line;
544         if (block)
545             *block = ep->block ;
546         if (level)
547             *level = ep->level ;
548         return 1;
549     }
550
551     return 0;
552     
553 }
554
555 /*-----------------------------------------------------------------*/
556 /* discoverContext - find out the current context of the bp        */
557 /*-----------------------------------------------------------------*/
558 context *discoverContext (unsigned addr)
559 {
560     function *func = NULL;
561     int line = 0;
562
563     /* find the function we are in */
564     if (!applyToSet(functions,funcInAddr,addr,&func)) {
565       fprintf(stderr, "Error?:discoverContext: cannot apply to set!\n");
566         return NULL;
567     }
568
569     currCtxt->func = func;
570     currCtxt->addr = func->laddr = addr;
571     currCtxt->modName = func->modName;
572     
573     /* find the c line number */
574     if(applyToSet(func->cfpoints,lineAtAddr,addr,
575                   &line,&currCtxt->block,&currCtxt->level)) 
576         currCtxt->cline = func->lline = line;
577     else
578         currCtxt->cline = func->exitline;
579     
580     /* find the asm line number */
581     line = 0;
582     if (applyToSet(func->afpoints,lineAtAddr,addr,
583                    &line,NULL,NULL))
584         currCtxt->asmline = line;       
585     else
586         currCtxt->asmline = -1;
587         
588     return currCtxt ;
589 }
590
591
592 /*-----------------------------------------------------------------*/
593 /* simGo - send 'go' cmd to simulator and wait till a break occurs */
594 /*-----------------------------------------------------------------*/
595 void simGo (unsigned int gaddr)
596 {   
597     unsigned int addr ;
598     context *ctxt;
599     int rv;
600     static int initial_break_flag = 0;
601
602  top:    
603     addr = simGoTillBp (gaddr);
604
605     /* got the pc for the break point now first
606        discover the program context i.e. module, function 
607        linenumber of the source etc, etc etc */
608     ctxt = discoverContext (addr);
609     
610     /* dispatch all the break point call back functions */
611     rv = dispatchCB (addr,ctxt);    
612
613  ret:    
614
615     /* the dispatch call back function will return
616        non-zero if an user break point has been hit
617        if not then we continue with the execution 
618        of the program */
619     if (!rv) {
620       if (!initial_break_flag) {
621         initial_break_flag = 1;  // kludge to stop only at first run
622         fprintf(stdout, "Stopping at entry.  You can now list and set breakpoints\n");
623       }
624       else {
625         gaddr = -1;
626         goto top ;
627       }
628
629 // notes: kpb
630 // I took this out, after running "run" it would just keep re-running
631 // even after a lot of break points hit.  For some reason above code
632 // not triggering(dispatchCB).  This seems to be by design, startup adds
633 // a bunch of breakpoints-but they are not USER breakpoints.  Perhaps the
634 // debugger changed with its implementation of "go"("run").  It seems we
635 // need to add a "next" or "step" followed by a "run"...
636 // I added a "step" in simi.c when we want a resume function, this seems
637 // to work.
638
639 // still there is question of how do we stop it initially, since
640 // it must be started before it can get a context.  If so, we would
641 // want it to just run up to an initial entry point you'd think...
642 // I don't see why we can't set breakpoints before an initial run,
643 // this does not seem right to me.
644
645 // line #'s are a bit off too.
646
647 #if 0
648         gaddr = -1;
649         goto top ;
650 #endif
651     }
652     
653 }
654
655 /*-----------------------------------------------------------------*/
656 /* cmdSetUserBp - set break point at the user specified location   */
657 /*-----------------------------------------------------------------*/
658 int cmdSetUserBp (char *s, context *cctxt)
659 {
660     char *bp ;
661     function *func = NULL;
662         
663     /* user break point location specification can be of the following
664        forms
665        a) <nothing>        - break point at current location
666        b) lineno           - number of the current module
667        c) filename:lineno  - line number of the given file
668        e) filename:function- function X in file Y (useful for static functions)
669        f) function         - function entry point
670     */
671
672     if (!cctxt) {
673         fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
674         return 0;
675     }
676     /* white space skip */
677     while (*s && isspace(*s)) s++;
678     
679     /* null terminate it after stripping trailing blanks*/
680     bp = s + strlen(s);
681     while (bp != s && isspace(*bp)) bp--;
682     *bp = '\0';
683
684     /* case a) nothing */
685     /* if nothing given then current location : we know
686        the current execution location from the currentContext */
687     if (! *s ) {
688
689         /* if current context is known */
690         if (cctxt->func) {
691             if (srcMode == SRC_CMODE)
692                 /* set the break point */
693                 setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
694                                 cctxt->func->mod->c_name, cctxt->cline);
695             else
696                 setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
697                                 cctxt->func->mod->asm_name, cctxt->asmline);
698                 
699         }
700         else
701             fprintf(stderr,"No default breakpoint address now.\n");
702                         
703         goto ret ;
704     }
705
706     /* case b) lineno */
707     /* check if line number */
708     if (isdigit(*s)) {
709         /* get the lineno */
710         int line = atoi(s);
711
712         /* if current context not present then we must get the module
713            which has main & set the break point @ line number provided
714            of that module : if current context known then set the bp 
715            at the line number given for the current module 
716         */
717         if (cctxt->func) {
718             if (!cctxt->func->mod) {
719                 if (!applyToSet(functions,funcWithName,"main"))
720                     fprintf(stderr,"Function \"main\" not defined.\n");
721                 else 
722                     setBPatModLine(func->mod,line);
723             } else 
724                 setBPatModLine(cctxt->func->mod,line);
725         } else {
726                 if (list_mod) {
727                         setBPatModLine(list_mod,line);
728                 } else {
729                   fprintf(stdout,"Sdcdb fails to have module symbol context at %d\n", __LINE__);
730                 }
731         }
732         
733         goto ret;
734     }
735
736     if ((bp = strchr(s,':'))) {
737         
738         module *mod = NULL;
739         *bp = '\0';
740         
741         if (srcMode == SRC_CMODE) {
742             if (!applyToSet(modules,moduleWithCName,s,&mod)) {
743                 fprintf (stderr,"No source file named %s.\n",s);
744                 goto ret;
745             }
746         } else {
747             if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
748                 fprintf (stderr,"No source file named %s.\n",s);
749                 goto ret;
750             }
751         }
752                 
753         /* case c) filename:lineno */
754         if (isdigit(*(bp +1))) {                    
755          
756             setBPatModLine (mod,atoi(bp+1));        
757             goto ret;
758             
759         }
760         /* case d) filename:function */
761         if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
762             fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
763         else        
764             setBPatModLine (mod,
765                             (srcMode == SRC_CMODE ? 
766                              func->entryline :
767                              func->aentryline));
768         
769         goto ret;
770     }
771             
772     /* case e) function */
773     if (!applyToSet(functions,funcWithName,s,&func))
774         fprintf(stderr,"Function \"%s\" not defined.\n",s); 
775     else
776         setBPatModLine(func->mod,
777                        (srcMode == SRC_CMODE ?
778                         func->entryline :
779                         func->aentryline));
780
781  ret:    
782     return 0;
783 }
784
785 /*-----------------------------------------------------------------*/
786 /* cmdListAsm - list assembler source code                         */
787 /*-----------------------------------------------------------------*/
788 int cmdListAsm (char *s, context *cctxt)
789 {
790     fprintf(stderr,"'listasm' command not yet implemented\n");
791     return 0;
792 }
793
794 /*-----------------------------------------------------------------*/
795 /* cmdSetOption - set debugger options                             */
796 /*-----------------------------------------------------------------*/
797 int cmdSetOption (char *s, context *cctxt)
798 {
799     while (*s && isspace(*s)) s++;
800     if (strncmp(s,"srcmode",7) == 0 ) {
801         if (srcMode == SRC_CMODE)
802             srcMode = SRC_AMODE;
803         else
804             srcMode = SRC_CMODE;
805         fprintf(stderr,"source mode set to '%s'\n", 
806                 (srcMode == SRC_CMODE ? "C" : "asm"));
807         return 0;
808     }
809     
810     fprintf(stderr,"'set %s' command not yet implemented\n",s);
811     return 0;
812 }
813
814 /*-----------------------------------------------------------------*/
815 /* cmdContinue - continue till next break point                    */
816 /*-----------------------------------------------------------------*/
817 int cmdContinue (char *s, context *cctxt)
818 {
819     if (!cctxt || !cctxt->func) {
820         fprintf(stdout,"The program is not being run.\n");
821         return 0;
822     }
823
824     fprintf(stdout,"Continuing.\n");
825     simGo(-1);
826     return 0;
827 }
828
829 /*-----------------------------------------------------------------*/
830 /* cmdDelUserBp - delete user break point                          */
831 /*-----------------------------------------------------------------*/
832 int cmdDelUserBp (char *s, context *cctxt)
833 {
834     int bpnum ;
835     while (isspace(*s)) s++;
836     
837     if (!*s ) {
838         if (userBpPresent) {
839             char buffer[10];
840             fprintf (stdout,"Delete all breakpoints? (y or n) ");
841             fflush(stdout);
842             fgets(buffer,sizeof(buffer),stdin);
843             if (toupper(buffer[0]) == 'Y')
844                 deleteUSERbp(-1);          
845         }
846         return 0;
847     }
848     
849     /* determine the break point number */
850     if (sscanf(s,"%d",&bpnum) == 1)
851         deleteUSERbp(bpnum);
852
853     return 0;
854 }
855
856 /*-----------------------------------------------------------------*/
857 /* cmdStep - single step thru C source file                        */
858 /*-----------------------------------------------------------------*/
859 int cmdStep (char *s, context *cctxt)
860 {
861     function *func = NULL;
862
863     if (!cctxt || !cctxt->func || !cctxt->func->mod) 
864         fprintf(stdout,"The program is not being run.\n");
865     else {
866         /* if we are @ the end of a function then set
867            break points at execution points of the
868            function in the call stack... */
869         if (cctxt->addr == cctxt->func->sym->eaddr) {
870             if ((func = STACK_PEEK(callStack))) {
871                 if (srcMode == SRC_CMODE)
872                     applyToSet (func->cfpoints,setStepEPBp,STEP,
873                                 func->mod->c_name);     
874                 else
875                     applyToSet (func->afpoints,setStepEPBp,STEP,
876                                 func->mod->asm_name);
877             }
878         } else {
879             /* set breakpoints at all function entry points
880                and all exepoints of this functions & for
881                all functions one up in the call stack */
882             
883             /* all function entry points */
884             applyToSet(functions,setStepBp); 
885             
886             if (srcMode == SRC_CMODE) {
887                 /* for all execution points in this function */
888                 applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP,
889                            cctxt->func->mod->c_name);
890                 
891                 /* set a break point @ the current function's
892                    exit */
893                 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
894                                stepBpCB, cctxt->func->mod->c_name, 
895                                cctxt->func->exitline);
896                 
897                 /* now break point @ callers execution points */
898                 if ((func = STACK_PPEEK(callStack))) {
899                     applyToSet (func->cfpoints,setStepEPBp,STEP,
900                                 func->mod->c_name);     
901                     /* set bp @ callers exit point */
902                     setBreakPoint (func->sym->eaddr, CODE, STEP , 
903                                    stepBpCB, func->mod->c_name, 
904                                    func->exitline);
905                 }
906             } else {
907                 /* for all execution points in this function */
908                 applyToSet(cctxt->func->afpoints,setStepEPBp,STEP,
909                            cctxt->func->mod->asm_name);
910                 
911                 /* set a break point @ the current function's
912                    exit */
913                 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
914                                stepBpCB, cctxt->func->mod->asm_name, 
915                                cctxt->func->aexitline);
916                 
917                 /* now break point @ callers execution points */
918                 if ((func = STACK_PPEEK(callStack))) {
919                     
920                     applyToSet (func->afpoints,setStepEPBp,STEP,
921                                 func->mod->asm_name);   
922                     
923                     /* set bp @ callers exit point */
924                     setBreakPoint (func->sym->eaddr, CODE, STEP , 
925                                    stepBpCB, func->mod->asm_name, 
926                                    func->aexitline);
927                 }
928             }
929         }
930
931         simGo(-1);
932     }
933     return 0;
934 }
935
936 /*-----------------------------------------------------------------*/
937 /* cmdNext - next executable C statement file                      */
938 /*-----------------------------------------------------------------*/
939 int cmdNext (char *s, context *cctxt)
940 {
941     function *func = NULL;
942     /* next is almost the same as step except we don't
943        we don't set break point for all function entry
944        points */
945     if (!cctxt || !cctxt->func || !cctxt->func->mod) 
946         fprintf(stdout,"The program is not being run.\n");
947     else {
948         
949         /* if we are @ the end of a function then set
950            break points at execution points of the
951            function in the call stack... */
952         if (cctxt->addr == cctxt->func->sym->eaddr) {
953             if ((func = STACK_PEEK(callStack))) {
954                 if (srcMode == SRC_CMODE)
955                     applyToSet (func->cfpoints,setStepEPBp,STEP,
956                                 func->mod->c_name);     
957                 else
958                     applyToSet (func->afpoints,setStepEPBp,STEP,
959                                func->mod->asm_name);
960             }
961         } else {
962             if (srcMode == SRC_CMODE) {
963                 /* for all execution points in this function */
964                 applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT,
965                            cctxt->func->mod->c_name);
966                 /* set a break point @ the current function's
967                    exit */
968                 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
969                                nextBpCB, cctxt->func->mod->c_name, 
970                                cctxt->func->exitline);
971                 
972                 /* now break point @ callers execution points */        
973                 if ((func = STACK_PPEEK(callStack))) {
974                     applyToSet (func->cfpoints,setNextEPBp,NEXT ,
975                                 func->mod->c_name);     
976                     /* set bp @ callers exit point */
977                     setBreakPoint (func->sym->eaddr, CODE, NEXT , 
978                                    stepBpCB, func->mod->c_name, 
979                                    func->exitline);
980                 }
981             } else {
982                 /* for all execution points in this function */
983                 applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT,
984                            cctxt->func->mod->asm_name);
985                 /* set a break point @ the current function's
986                    exit */
987                 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
988                                nextBpCB, cctxt->func->mod->asm_name, 
989                                cctxt->func->aexitline);
990                 
991                 /* now break point @ callers execution points */        
992                 if ((func = STACK_PPEEK(callStack))) {
993                     applyToSet (func->cfpoints,setNextEPBp,NEXT ,
994                                 func->mod->asm_name);   
995                     /* set bp @ callers exit point */
996                     setBreakPoint (func->sym->eaddr, CODE, NEXT , 
997                                    stepBpCB, func->mod->asm_name, 
998                                    func->aexitline);
999                 }
1000             }
1001             simGo(-1);  
1002         }
1003     }    
1004     return 0;
1005 }
1006
1007 /*-----------------------------------------------------------------*/
1008 /* cmdRun  - run till next break point                             */
1009 /*-----------------------------------------------------------------*/
1010 int cmdRun (char *s, context *cctxt)
1011 {
1012     char buff[10];
1013     if (!cctxt || !cctxt->func || !cctxt->func->mod) {
1014         fprintf(stdout,"Starting program\n");
1015         simGo(0);
1016     } else {
1017         
1018         fprintf(stdout,
1019                 "The program being debugged has been started already.\n");
1020         fprintf(stdout,"Start it from the beginning? (y or n) ");
1021         fflush(stdout);
1022
1023         fgets(buff,sizeof(buff),stdin);
1024         if (toupper(buff[0]) == 'Y') {
1025             simReset();
1026             simGo(0);
1027         }
1028     }
1029
1030     return 0;
1031 }
1032
1033 /*-----------------------------------------------------------------
1034  cmdListSymbols - list symbols
1035 |-----------------------------------------------------------------*/
1036 int cmdListSymbols (char *s, context *cctxt)
1037 {
1038     int our_verbose = 0;
1039     symbol *sy;
1040     int i;
1041
1042     if (strstr(s, "v1")) {
1043       our_verbose = 1;
1044     } else if (strstr(s, "v2")) {
1045       our_verbose = 2;
1046     }
1047
1048     printf("[symbols]\n");
1049     sy = setFirstItem(symbols);
1050     i = 0;
1051     for (;;) {
1052       if (sy == NULL)
1053         break;
1054       if (our_verbose <= 1)
1055         printf("<%s>", sy->name);
1056
1057       if (our_verbose > 1) {
1058         printf("  %d) name:%s, size:%d, level:%d block:%d\n", i,
1059           sy->name, sy->size, sy->level, sy->block);
1060         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
1061           sy->isonstack, sy->isfunc, sy->offset, sy->addr);
1062         printf("    eaddr:%d, addr_type:%c, type:%x etype:%x\n",
1063           sy->eaddr, sy->addr_type, sy->type, sy->etype);
1064         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
1065           sy->scopetype, sy->sname, sy->rname, sy->addrspace);
1066         printf("    next:%x\n", sy->next);
1067       }
1068       ++i;
1069       sy = setNextItem(symbols);
1070     }
1071     printf("   %d symbols\n", i);
1072     return 0;
1073 }
1074
1075 /*-----------------------------------------------------------------
1076  cmdListFunctions - list functions.
1077 |-----------------------------------------------------------------*/
1078 int cmdListFunctions (char *s, context *cctxt)
1079 {
1080     function *f;
1081     int i;
1082     int our_verbose = 0;
1083
1084     if (strstr(s, "v1")) {
1085       our_verbose = 1;
1086     } else if (strstr(s, "v2")) {
1087       our_verbose = 2;
1088     }
1089
1090     printf("[functions]\n");
1091     f = setFirstItem(functions);
1092     i = 0;
1093     for (;;) {
1094       if (f == NULL)
1095         break;
1096       if (our_verbose) {
1097         printf("  %d) sym:%x, modName:%s, mod:%x\n", i,
1098           f->sym, f->modName, f->mod);
1099         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
1100                 f->entryline, f->aentryline, f->exitline, f->aexitline);
1101         printf("    cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n",
1102                 f->cfpoints, f->afpoints, f->laddr, f->lline);
1103       }
1104       else {
1105         printf("<%s>", f->modName);
1106       }
1107       ++i;
1108       f = setNextItem(functions);
1109     }
1110     printf("   %d functions\n", i);
1111     return 0;
1112 }
1113
1114 /*-----------------------------------------------------------------
1115  cmdListModules - list functions.
1116 |-----------------------------------------------------------------*/
1117 int cmdListModules (char *s, context *cctxt)
1118 {
1119     module *m;
1120     srcLine *cs, *as;
1121     int i, mi;
1122     int our_verbose = 0;
1123
1124     if (strstr(s, "v1")) {
1125       our_verbose = 1;
1126     } else if (strstr(s, "v2")) {
1127       our_verbose = 2;
1128     }
1129
1130     printf("[modules]\n");
1131     m = setFirstItem(modules);
1132     mi = 0;
1133     for (;;) {
1134       if (m == NULL)
1135         break;
1136
1137       if (our_verbose >= 0) {
1138       printf("  %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
1139         m->cfullname, m->afullname, m->name);
1140       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
1141               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
1142       printf("    cLines:%x, asmLines:%x\n",
1143               m->cLines, m->asmLines);
1144       }
1145       if (our_verbose > 2) {
1146         i = 0;
1147         if (m->cLines) {
1148           cs = m->cLines[i++];
1149           printf("    [cLines] ");
1150           while (cs) {
1151             if (our_verbose)
1152               printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1153                  i, cs->addr, cs->block, cs->level, cs->src);
1154             cs = m->cLines[i++];
1155           }
1156           if (!our_verbose)
1157               printf("%d records", i);
1158         }
1159         i = 0;
1160         if (m->asmLines) {
1161           as = m->asmLines[i++];
1162           printf("    [asmLines] ");
1163           while (as) {
1164             if (our_verbose)
1165               printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1166                  i, as->addr, as->block, as->level, as->src);
1167             as = m->asmLines[i++];
1168           }
1169           if (!our_verbose)
1170               printf("%d records", i);
1171         }
1172         printf("\n");
1173       }
1174
1175       m = setNextItem(modules);
1176     }
1177     return 0;
1178 }
1179
1180 /*-----------------------------------------------------------------
1181  infoSymbols - This is really just a tool to dump all these
1182    huge program structures out into human readable form.
1183 |-----------------------------------------------------------------*/
1184 static void infoSymbols(context *ctxt)
1185 {
1186   int our_verbose = 0;
1187
1188   printf("[context:%x] func:%x modName:%s addr:%x\n",
1189     ctxt, ctxt->func, ctxt->modName, ctxt->addr);
1190
1191   printf("  cline:%d asmline:%d block:%d level:%d\n",
1192     ctxt->cline, ctxt->asmline, ctxt->level);
1193
1194   printf("[globals] currCtxt:%x, modules:%x, functions:%x symbols:%x\n",
1195     currCtxt, modules, functions, symbols);
1196   printf("  nStructs:%d, structs:%x, ssdirl:%s\n",
1197     nStructs, structs, ssdirl);
1198
1199   /**************** modules *******************/
1200   {
1201     module *m;
1202     srcLine *cs, *as;
1203     int i, mi;
1204     printf("[modules]\n");
1205     m = setFirstItem(modules);
1206     mi = 0;
1207     for (;;) {
1208       if (m == NULL)
1209         break;
1210       printf("  %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
1211         m->cfullname, m->afullname, m->name);
1212       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
1213               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
1214       printf("    cLines:%x, asmLines:%x\n",
1215               m->cLines, m->asmLines);
1216       i = 0;
1217       if (m->cLines) {
1218         cs = m->cLines[i++];
1219         printf("    [cLines] ");
1220         while (cs) {
1221           if (our_verbose)
1222             printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1223                i, cs->addr, cs->block, cs->level, cs->src);
1224           cs = m->cLines[i++];
1225         }
1226         if (!our_verbose)
1227             printf("%d records", i);
1228       }
1229       i = 0;
1230       if (m->asmLines) {
1231         as = m->asmLines[i++];
1232         printf("    [asmLines] ");
1233         while (as) {
1234           if (our_verbose)
1235             printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1236                i, as->addr, as->block, as->level, as->src);
1237           as = m->asmLines[i++];
1238         }
1239         if (!our_verbose)
1240             printf("%d records", i);
1241       }
1242       printf("\n");
1243
1244       m = setNextItem(modules);
1245     }
1246   }
1247
1248   /**************** functions *******************/
1249   {
1250     function *f;
1251     int i;
1252     printf("[functions]\n");
1253     f = setFirstItem(functions);
1254     i = 0;
1255     for (;;) {
1256       if (f == NULL)
1257         break;
1258       if (our_verbose) {
1259         printf("  %d) sym:%x, modName:%s, mod:%x\n", i,
1260           f->sym, f->modName, f->mod);
1261         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
1262                 f->entryline, f->aentryline, f->exitline, f->aexitline);
1263         printf("    cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n",
1264                 f->cfpoints, f->afpoints, f->laddr, f->lline);
1265       }
1266       ++i;
1267       f = setNextItem(functions);
1268     }
1269     if (!our_verbose)
1270       printf("   %d functions\n", i);
1271   }
1272
1273   /**************** symbols *******************/
1274   {
1275     symbol *s;
1276     int i;
1277     printf("[symbols]\n");
1278     s = setFirstItem(symbols);
1279     i = 0;
1280     for (;;) {
1281       if (s == NULL)
1282         break;
1283       if (our_verbose) {
1284         printf("  %d) name:%s, size:%d, level:%d block:%d\n", i,
1285           s->name, s->size, s->level, s->block);
1286         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
1287           s->isonstack, s->isfunc, s->offset, s->addr);
1288         printf("    eaddr:%d, addr_type:%c, type:%x etype:%x\n",
1289           s->eaddr, s->addr_type, s->type, s->etype);
1290         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
1291           s->scopetype, s->sname, s->rname, s->addrspace);
1292         printf("    next:%x\n", s->next);
1293       }
1294       ++i;
1295       s = setNextItem(symbols);
1296     }
1297     if (!our_verbose)
1298       printf("   %d symbols\n", i);
1299   }
1300
1301 }
1302
1303 /*-----------------------------------------------------------------*/
1304 /* infoStack - print call stack information                        */
1305 /*-----------------------------------------------------------------*/
1306 static void infoStack(context *ctxt)
1307 {
1308     function *func ;
1309     int i = 0 ;
1310
1311     STACK_STARTWALK(callStack) ;
1312     while ((func = STACK_WALK(callStack))) {
1313
1314         fprintf(stdout,"#%d 0x%04x %s () at %s:%d\n",i++,
1315                 func->laddr,func->sym->name,
1316                 func->mod->c_name,func->lline);
1317     }
1318
1319 }
1320
1321 /*-----------------------------------------------------------------*/
1322 /* cmdInfo - info command                                          */
1323 /*-----------------------------------------------------------------*/
1324 int cmdInfo (char *s, context *cctxt)
1325 {
1326     while (isspace(*s)) s++;
1327
1328     /* list all break points */
1329     if (strcmp(s,"break") == 0) {
1330         listUSERbp();
1331         return 0;
1332     }
1333
1334     /* info frame same as frame */
1335     if (strcmp(s,"frame") == 0) {
1336         cmdFrame (s,cctxt);
1337         return 0;
1338     }
1339
1340     /* info stack display call stack */
1341     if (strcmp(s,"stack") == 0) {
1342         infoStack(cctxt);
1343         return 0;
1344     }
1345
1346     /* info stack display call stack */
1347     if (strcmp(s,"registers") == 0) {
1348         fprintf(stdout,"%s",simRegs());
1349         return 0;
1350     }
1351
1352     /* info stack display call stack */
1353     if (strcmp(s,"symbols") == 0) {
1354       /* dump out symbols we have read in */
1355       fprintf(stdout,"Dumping symbols...\n");
1356       infoSymbols(cctxt);
1357       return 0;
1358     }
1359
1360     fprintf(stdout,"Undefined info command: \"%s\".  Try \"help\n",s);
1361     return 0;
1362
1363 }
1364
1365 /*-----------------------------------------------------------------*/
1366 /* cmdQuit  - quit debugging                                       */
1367 /*-----------------------------------------------------------------*/
1368 int cmdQuit (char *s, context *cctxt)
1369 {   
1370     if (simactive)
1371         closeSimulator();
1372     return 1;
1373 }
1374
1375 /*-----------------------------------------------------------------*/
1376 /* cmdListSrc  - list src                                          */
1377 /*-----------------------------------------------------------------*/
1378 int cmdListSrc (char *s, context *cctxt)
1379 {   
1380     static int currline = 0;
1381     int i =0 ;
1382     int pline = 0;
1383     int llines = listLines;
1384
1385     while (*s && isspace(*s)) s++;
1386     
1387     /* if the user has spcified line numer then the line number
1388        can be of the following formats
1389        LINE          - just line number
1390        FILE:LINE     - filename line number
1391        FUNCTION      - list a function
1392        FILE:FUNCTION - function in file */
1393
1394     if (*s) {
1395         /* case a) LINE */
1396         if (isdigit(*s)) {
1397             sscanf(s,"%d",&pline);
1398             if (!cctxt || !cctxt->func || !cctxt->func->mod) {
1399               if (!list_mod) {
1400                 fprintf(stdout,"Sdcdb fails to have a proper context at %d.\n", __LINE__);
1401                 return 0;
1402               }
1403             }
1404             else
1405               list_mod = cctxt->func->mod;
1406         }
1407         else {
1408             char *bp;
1409             function *func = NULL;
1410             
1411             /* if ':' present then FILE:LINE || FILE:FUNCTION */
1412             if ((bp = strchr(s,':'))) {
1413                 *bp = '\0';
1414                 bp ++;
1415                 if (isdigit(*bp)) {
1416                     /* FILE:LINE */
1417                     list_mod=NULL;  /* bug fix 2-09-02, moduleWithCName expects mod to be null */
1418                     if (srcMode == SRC_CMODE) {
1419                         if (!applyToSet(modules,moduleWithCName,s,&list_mod)) {
1420                             fprintf (stderr,"No c source file named %s.\n",s);
1421                             return 0;
1422                         }
1423                     } else {
1424                         if (!applyToSet(modules,moduleWithAsmName,s,&list_mod)) {
1425                             fprintf (stderr,"No source file named %s.\n",s);
1426                             return 0;
1427                         }
1428                     }
1429                     sscanf(bp,"%d",&pline);
1430                 } else {
1431                     /* FILE:FUCTION */
1432                     if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) {
1433                         fprintf(stdout,"Function \"%s\" not defined.\n",bp);
1434                         return 0;
1435                     }
1436                     list_mod = func->mod;
1437                     if (srcMode == SRC_CMODE) {
1438                         pline = func->entryline;
1439                         llines = func->exitline - func->entryline + 1;
1440                     } else {
1441                         pline = func->aentryline;
1442                         llines = func->aexitline - func->aentryline + 1;
1443                     }
1444                 }
1445             }
1446             else {
1447                 /* FUNCTION */
1448                 if (!applyToSet(functions,funcWithName,s,&func)) {
1449                     fprintf(stderr,"Function \"%s\" not defined.\n",s); 
1450                     return 0;
1451                 }
1452                 else {
1453                     list_mod = func->mod;
1454                     if (srcMode == SRC_CMODE) {
1455                         pline = func->entryline;
1456                         llines = func->exitline - func->entryline + 1; 
1457                     } else {
1458                         pline = func->aentryline;
1459                         llines = func->aexitline - func->aentryline + 1; 
1460                     }
1461                 }
1462             }
1463         }
1464     } else {
1465         /* if no line specified & we had listed
1466            before then continue from that listing */
1467         if (currline)
1468             pline = currline ;
1469         else {
1470             if (!cctxt || !cctxt->func || !cctxt->func->mod) {
1471               fprintf(stdout,"Missing context at %d. Try list filename:lineno\n", __LINE__);
1472               return 0;
1473             }
1474             list_mod = cctxt->func->mod;
1475             if (srcMode == SRC_CMODE)
1476                 pline = cctxt->cline;
1477             else
1478                 pline = cctxt->asmline;
1479         }
1480     }
1481
1482     if (!list_mod) {
1483       fprintf(stdout,"Sdcdb fails to have a valid module context at %d.\n", __LINE__);
1484       return 0;
1485     }
1486     
1487     if (llines > listLines) llines = listLines;
1488
1489     for ( i = 0 ; i < llines ; i++ ) {
1490         if (srcMode == SRC_CMODE) {
1491             if ( (pline + i) >= list_mod->ncLines )
1492                 break;
1493             fprintf(stdout,"%d\t%s",pline + i,
1494                     list_mod->cLines[pline +i]->src);
1495         } else {
1496             if ( (pline + i) >= list_mod->nasmLines )
1497                 break;
1498             fprintf(stdout,"%d\t%s",pline + i,
1499                     list_mod->asmLines[pline +i]->src);
1500         }
1501     }
1502     currline = pline + i ;
1503     return 0;
1504 }
1505
1506 /*-----------------------------------------------------------------*/
1507 /* printValBasic - print value of basic types                      */
1508 /*-----------------------------------------------------------------*/
1509 static void printValBasic(symbol *sym,unsigned addr,char mem, int size)
1510 {
1511     union {     
1512         float f;     
1513         unsigned long val;
1514         long         sval;
1515         struct {
1516             short    lo;
1517             short    hi;
1518         } i;
1519         unsigned char b[4];
1520     }v;
1521     union {
1522         unsigned char b[4];
1523     }v1;
1524     
1525     v.val = simGetValue(addr,mem,size);
1526     /* if this a floating point number then */
1527     if (IS_FLOAT(sym->type))    
1528         fprintf(stdout,"%f",v.f);    
1529     else
1530         if (IS_PTR(sym->type))
1531             fprintf(stdout,"0x%x",v.val);
1532         else
1533             if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) {
1534                 if (IS_CHAR(sym->etype)) 
1535                     fprintf(stdout,"'%c' %d 0x%x",v.val,v.val,v.val);
1536                 else
1537                     if (IS_INT(sym->etype)) 
1538                         if (IS_LONG(sym->etype))
1539                             if (SPEC_USIGN(sym->etype))
1540                                 fprintf(stdout,"%d 0x%x",v.val,v.val);
1541                             else
1542                                 fprintf(stdout,"%d 0x%x",v.sval,v.sval);
1543                         else
1544                             fprintf(stdout,"%d 0x%x",v.i.lo,v.i.lo);
1545                     else
1546                         fprintf(stdout,"0x%x",v.val);
1547             } else
1548                 fprintf(stdout,"0x%x",v.val);
1549                 
1550     
1551 }
1552
1553 /*-----------------------------------------------------------------*/
1554 /* printValFunc  - prints function values                          */
1555 /*-----------------------------------------------------------------*/
1556 static void printValFunc (symbol *sym)
1557 {
1558     fprintf(stdout,"print function not yet implemented\n");
1559 }
1560
1561 /*-----------------------------------------------------------------*/
1562 /* printArrayValue - will print the values of array elements       */
1563 /*-----------------------------------------------------------------*/
1564 static void printArrayValue (symbol *sym, char space, unsigned int addr)
1565 {
1566         link *elem_type = sym->type->next;
1567         int i;
1568         
1569         fprintf(stdout," { ");
1570         for (i = 0 ; i < DCL_ELEM(sym->type) ; i++) {           
1571                 if (IS_AGGREGATE(elem_type)) {
1572                         printValAggregates(sym,elem_type,space,addr);                  
1573                 } else {
1574                         printValBasic(sym,addr,space,getSize(elem_type));
1575                 }
1576                 addr += getSize(elem_type);
1577                 if (i != DCL_ELEM(sym->type) -1)
1578                         fprintf(stdout,",");
1579         }
1580
1581         fprintf(stdout,"}\n");          
1582 }
1583
1584 /*-----------------------------------------------------------------*/
1585 /* printStructValue - prints structures elements                   */
1586 /*-----------------------------------------------------------------*/
1587 static void printStructValue (symbol *sym,link *type, char space, unsigned int addr) 
1588 {
1589         symbol *fields = SPEC_STRUCT(type)->fields;
1590
1591         fprintf(stdout," { ");
1592         while (fields) {
1593                 fprintf(stdout,"%s = ",fields->name);
1594                 if (IS_AGGREGATE(fields->type)) {
1595                         printValAggregates(fields,fields->type,space, addr);
1596                 } else {
1597                         printValBasic(fields,addr,space,getSize(fields->type));
1598                 }
1599                 addr += getSize(fields->type);
1600                 fields = fields->next;
1601         }
1602         fprintf(stdout,"}\n");
1603 }
1604
1605 /*-----------------------------------------------------------------*/
1606 /* printValAggregates - print value of aggregates                  */
1607 /*-----------------------------------------------------------------*/
1608 static void printValAggregates (symbol *sym, link *type,char space,unsigned int addr)
1609 {
1610
1611         if (IS_ARRAY(type)) {
1612                 printArrayValue(sym, space, addr);
1613                 return ;
1614         }
1615
1616         if (IS_STRUCT(type)) { 
1617                 printStructValue(sym,sym->type,space, addr); 
1618                 return; 
1619         } 
1620 }
1621
1622 /*-----------------------------------------------------------------*/
1623 /* printSymValue - print value of a symbol                         */
1624 /*-----------------------------------------------------------------*/
1625 static void printSymValue (symbol *sym, context *cctxt)
1626 {
1627     static int stack = 1;
1628     unsigned long val;
1629     /* if it is on stack then compute address & fall thru */
1630     if (sym->isonstack) {
1631         symbol *bp = symLookup("bp",cctxt);
1632         if (!bp) {
1633             fprintf(stdout,"cannot determine stack frame\n");
1634             return ;
1635         }
1636
1637         sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
1638           + sym->offset ;      
1639     }
1640     
1641     /* get the value from the simulator and
1642        print it */
1643     fprintf(stdout,"$%d = ",stack++);
1644     /* arrays & structures first */
1645     if (IS_AGGREGATE(sym->type))
1646         printValAggregates(sym,sym->type,sym->addrspace,sym->addr);
1647     else
1648         /* functions */
1649         if (IS_FUNC(sym->type))
1650             printValFunc(sym);
1651         else {
1652             printValBasic(sym,sym->addr,sym->addrspace,sym->size);
1653             fprintf(stdout,"\n");
1654             //fprintf(stdout,"(BASIC %x,%c,%d)\n",sym->addr,sym->addrspace,sym->size);
1655         }
1656 }
1657
1658 /*-----------------------------------------------------------------*/
1659 /* printStructInfo - print out structure information               */
1660 /*-----------------------------------------------------------------*/
1661 static void printStructInfo (structdef *sdef)
1662 {
1663     symbol *field = sdef->fields ;
1664     int i = 0 ;
1665     
1666     while (field) {
1667         i += field->offset;
1668         field = field->next;
1669     }
1670
1671     fprintf(stdout,"%s %s {\n",(i ? "struct" : "union" ), sdef->tag);
1672     field = sdef->fields;
1673     while (field) {
1674         printTypeInfo (field->type);
1675         fprintf(stdout," %s ;\n",field->name);
1676         field = field->next ;
1677     }
1678
1679     fprintf(stdout,"}\n");
1680
1681 }
1682
1683 /*-----------------------------------------------------------------*/
1684 /* printTypeInfo - print out the type information                  */
1685 /*-----------------------------------------------------------------*/
1686 static void printTypeInfo(link *p)
1687 {
1688     if (!p)
1689         return ;
1690
1691     if (IS_DECL(p)) {
1692         switch (DCL_TYPE(p))  {
1693         case FUNCTION:
1694             printTypeInfo (p->next);
1695             fprintf(stdout,"()");
1696             break;
1697         case ARRAY:
1698             printTypeInfo (p->next);
1699             fprintf(stdout,"[%d]",DCL_ELEM(p));
1700             break;
1701         
1702         case IPOINTER:
1703         case PPOINTER:
1704         case POINTER:
1705             printTypeInfo (p->next);
1706             fprintf(stdout,"(_near *)");
1707             break;
1708
1709         case FPOINTER:
1710             printTypeInfo (p->next);
1711             fprintf(stdout,"(_xdata *)");
1712             break;
1713
1714         case CPOINTER:
1715             printTypeInfo( p->next);
1716             fprintf(stdout,"(_code *)");
1717             break;
1718             
1719         case GPOINTER:
1720             printTypeInfo( p->next);
1721             fprintf(stdout,"(_generic *)");
1722             break;                   
1723         }
1724     } else {
1725         switch (SPEC_NOUN(p)) { /* depending on the specifier type */
1726         case V_INT:
1727             (IS_LONG(p) ? fputs("long ",stdout) : 
1728              ( IS_SHORT(p) ? fputs("short ",stdout) : 
1729                fputs("int ",stdout))) ;
1730             break;
1731         case V_FLOAT:
1732              fputs("float ",stdout);
1733              break;
1734
1735         case V_CHAR:
1736             fputs ("char ",stdout);
1737             break;
1738
1739         case V_VOID:
1740             fputs("void ",stdout);
1741             break;
1742
1743         case V_STRUCT:
1744             printStructInfo (SPEC_STRUCT(p));
1745             break;
1746
1747         case V_SBIT:
1748             fputs("sbit ",stdout);
1749             break;
1750
1751         case V_BIT:
1752             fprintf(stdout,": %d" ,SPEC_BLEN(p));       
1753             break;
1754         }
1755     }
1756 }
1757
1758 /*-----------------------------------------------------------------*/
1759 /* cmdPrint - print value of variable                              */
1760 /*-----------------------------------------------------------------*/
1761 int cmdPrint (char *s, context *cctxt)
1762 {   
1763     symbol *sym ;
1764     char *bp = s+strlen(s) -1;
1765
1766     while (isspace(*s)) s++;
1767     if (!*s) return 0;
1768     while (isspace(*bp)) bp--;
1769     bp++ ;
1770     *bp = '\0';
1771
1772     if ((sym = symLookup(s,cctxt))) {
1773         printSymValue(sym,cctxt);
1774     } else {
1775         fprintf(stdout,
1776                 "No symbol \"%s\" in current context.\n",              
1777                 s);
1778     }
1779     return 0;
1780 }
1781
1782 /*-----------------------------------------------------------------*/
1783 /* cmdPrintType - print type of a variable                         */
1784 /*-----------------------------------------------------------------*/
1785 int cmdPrintType (char *s, context *cctxt)
1786 {   
1787         symbol *sym ;
1788     char *bp = s+strlen(s) -1;
1789
1790     while (isspace(*s)) s++;
1791     if (!*s) return 0;
1792     while (isspace(*bp)) bp--;
1793     bp++ ;
1794     *bp = '\0';
1795
1796     if ((sym = symLookup(s,cctxt))) {
1797         printTypeInfo(sym->type);
1798         fprintf(stdout,"\n");
1799     } else {
1800         fprintf(stdout,
1801                 "No symbol \"%s\" in current context.\n",
1802                 s);
1803     }
1804     return 0;   
1805 }
1806
1807 /*-----------------------------------------------------------------*/
1808 /* cmdClrUserBp - clear user break point                           */
1809 /*-----------------------------------------------------------------*/
1810 int cmdClrUserBp (char *s, context *cctxt)
1811 {   
1812     char *bp ;    
1813     function *func = NULL;
1814         
1815     /* clear break point location specification can be of the following
1816        forms
1817        a) <nothing>        - break point at current location
1818        b) lineno           - number of the current module
1819        c) filename:lineno  - line number of the given file
1820        e) filename:function- function X in file Y (useful for static functions)
1821        f) function         - function entry point
1822     */
1823
1824     if (!cctxt) {
1825         fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
1826         return 0;
1827     }
1828
1829     /* white space skip */
1830     while (*s && isspace(*s)) s++;
1831     
1832     /* null terminate it after stripping trailing blanks*/
1833     bp = s + strlen(s);
1834     while (bp != s && isspace(*bp)) bp--;
1835     *bp = '\0';
1836
1837     /* case a) nothing */
1838     /* if nothing given then current location : we know
1839        the current execution location from the currentContext */
1840     if (! *s ) {
1841
1842         /* if current context is known */
1843         if (cctxt->func) 
1844             /* clear the break point @ current location */
1845             clearUSERbp (cctxt->addr);
1846         else
1847             fprintf(stderr,"No default breakpoint address now.\n");
1848                         
1849         goto ret ;
1850     }
1851
1852     /* case b) lineno */
1853     /* check if line number */
1854     if (isdigit(*s)) {
1855         /* get the lineno */
1856         int line = atoi(s);
1857
1858         /* if current context not present then we must get the module
1859            which has main & set the break point @ line number provided
1860            of that module : if current context known then set the bp 
1861            at the line number given for the current module 
1862         */
1863         if (cctxt->func) {
1864             if (!cctxt->func->mod) {
1865                 if (!applyToSet(functions,funcWithName,"main"))
1866                     fprintf(stderr,"Function \"main\" not defined.\n");
1867                 else 
1868                     clearBPatModLine(func->mod,line);
1869             } else 
1870                 clearBPatModLine(cctxt->func->mod,line);                        
1871         }
1872         
1873         goto ret;
1874     }
1875
1876     if ((bp = strchr(s,':'))) {
1877         
1878         module *mod = NULL;
1879         *bp = '\0';
1880         
1881         if (!applyToSet(modules,moduleWithCName,s,&mod)) {
1882             fprintf (stderr,"No source file named %s.\n",s);
1883             goto ret;
1884         }
1885
1886         /* case c) filename:lineno */
1887         if (isdigit(*(bp +1))) {                    
1888          
1889             clearBPatModLine (mod,atoi(bp+1));      
1890             goto ret;
1891             
1892         }
1893         /* case d) filename:function */
1894         if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
1895             fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
1896         else
1897             clearBPatModLine (mod,func->entryline);
1898         
1899         goto ret;
1900     }
1901             
1902     /* case e) function */
1903     if (!applyToSet(functions,funcWithName,s,&func))
1904         fprintf(stderr,"Function \"%s\" not defined.\n",s); 
1905     else
1906         clearBPatModLine(func->mod,func->entryline);
1907
1908  ret:    
1909     return 0;        
1910 }
1911
1912
1913 /*-----------------------------------------------------------------*/
1914 /* cmdSimulator - send command to simulator                        */
1915 /*-----------------------------------------------------------------*/
1916 int cmdSimulator (char *s, context *cctxt)
1917 {   
1918   char tmpstr[82];
1919
1920     if (strlen(s) > 80) {
1921       printf("error 3A\n");
1922       exit(1);
1923     }
1924     strcpy(tmpstr, s);
1925     strcat(tmpstr, "\n");
1926     sendSim(tmpstr);
1927     waitForSim(200,NULL);
1928     fprintf(stdout,"%s",simResponse());
1929     return 0;
1930 }
1931
1932 /*-----------------------------------------------------------------*/
1933 /* cmdFrame - Frame command                                        */
1934 /*-----------------------------------------------------------------*/
1935 int cmdFrame (char *s, context *cctxt)
1936 {   
1937     function *func ;
1938
1939     if ((func = STACK_PEEK(callStack))) {
1940         fprintf(stdout,"#0  %s () at %s:%d\n",
1941                 func->sym->name,func->mod->c_name,cctxt->cline);
1942
1943         if (cctxt->cline < func->mod->ncLines)      
1944             fprintf(stdout,"%d\t%s",
1945                     cctxt->cline,
1946                     func->mod->cLines[cctxt->cline]->src);
1947     } else
1948         fprintf(stdout,"No stack.\n");
1949     return 0;
1950 }
1951
1952 /*-----------------------------------------------------------------*/
1953 /* cmdFinish - exec till end of current function                   */
1954 /*-----------------------------------------------------------------*/
1955 int cmdFinish (char *s, context *ctxt)
1956 {
1957     if (!ctxt || ! ctxt->func) {
1958         fprintf(stdout,"The program is not running.\n");
1959         return 0;
1960     }
1961
1962     if (srcMode == SRC_CMODE) {
1963         setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, 
1964                        stepBpCB, ctxt->func->mod->c_name, 
1965                        ctxt->func->exitline);
1966     } else {
1967         setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, 
1968                        stepBpCB, ctxt->func->mod->asm_name, 
1969                        ctxt->func->aexitline);
1970     }
1971
1972     simGo(-1);
1973     return 0;
1974     
1975 }
1976
1977
1978 /*-----------------------------------------------------------------*/
1979 /* cmdShow - show command                                          */
1980 /*-----------------------------------------------------------------*/
1981 int cmdShow (char *s, context *cctxt)
1982 {
1983     /* skip white space */
1984     while (*s && isspace(*s)) s++ ;
1985
1986     if (strcmp(s,"copying") == 0) {
1987         fputs(copying,stdout);
1988         return 0;
1989     }
1990     
1991     if (strcmp(s,"warranty") == 0) {
1992         fputs(warranty,stdout);
1993         return 0;
1994     }
1995
1996     return 0;
1997 }
1998