sdcdb updates,ddd
[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 static void setSymValue(symbol *sym, char *val, context *cctxt);
332
333 int srcMode = SRC_CMODE ;
334 static set  *dispsymbols = NULL   ; /* set of displayable symbols */
335
336 /*-----------------------------------------------------------------*/
337 /* funcWithName - returns function with name                       */
338 /*-----------------------------------------------------------------*/
339 DEFSETFUNC(funcWithName)
340 {
341     function *func = item;
342     V_ARG(char *,name);
343     V_ARG(function **,funcp);
344
345     if (*funcp)
346         return 0;
347
348     if (strcmp(func->sym->name,name) == 0) {
349         *funcp = func;
350         return 1;
351     }
352     
353     return 0;
354 }
355
356 /*-----------------------------------------------------------------*/
357 /* setBPatModLine - set break point at the line specified for the  */
358 /*-----------------------------------------------------------------*/
359 static void setBPatModLine (module *mod, int line)
360 {
361   int next_line;
362
363     /* look for the first executable line after the line
364        specified & get the break point there */    
365     if (srcMode == SRC_CMODE && line > mod->ncLines) {
366         fprintf(stderr,"No line %d in file \"%s\".\n",
367                 line,mod->c_name);
368         return ;
369     }
370     
371     if (srcMode == SRC_AMODE && line > mod->nasmLines) {
372         fprintf(stderr,"No line %d in file \"%s\".\n",
373                 line,mod->asm_name);
374         return ;
375     }
376
377     next_line = line;
378     for ( ; next_line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; 
379           next_line++ ) {
380         if (srcMode == SRC_CMODE) {
381             if (mod->cLines[next_line]->addr) {
382                 setBreakPoint (mod->cLines[next_line]->addr, CODE, USER, 
383                                userBpCB, mod->c_name, next_line);
384                 return;
385 //              break;
386             }
387         }
388         else {
389            if (mod->asmLines[next_line]->addr) {
390                setBreakPoint (mod->asmLines[next_line]->addr, CODE, USER, 
391                               userBpCB, mod->asm_name, next_line);
392                 return;
393 //             break;
394            } 
395         }
396     }
397
398         fprintf(stderr,"No line %d or after in file \"%s\"..\n",
399                         line,mod->c_name);
400
401     return;
402 }
403
404 /*-----------------------------------------------------------------*/
405 /* clearBPatModLine - clr break point at the line specified        */
406 /*-----------------------------------------------------------------*/
407 static void clearBPatModLine (module *mod, int line)
408 {
409     /* look for the first executable line after the line
410        specified & get the break point there */
411     if (srcMode == SRC_CMODE && line > mod->ncLines) {
412         fprintf(stderr,"No line %d in file \"%s\".\n",
413                 line,mod->c_name);
414         return ;
415     }
416     
417     if (srcMode == SRC_AMODE && line > mod->ncLines) {
418         fprintf(stderr,"No line %d in file \"%s\".\n",
419                 line,mod->c_name);
420         return ;
421     }    
422     
423     for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ; 
424           line++ ) {
425         if (srcMode == SRC_CMODE) 
426             if (mod->cLines[line]->addr) {
427                 clearUSERbp (mod->cLines[line]->addr);                    
428                 break;
429             }
430         else
431             if (mod->asmLines[line]->addr) {
432                 clearUSERbp (mod->asmLines[line]->addr);                          
433                 break;
434             }
435     }
436
437     return;
438 }
439
440 /*-----------------------------------------------------------------*/
441 /* moduleLineWithAddr - finds and returns a line  with a given address */
442 /*-----------------------------------------------------------------*/
443 DEFSETFUNC(moduleLineWithAddr)
444 {
445     module *mod = item;
446     int i;
447
448     V_ARG(unsigned int,addr);
449     V_ARG(module **,rmod);
450     V_ARG(int *,line);
451
452     if (*rmod)
453         return 0;
454
455     for (i=0; i < mod->nasmLines; i++ ) 
456     {
457         if ( mod->asmLines[i]->addr == addr)
458         {
459             *rmod = mod ;
460             if (line )
461                 *line = mod->ncLines;
462             return 1;
463         }
464     }
465
466     return 0;
467 }
468
469 /*-----------------------------------------------------------------*/
470 /* funcWithNameModule - returns functions with a name module combo */
471 /*-----------------------------------------------------------------*/
472 DEFSETFUNC(funcWithNameModule) 
473 {
474     function *func = item;
475     V_ARG(char *,fname);
476     V_ARG(char *,mname);
477     V_ARG(function **,funcp);
478
479     if (*funcp)
480         return 0;
481
482     if (strcmp(func->sym->name,fname) == 0 &&
483         strcmp(func->mod->c_name,mname) == 0) {
484         *funcp = func;
485         return 1;
486     }
487
488     return 0;
489 }
490
491 /*-----------------------------------------------------------------*/
492 /* funcInAddr - given an address returns the function              */
493 /*-----------------------------------------------------------------*/
494 DEFSETFUNC(funcInAddr)
495 {
496     function *func = item;
497     V_ARG(unsigned int,addr);
498     V_ARG(function **,funcp);
499
500     if (*funcp)
501         return 0;
502
503     /* in the address range */
504     if (func->sym->addr <= addr &&
505         func->sym->eaddr >= addr) {
506         
507         *funcp = func;
508         return 1;
509     }
510
511     return 0;       
512 }
513
514 /*-----------------------------------------------------------------*/
515 /* setStepBp - will set STEP Bp @ function entry points            */
516 /*-----------------------------------------------------------------*/
517 DEFSETFUNC(setStepBp)
518 {
519     function *func = item;
520     
521     if (func->sym && func->sym->addr ) {
522         
523         /* set the entry break point */
524         setBreakPoint (func->sym->addr , CODE , STEP , 
525                        stepBpCB ,func->mod->c_name , func->entryline);
526
527         return 1;
528     }
529
530     return 0;
531 }
532
533 /*-----------------------------------------------------------------*/
534 /* setStepEPBp - sets a given type of bp @ the execution point     */
535 /*-----------------------------------------------------------------*/
536 DEFSETFUNC(setStepEPBp)
537 {
538     exePoint *ep = item;
539     V_ARG(int,bptype);
540     V_ARG(char *,mname);
541    
542     setBreakPoint (ep->addr, CODE, bptype, 
543                    stepBpCB, mname, ep->line);
544     return 1;
545 }
546
547 /*-----------------------------------------------------------------*/
548 /* setNextEPBp - sets a given type of bp @ the execution point     */
549 /*-----------------------------------------------------------------*/
550 DEFSETFUNC(setNextEPBp)
551 {
552     exePoint *ep = item;
553     V_ARG(int,bptype);
554     V_ARG(char *,mname);
555    
556     setBreakPoint (ep->addr, CODE, bptype, 
557                    nextBpCB, mname, ep->line);
558     return 1;
559 }
560
561 /*-----------------------------------------------------------------*/
562 /* lineAtAddr - for execution points returns the one with addr     */
563 /*-----------------------------------------------------------------*/
564 DEFSETFUNC(lineAtAddr)
565 {
566     exePoint *ep = item;
567     V_ARG(unsigned int,addr);
568     V_ARG(int *,line);
569     V_ARG(int *,block);
570     V_ARG(int *,level);
571
572     /* address must be an exact match */
573     if (ep->addr == addr) {
574         *line = ep->line;
575         if (block)
576             *block = ep->block ;
577         if (level)
578             *level = ep->level ;
579         return 1;
580     }
581
582     return 0;
583     
584 }
585
586 /*-----------------------------------------------------------------*/
587 /* lineNearAddr - for execution points returns the one with addr   */
588 /*-----------------------------------------------------------------*/
589 DEFSETFUNC(lineNearAddr)
590 {
591     exePoint *ep = item;
592     V_ARG(unsigned int,addr);
593     V_ARG(int *,line);
594     V_ARG(int *,block);
595     V_ARG(int *,level);
596
597     /* the line in which the address is */
598     if (ep->addr <= addr) {
599         *line = ep->line;
600         if (block)
601             *block = ep->block ;
602         if (level)
603             *level = ep->level ;
604         return 1;
605     }
606
607     return 0;
608     
609 }
610
611 /*-----------------------------------------------------------------*/
612 /* discoverContext - find out the current context of the bp        */
613 /*-----------------------------------------------------------------*/
614 context *discoverContext (unsigned addr)
615 {
616     function *func = NULL;
617     module   *mod  = NULL;
618     int line = 0;
619
620     /* find the function we are in */
621     if (!applyToSet(functions,funcInAddr,addr,&func)) {
622         if (!applyToSet(functions,funcWithName,"main") ||
623             !applyToSet(modules,moduleLineWithAddr,addr,&mod,&line))
624         {
625             fprintf(stderr, "Error?:discoverContext: cannot apply to set!\n");
626             return NULL;
627         }
628         currCtxt->func = func;
629         currCtxt->addr = addr;
630         currCtxt->modName = mod->name;
631         currCtxt->cline = func->exitline;
632     }
633     else
634     {
635         currCtxt->func = func;
636         currCtxt->addr = func->laddr = addr;
637         currCtxt->modName = func->modName;
638     
639         /* find the c line number */
640         if(applyToSet(func->cfpoints,lineNearAddr,addr,
641                   &line,&currCtxt->block,&currCtxt->level)) 
642             currCtxt->cline = func->lline = line;
643         else
644             currCtxt->cline = func->exitline;
645     }    
646     /* find the asm line number */
647     line = 0;
648     if (applyToSet(func->afpoints,lineAtAddr,addr,
649                    &line,NULL,NULL))
650         currCtxt->asmline = line;       
651     else
652         currCtxt->asmline = -1;
653         
654     return currCtxt ;
655 }
656
657
658 /*-----------------------------------------------------------------*/
659 /* simGo - send 'go' cmd to simulator and wait till a break occurs */
660 /*-----------------------------------------------------------------*/
661 void simGo (unsigned int gaddr)
662 {   
663     unsigned int addr ;
664     context *ctxt;
665     int rv;
666     static int initial_break_flag = 0;
667
668  top:    
669     if ( userinterrupt )
670     {
671         userinterrupt = 0;
672         return;
673     }
674     addr = simGoTillBp (gaddr);
675
676     /* got the pc for the break point now first
677        discover the program context i.e. module, function 
678        linenumber of the source etc, etc etc */
679     ctxt = discoverContext (addr);
680     
681     /* dispatch all the break point call back functions */
682     rv = dispatchCB (addr,ctxt);    
683  ret:    
684
685     /* the dispatch call back function will return
686        non-zero if an user break point has been hit
687        if not then we continue with the execution 
688        of the program */
689     if (!rv) {
690       if (!initial_break_flag) {
691         initial_break_flag = 1;  // kludge to stop only at first run
692         fprintf(stdout, "Stopping at entry.  You can now list and set breakpoints\n");
693       }
694       else {
695         gaddr = -1;
696         goto top ;
697       }
698
699 // notes: kpb
700 // I took this out, after running "run" it would just keep re-running
701 // even after a lot of break points hit.  For some reason above code
702 // not triggering(dispatchCB).  This seems to be by design, startup adds
703 // a bunch of breakpoints-but they are not USER breakpoints.  Perhaps the
704 // debugger changed with its implementation of "go"("run").  It seems we
705 // need to add a "next" or "step" followed by a "run"...
706 // I added a "step" in simi.c when we want a resume function, this seems
707 // to work.
708
709 // still there is question of how do we stop it initially, since
710 // it must be started before it can get a context.  If so, we would
711 // want it to just run up to an initial entry point you'd think...
712 // I don't see why we can't set breakpoints before an initial run,
713 // this does not seem right to me.
714
715 // line #'s are a bit off too.
716
717 #if 0
718         gaddr = -1;
719         goto top ;
720 #endif
721     }
722     
723 }
724
725 static int printAsmLine( function *func, module *m, long saddr, long eaddr)
726 {
727     int i,j,delta;
728     int symaddr;
729     int lastaddr = saddr+1;
730     char *symname;
731
732     if ( func )
733     {
734         symaddr = func->sym->addr;
735         symname = func->sym->name;
736     }
737     else
738     {
739         symaddr = saddr;
740         symname = "" ;
741     }
742     for (j=0,i=0; i < m->nasmLines; i++ ) 
743     {
744         if ( saddr >= 0 && m->asmLines[i]->addr < saddr)
745         {
746                 continue;
747         }
748         if ( eaddr >= 0 && m->asmLines[i]->addr > eaddr)
749         {
750                 continue;
751         }
752         if ( func && 
753             (m->asmLines[i]->addr < func->sym->addr ||
754              m->asmLines[i]->addr > func->sym->eaddr ))
755         {
756             continue;
757         } 
758         delta = m->asmLines[i]->addr - symaddr;
759         if ( delta >= 0 )
760         {
761             j++;
762             lastaddr = m->asmLines[i]->addr;
763             printf("0x%08x <%s",lastaddr,symname);
764             if (delta > 0) printf("+%d",delta);
765             printf(">:\t%s",m->asmLines[i]->src);            
766         }
767     }
768     return lastaddr;
769 }
770
771 /*-----------------------------------------------------------------*/
772 /* cmdDisasm - disassemble  asm instruction                        */
773 /*-----------------------------------------------------------------*/
774 static int cmdDisasm (char *s, context *cctxt, int args)
775 {
776     function *func = NULL;
777     long  saddr = -1;
778     long  eaddr = -1;
779     int   found = 0;
780     module *modul;
781     /* white space skip */
782
783     if ( args > 0 )
784     {
785         while (*s && isspace(*s)) s++;
786
787         if ( isdigit(*s))
788         {
789             saddr = strtol(s,&s,0);
790             if ( args > 1 )
791             {
792                 while (*s && isspace(*s)) s++;
793
794                 if ( isdigit(*s))
795                     eaddr = strtol(s,0,0);
796             }
797             else
798                 eaddr = saddr+1;
799         }
800     }
801
802     if ( eaddr == -1 )
803     {       
804         /* no start or only start so dump function */
805         if ( saddr == -1 )
806         {
807             func = cctxt->func;
808         }
809         else
810         {
811             applyToSet(functions,funcInAddr,saddr,&func);
812         }
813         if ( func )
814         {
815             printf("Dump of assembler code for function %s:\n",func->sym->name);
816             printAsmLine(func,func->mod,-1,-1);
817             printf("End of assembler dump.\n");
818             return 0; 
819         }
820         else
821         {
822             if (applyToSet(modules,moduleLineWithAddr,saddr,&modul,NULL))
823             {
824                 eaddr = saddr + 5;
825                 printf("Dump of assembler code:\n");
826                 printAsmLine(NULL,modul,saddr,eaddr);
827                 printf("End of assembler dump.\n");
828                 return 0; 
829             }
830         }
831     }
832     else
833     {
834         if ( args > 1 )
835             printf("Dump of assembler code from 0x%08x to 0x%08x:\n",saddr,eaddr);
836         found = 0;
837         while ( saddr < eaddr )
838         {
839             func = NULL;
840             if (applyToSet(functions,funcInAddr,saddr,&func))
841             {
842                 found = 1;
843                 modul = func->mod;
844             }
845             else
846             {
847                 if ( found )
848                     break;
849                 if (!applyToSet(modules,moduleLineWithAddr,saddr,&modul,NULL))
850                     break;
851             }
852             saddr = printAsmLine(func,modul,saddr,eaddr) + 1;
853         }
854         if( saddr >= eaddr)
855         {
856             if ( args > 1 )
857                 printf("End of assembler dump.\n");
858             return 0; 
859         }
860         
861     }
862     fprintf(stderr,"No function contains specified address.\n");
863     return 0; 
864 }
865 /*-----------------------------------------------------------------*/
866 /* cmdDisasm1 - disassemble one asm instruction                    */
867 /*-----------------------------------------------------------------*/
868 int cmdDisasm1 (char *s, context *cctxt)
869 {
870     return cmdDisasm( s, cctxt, 1);
871 }
872
873 /*-----------------------------------------------------------------*/
874 /* cmdDisasmF - disassemble asm instructions                       */
875 /*-----------------------------------------------------------------*/
876 int cmdDisasmF(char *s, context *cctxt)
877 {
878     return cmdDisasm( s, cctxt, 2);
879 }
880
881 /*-----------------------------------------------------------------*/
882 /* cmdSetUserBp - set break point at the user specified location   */
883 /*-----------------------------------------------------------------*/
884 int cmdSetUserBp (char *s, context *cctxt)
885 {
886     char *bp ;
887     function *func = NULL;
888         
889     /* user break point location specification can be of the following
890        forms
891        a) <nothing>        - break point at current location
892        b) lineno           - number of the current module
893        c) filename:lineno  - line number of the given file
894        e) filename:function- function X in file Y (useful for static functions)
895        f) function         - function entry point
896        g) *addr            - break point at address 
897     */
898
899     if (!cctxt) {
900         fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
901         return 0;
902     }
903     /* white space skip */
904     while (*s && isspace(*s)) s++;
905     
906     /* null terminate it after stripping trailing blanks*/
907     bp = s + strlen(s);
908     while (bp != s && isspace(*bp)) bp--;
909     *bp = '\0';
910
911     /* case a) nothing */
912     /* if nothing given then current location : we know
913        the current execution location from the currentContext */
914     if (! *s ) {
915
916         /* if current context is known */
917         if (cctxt->func) {
918             if (srcMode == SRC_CMODE)
919                 /* set the break point */
920                 setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
921                                 cctxt->func->mod->c_name, cctxt->cline);
922             else
923                 setBreakPoint ( cctxt->addr , CODE , USER , userBpCB ,
924                                 cctxt->func->mod->asm_name, cctxt->asmline);
925                 
926         }
927         else
928             fprintf(stderr,"No default breakpoint address now.\n");
929                         
930         goto ret ;
931     }
932     /* case g) *addr */
933     if ( *s == '*' && isdigit(*(s+1)))
934     {
935         int  line   = 0;
936         long braddr = strtol(s+1,0,0);
937         if (!applyToSet(functions,funcInAddr,braddr,&func))
938         {
939             module *modul;
940             if (!applyToSet(modules,moduleLineWithAddr,braddr,&modul,&line))
941             {
942                 fprintf(stderr,"Address 0x%08x not exists in code.\n",braddr); 
943             }
944             else
945             {
946                 setBreakPoint ( braddr , CODE , USER , userBpCB ,
947                             modul->c_name,line);
948             }
949             goto ret ;
950         }
951                 else
952         {
953             int line = func->exitline;
954             applyToSet(func->cfpoints,lineNearAddr,braddr,&line,NULL,NULL);
955             setBreakPoint ( braddr , CODE , USER , userBpCB ,
956                             func->mod->c_name,line);
957         }
958         goto ret ;
959     }
960     /* case b) lineno */
961     /* check if line number */
962     if (isdigit(*s)) {
963         /* get the lineno */
964         int line = atoi(s);
965
966         /* if current context not present then we must get the module
967            which has main & set the break point @ line number provided
968            of that module : if current context known then set the bp 
969            at the line number given for the current module 
970         */
971         if (cctxt->func) {
972             if (!cctxt->func->mod) {
973                 if (!applyToSet(functions,funcWithName,"main"))
974                     fprintf(stderr,"Function \"main\" not defined.\n");
975                 else 
976                     setBPatModLine(func->mod,line);
977             } else 
978                 setBPatModLine(cctxt->func->mod,line);
979         } else {
980                 if (list_mod) {
981                         setBPatModLine(list_mod,line);
982                 } else {
983                   fprintf(stdout,"Sdcdb fails to have module symbol context at %d\n", __LINE__);
984                 }
985         }
986         
987         goto ret;
988     }
989
990     if ((bp = strchr(s,':'))) {
991         
992         module *mod = NULL;
993         *bp = '\0';
994         
995         if (srcMode == SRC_CMODE) {
996             if (!applyToSet(modules,moduleWithCName,s,&mod)) {
997                 fprintf (stderr,"No source file named %s.\n",s);
998                 goto ret;
999             }
1000         } else {
1001             if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
1002                 fprintf (stderr,"No source file named %s.\n",s);
1003                 goto ret;
1004             }
1005         }
1006                 
1007         /* case c) filename:lineno */
1008         if (isdigit(*(bp +1))) {                    
1009          
1010             setBPatModLine (mod,atoi(bp+1));        
1011             goto ret;
1012             
1013         }
1014         /* case d) filename:function */
1015         if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
1016             fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
1017         else        
1018             setBPatModLine (mod,
1019                             (srcMode == SRC_CMODE ? 
1020                              func->entryline :
1021                              func->aentryline));
1022         
1023         goto ret;
1024     }
1025             
1026     /* case e) function */
1027     if (!applyToSet(functions,funcWithName,s,&func))
1028         fprintf(stderr,"Function \"%s\" not defined.\n",s); 
1029     else
1030         setBPatModLine(func->mod,
1031                        (srcMode == SRC_CMODE ?
1032                         func->entryline :
1033                         func->aentryline));
1034
1035  ret:    
1036     return 0;
1037 }
1038
1039 /*-----------------------------------------------------------------*/
1040 /* cmdListAsm - list assembler source code                         */
1041 /*-----------------------------------------------------------------*/
1042 int cmdListAsm (char *s, context *cctxt)
1043 {
1044     if (  cctxt && cctxt->func) 
1045     {
1046         /* actual line */
1047         if (printAsmLine(cctxt->func,cctxt->func->mod,
1048                          (long)cctxt->addr,(long)cctxt->addr))
1049             return 0; 
1050     }
1051     return 0;
1052 }
1053
1054 /*-----------------------------------------------------------------*/
1055 /* cmdSetOption - set debugger options                             */
1056 /*-----------------------------------------------------------------*/
1057 int cmdSetOption (char *s, context *cctxt)
1058 {
1059     while (*s && isspace(*s)) s++;
1060     if (strncmp(s,"srcmode",7) == 0 ) {
1061         if (srcMode == SRC_CMODE)
1062             srcMode = SRC_AMODE;
1063         else
1064             srcMode = SRC_CMODE;
1065         fprintf(stderr,"source mode set to '%s'\n", 
1066                 (srcMode == SRC_CMODE ? "C" : "asm"));
1067         return 0;
1068     }
1069
1070     if (strncmp(s,"variable ",9) == 0) 
1071     {
1072         symbol *sym ;
1073         char *val;
1074         s += 9;
1075         while (isspace(*s)) s++;
1076         if (!*s) return 0;
1077
1078         val = s;
1079         while (*val && !isspace(*val) && *val != '=') val++;
1080         while (isspace(*val)) *val++ = '\0';
1081         if (*val) *val++ = '\0';
1082         if (*val)
1083         {
1084             if ((sym = symLookup(s,cctxt))) 
1085             {
1086                 setSymValue(sym,val,cctxt);
1087                 return 0;
1088             }   
1089             fprintf(stdout,"No symbol \"%s\" in current context.\n",s);
1090         }
1091         else
1092             fprintf(stdout,"No new value for \"%s\".\n",s);
1093         return 0;       
1094     }
1095
1096  
1097     fprintf(stderr,"'set %s' command not yet implemented\n",s);
1098     return 0;
1099 }
1100
1101 /*-----------------------------------------------------------------*/
1102 /* cmdContinue - continue till next break point                    */
1103 /*-----------------------------------------------------------------*/
1104 int cmdContinue (char *s, context *cctxt)
1105 {
1106     if (!cctxt || !cctxt->func) {
1107         fprintf(stdout,"The program is not being run.\n");
1108         return 0;
1109     }
1110
1111     fprintf(stdout,"Continuing.\n");
1112     simGo(-1);
1113     showfull = 1;
1114     return 0;
1115 }
1116
1117 /*-----------------------------------------------------------------*/
1118 /* cmdDelUserBp - delete user break point                          */
1119 /*-----------------------------------------------------------------*/
1120 int cmdDelUserBp (char *s, context *cctxt)
1121 {
1122     int bpnum ;
1123     while (isspace(*s)) s++;
1124     
1125     if (!*s ) {
1126         if (userBpPresent) {
1127             char buffer[10];
1128             fprintf (stdout,"Delete all breakpoints? (y or n) ");
1129             fflush(stdout);
1130             fgets(buffer,sizeof(buffer),stdin);
1131             if (toupper(buffer[0]) == 'Y')
1132                 deleteUSERbp(-1);          
1133         }
1134         return 0;
1135     }
1136     
1137     /* determine the break point number */
1138     if (sscanf(s,"%d",&bpnum) == 1)
1139         deleteUSERbp(bpnum);
1140
1141     return 0;
1142 }
1143
1144 /*-----------------------------------------------------------------*/
1145 /* cmdStep - single step thru C source file                        */
1146 /*-----------------------------------------------------------------*/
1147 int cmdStep (char *s, context *cctxt)
1148 {
1149     function *func = NULL;
1150
1151     if (!cctxt || !cctxt->func || !cctxt->func->mod) 
1152         fprintf(stdout,"The program is not being run.\n");
1153     else {
1154     int origSrcMode = srcMode;
1155     if ( *s == 'i' )
1156         srcMode = SRC_AMODE;
1157         /* if we are @ the end of a function then set
1158            break points at execution points of the
1159            function in the call stack... */
1160         if (cctxt->addr == cctxt->func->sym->eaddr) {
1161             if ((func = STACK_PEEK(callStack))) {
1162                 if (srcMode == SRC_CMODE)
1163                     applyToSet (func->cfpoints,setStepEPBp,STEP,
1164                                 func->mod->c_name);     
1165                 else
1166                     applyToSet (func->afpoints,setStepEPBp,STEP,
1167                                 func->mod->asm_name);
1168             }
1169         } else {
1170             /* set breakpoints at all function entry points
1171                and all exepoints of this functions & for
1172                all functions one up in the call stack */
1173             
1174             /* all function entry points */
1175             applyToSet(functions,setStepBp); 
1176             
1177             if (srcMode == SRC_CMODE) {
1178                 /* for all execution points in this function */
1179                 applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP,
1180                            cctxt->func->mod->c_name);
1181                 
1182                 /* set a break point @ the current function's
1183                    exit */
1184                 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
1185                                stepBpCB, cctxt->func->mod->c_name, 
1186                                cctxt->func->exitline);
1187                 
1188                 /* now break point @ callers execution points */
1189                 if ((func = STACK_PPEEK(callStack))) {
1190                     applyToSet (func->cfpoints,setStepEPBp,STEP,
1191                                 func->mod->c_name);     
1192                     /* set bp @ callers exit point */
1193                     setBreakPoint (func->sym->eaddr, CODE, STEP , 
1194                                    stepBpCB, func->mod->c_name, 
1195                                    func->exitline);
1196                 }
1197             } else {
1198                 /* for all execution points in this function */
1199                 applyToSet(cctxt->func->afpoints,setStepEPBp,STEP,
1200                            cctxt->func->mod->asm_name);
1201                 
1202                 /* set a break point @ the current function's
1203                    exit */
1204                 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP , 
1205                                stepBpCB, cctxt->func->mod->asm_name, 
1206                                cctxt->func->aexitline);
1207                 
1208                 /* now break point @ callers execution points */
1209                 if ((func = STACK_PPEEK(callStack))) {
1210                     
1211                     applyToSet (func->afpoints,setStepEPBp,STEP,
1212                                 func->mod->asm_name);   
1213                     
1214                     /* set bp @ callers exit point */
1215                     setBreakPoint (func->sym->eaddr, CODE, STEP , 
1216                                    stepBpCB, func->mod->asm_name, 
1217                                    func->aexitline);
1218                 }
1219             }
1220         }
1221
1222     srcMode = origSrcMode;
1223         simGo(-1);
1224     showfull = 1;
1225     }
1226     return 0;
1227 }
1228
1229 /*-----------------------------------------------------------------*/
1230 /* cmdNext - next executable C statement file                      */
1231 /*-----------------------------------------------------------------*/
1232 int cmdNext (char *s, context *cctxt)
1233 {
1234     function *func = NULL;
1235     /* next is almost the same as step except we don't
1236        we don't set break point for all function entry
1237        points */
1238     if (!cctxt || !cctxt->func || !cctxt->func->mod) 
1239         fprintf(stdout,"The program is not being run.\n");
1240     else {
1241     int origSrcMode = srcMode;
1242     if ( *s == 'i' )
1243         srcMode = SRC_AMODE;
1244         
1245         /* if we are @ the end of a function then set
1246            break points at execution points of the
1247            function in the call stack... */
1248         if (cctxt->addr == cctxt->func->sym->eaddr) {
1249             if ((func = STACK_PEEK(callStack))) {
1250                 if (srcMode == SRC_CMODE)
1251                     applyToSet (func->cfpoints,setStepEPBp,STEP,
1252                                 func->mod->c_name);     
1253                 else
1254                     applyToSet (func->afpoints,setStepEPBp,STEP,
1255                                func->mod->asm_name);
1256             }
1257         } else {
1258             if (srcMode == SRC_CMODE) {
1259                 /* for all execution points in this function */
1260                 applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT,
1261                            cctxt->func->mod->c_name);
1262                 /* set a break point @ the current function's
1263                    exit */
1264                 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
1265                                nextBpCB, cctxt->func->mod->c_name, 
1266                                cctxt->func->exitline);
1267                 
1268                 /* now break point @ callers execution points */        
1269                 if ((func = STACK_PPEEK(callStack))) {
1270                     applyToSet (func->cfpoints,setNextEPBp,NEXT ,
1271                                 func->mod->c_name);     
1272                     /* set bp @ callers exit point */
1273                     setBreakPoint (func->sym->eaddr, CODE, NEXT , 
1274                                    stepBpCB, func->mod->c_name, 
1275                                    func->exitline);
1276                 }
1277             } else {
1278                 /* for all execution points in this function */
1279                 applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT,
1280                            cctxt->func->mod->asm_name);
1281                 /* set a break point @ the current function's
1282                    exit */
1283                 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT , 
1284                                nextBpCB, cctxt->func->mod->asm_name, 
1285                                cctxt->func->aexitline);
1286                 
1287                 /* now break point @ callers execution points */        
1288                 if ((func = STACK_PPEEK(callStack))) {
1289                     applyToSet (func->cfpoints,setNextEPBp,NEXT ,
1290                                 func->mod->asm_name);   
1291                     /* set bp @ callers exit point */
1292                     setBreakPoint (func->sym->eaddr, CODE, NEXT , 
1293                                    stepBpCB, func->mod->asm_name, 
1294                                    func->aexitline);
1295                 }
1296             }
1297         srcMode = origSrcMode;
1298             simGo(-1);  
1299         showfull = 1;
1300         }
1301     srcMode = origSrcMode;
1302     }    
1303     return 0;
1304 }
1305
1306 /*-----------------------------------------------------------------*/
1307 /* cmdRun  - run till next break point                             */
1308 /*-----------------------------------------------------------------*/
1309 int cmdRun (char *s, context *cctxt)
1310 {
1311     char buff[10];
1312     if (!cctxt || !cctxt->func || !cctxt->func->mod) {
1313         fprintf(stdout,"Starting program\n");
1314     if ( ! simactive )
1315     {
1316         fprintf(stdout,"No executable file specified.\nUse the \"file\" command.\n");
1317         return 0;
1318     }
1319         simGo(0);
1320     } else {
1321         
1322         fprintf(stdout,
1323                 "The program being debugged has been started already.\n");
1324         fprintf(stdout,"Start it from the beginning? (y or n) ");
1325         fflush(stdout);
1326
1327         fgets(buff,sizeof(buff),stdin);
1328         if (toupper(buff[0]) == 'Y') {
1329             simReset();
1330             simGo(0);
1331         }
1332     }
1333     showfull = 1;
1334     return 0;
1335 }
1336
1337 /*-----------------------------------------------------------------
1338  cmdListSymbols - list symbols
1339 |-----------------------------------------------------------------*/
1340 int cmdListSymbols (char *s, context *cctxt)
1341 {
1342     int our_verbose = 0;
1343     symbol *sy;
1344     int i;
1345
1346     if (strstr(s, "v1")) {
1347       our_verbose = 1;
1348     } else if (strstr(s, "v2")) {
1349       our_verbose = 2;
1350     }
1351
1352     printf("[symbols]\n");
1353     sy = setFirstItem(symbols);
1354     i = 0;
1355     for (;;) {
1356       if (sy == NULL)
1357         break;
1358       if (our_verbose <= 1)
1359         printf("<%s>", sy->name);
1360
1361       if (our_verbose > 1) {
1362         printf("  %d) name:%s, size:%d, level:%d block:%d\n", i,
1363           sy->name, sy->size, sy->level, sy->block);
1364         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
1365           sy->isonstack, sy->isfunc, sy->offset, sy->addr);
1366         printf("    eaddr:%d, addr_type:%c, type:%x etype:%x\n",
1367           sy->eaddr, sy->addr_type, sy->type, sy->etype);
1368         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
1369           sy->scopetype, sy->sname, sy->rname, sy->addrspace);
1370         printf("    next:%x\n", sy->next);
1371       }
1372       ++i;
1373       sy = setNextItem(symbols);
1374     }
1375     printf("   %d symbols\n", i);
1376     return 0;
1377 }
1378
1379 /*-----------------------------------------------------------------
1380  cmdListFunctions - list functions.
1381 |-----------------------------------------------------------------*/
1382 int cmdListFunctions (char *s, context *cctxt)
1383 {
1384     function *f;
1385     int i;
1386     int our_verbose = 0;
1387
1388     if (strstr(s, "v1")) {
1389       our_verbose = 1;
1390     } else if (strstr(s, "v2")) {
1391       our_verbose = 2;
1392     }
1393
1394     printf("[functions]\n");
1395     f = setFirstItem(functions);
1396     i = 0;
1397     for (;;) {
1398       if (f == NULL)
1399         break;
1400       if (our_verbose) {
1401         printf("  %d) sym:%x, fname:%s, modName:%s, mod:%x\n", i,
1402           f->sym, f->sym->name, f->modName, f->mod);
1403         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
1404                 f->entryline, f->aentryline, f->exitline, f->aexitline);
1405         printf("    cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n",
1406                 f->cfpoints, f->afpoints, f->laddr, f->lline);
1407       }
1408       else {
1409         printf("<%s>", f->modName);
1410       }
1411       ++i;
1412       f = setNextItem(functions);
1413     }
1414     printf("   %d functions\n", i);
1415     return 0;
1416 }
1417
1418 /*-----------------------------------------------------------------
1419  cmdListModules - list functions.
1420 |-----------------------------------------------------------------*/
1421 int cmdListModules (char *s, context *cctxt)
1422 {
1423     module *m;
1424     srcLine *cs, *as;
1425     int i, mi;
1426     int our_verbose = 0;
1427
1428     if (strstr(s, "v1")) {
1429       our_verbose = 1;
1430     } else if (strstr(s, "v2")) {
1431       our_verbose = 2;
1432     }
1433
1434     printf("[modules]\n");
1435     m = setFirstItem(modules);
1436     mi = 0;
1437     for (;;) {
1438       if (m == NULL)
1439         break;
1440
1441       if (our_verbose >= 0) {
1442       printf("  %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
1443         m->cfullname, m->afullname, m->name);
1444       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
1445               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
1446       printf("    cLines:%x, asmLines:%x\n",
1447               m->cLines, m->asmLines);
1448       }
1449       if (our_verbose >= 2) {
1450         if (m->ncLines) {
1451           printf("    [cLines] ");
1452           if ( our_verbose)
1453           for (i=0; i<m->ncLines; i++ ) {
1454               cs = m->cLines[i];
1455               printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1456                  i, cs->addr, cs->block, cs->level, cs->src);
1457           }
1458           if (!our_verbose)
1459               printf("%d records", i);
1460         }
1461         if (m->nasmLines) {
1462           printf("    [asmLines] ");
1463           if ( our_verbose)
1464           for (i=0; i<m->nasmLines; i++ ) {
1465               as = m->asmLines[i];
1466               printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1467                  i, as->addr, as->block, as->level, as->src);
1468           }
1469           if (!our_verbose)
1470               printf("%d records", i);
1471         }
1472         printf("\n");
1473       }
1474
1475       m = setNextItem(modules);
1476     }
1477     return 0;
1478 }
1479
1480 /*-----------------------------------------------------------------
1481  infoSymbols - This is really just a tool to dump all these
1482    huge program structures out into human readable form.
1483 |-----------------------------------------------------------------*/
1484 static void infoSymbols(context *ctxt)
1485 {
1486   int our_verbose = 0;
1487
1488   printf("[context:%x] func:%x modName:%s addr:%x\n",
1489     ctxt, ctxt->func, ctxt->modName, ctxt->addr);
1490
1491   printf("  cline:%d asmline:%d block:%d level:%d\n",
1492     ctxt->cline, ctxt->asmline, ctxt->level);
1493
1494   printf("[globals] currCtxt:%x, modules:%x, functions:%x symbols:%x\n",
1495     currCtxt, modules, functions, symbols);
1496   printf("  nStructs:%d, structs:%x, ssdirl:%s\n",
1497     nStructs, structs, ssdirl);
1498
1499   /**************** modules *******************/
1500   {
1501     module *m;
1502     srcLine *cs, *as;
1503     int i, mi;
1504     printf("[modules]\n");
1505     m = setFirstItem(modules);
1506     mi = 0;
1507     for (;;) {
1508       if (m == NULL)
1509         break;
1510       printf("  %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
1511         m->cfullname, m->afullname, m->name);
1512       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
1513               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
1514       printf("    cLines:%x, asmLines:%x\n",
1515               m->cLines, m->asmLines);
1516       i = 0;
1517       if (m->cLines) {
1518         cs = m->cLines[i++];
1519         printf("    [cLines] ");
1520         while (cs) {
1521           if (our_verbose)
1522             printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1523                i, cs->addr, cs->block, cs->level, cs->src);
1524           cs = m->cLines[i++];
1525         }
1526         if (!our_verbose)
1527             printf("%d records", i);
1528       }
1529       i = 0;
1530       if (m->asmLines) {
1531         as = m->asmLines[i++];
1532         printf("    [asmLines] ");
1533         while (as) {
1534           if (our_verbose)
1535             printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1536                i, as->addr, as->block, as->level, as->src);
1537           as = m->asmLines[i++];
1538         }
1539         if (!our_verbose)
1540             printf("%d records", i);
1541       }
1542       printf("\n");
1543
1544       m = setNextItem(modules);
1545     }
1546   }
1547
1548   /**************** functions *******************/
1549   {
1550     function *f;
1551     int i;
1552     printf("[functions]\n");
1553     f = setFirstItem(functions);
1554     i = 0;
1555     for (;;) {
1556       if (f == NULL)
1557         break;
1558       if (our_verbose) {
1559         printf("  %d) sym:%x, modName:%s, mod:%x\n", i,
1560           f->sym, f->modName, f->mod);
1561         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
1562                 f->entryline, f->aentryline, f->exitline, f->aexitline);
1563         printf("    cfpoints:%x, afpoints:%x, laddr:%x, lline:%d\n",
1564                 f->cfpoints, f->afpoints, f->laddr, f->lline);
1565       }
1566       ++i;
1567       f = setNextItem(functions);
1568     }
1569     if (!our_verbose)
1570       printf("   %d functions\n", i);
1571   }
1572
1573   /**************** symbols *******************/
1574   {
1575     symbol *s;
1576     int i;
1577     printf("[symbols]\n");
1578     s = setFirstItem(symbols);
1579     i = 0;
1580     for (;;) {
1581       if (s == NULL)
1582         break;
1583       if (our_verbose) {
1584         printf("  %d) name:%s, size:%d, level:%d block:%d\n", i,
1585           s->name, s->size, s->level, s->block);
1586         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
1587           s->isonstack, s->isfunc, s->offset, s->addr);
1588         printf("    eaddr:%d, addr_type:%c, type:%x etype:%x\n",
1589           s->eaddr, s->addr_type, s->type, s->etype);
1590         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
1591           s->scopetype, s->sname, s->rname, s->addrspace);
1592         printf("    next:%x\n", s->next);
1593       }
1594       ++i;
1595       s = setNextItem(symbols);
1596     }
1597     if (!our_verbose)
1598       printf("   %d symbols\n", i);
1599   }
1600
1601 }
1602
1603 /*-----------------------------------------------------------------*/
1604 /* infoStack - print call stack information                        */
1605 /*-----------------------------------------------------------------*/
1606 static void infoStack(context *ctxt)
1607 {
1608     function *func ;
1609     int i = 0 ;
1610
1611     STACK_STARTWALK(callStack) ;
1612     while ((func = STACK_WALK(callStack))) {
1613
1614         fprintf(stdout,"#%d 0x%04x %s () at %s:%d\n",i++,
1615                 func->laddr,func->sym->name,
1616                 func->mod->c_name,func->lline);
1617     }
1618
1619 }
1620
1621 /*-----------------------------------------------------------------*/
1622 /* cmdWhere -  where command                                       */
1623 /*-----------------------------------------------------------------*/
1624 int cmdWhere(char *s, context *cctxt)
1625 {
1626         infoStack(cctxt);
1627     showfull = 1;
1628         return 0;
1629 }
1630
1631 /*-----------------------------------------------------------------*/
1632 /* cmdUp -  Up command                                             */
1633 /*-----------------------------------------------------------------*/
1634 int cmdUp(char *s, context *cctxt)
1635 {
1636         return 0;
1637 }
1638
1639 /*-----------------------------------------------------------------*/
1640 /* cmdDown - down command                                          */
1641 /*-----------------------------------------------------------------*/
1642 int cmdDown(char *s, context *cctxt)
1643 {
1644         return 0;
1645 }
1646
1647 static int infomode = 0;
1648 /*-----------------------------------------------------------------*/
1649 /* cmdInfo - info command                                          */
1650 /*-----------------------------------------------------------------*/
1651 int cmdInfo (char *s, context *cctxt)
1652 {
1653     while (isspace(*s)) s++;
1654
1655     /* list all break points */
1656     if (strncmp(s,"break",5) == 0) {
1657         listUSERbp();
1658         return 0;
1659     }
1660
1661     /* info frame same as frame */
1662     if (strcmp(s,"frame") == 0) {
1663         cmdFrame (s,cctxt);
1664     showfull = 1;
1665         return 0;
1666     }
1667
1668     if (strncmp(s,"line",4) == 0) {
1669     infomode=1;
1670         cmdListSrc (s+4,cctxt);
1671         return 0;
1672     }
1673
1674     /* info stack display call stack */
1675     if (strcmp(s,"stack") == 0) {
1676         infoStack(cctxt);
1677     showfull = 1;
1678         return 0;
1679     }
1680
1681     /* info stack display call stack */
1682     if (strcmp(s,"registers") == 0) {
1683         fprintf(stdout,"%s",simRegs());
1684         return 0;
1685     }
1686
1687     /* info stack display call stack */
1688     if (strcmp(s,"all-registers") == 0) {
1689         fprintf(stdout,"%s",simRegs());
1690         fprintf(stdout,"Special Function Registers:\n");
1691     sendSim("ds 0x80 0x100\n");
1692     waitForSim(100,NULL);
1693     fprintf(stdout,simResponse());
1694         return 0;
1695     }
1696
1697     /* info stack display call stack */
1698     if (strcmp(s,"symbols") == 0) {
1699       /* dump out symbols we have read in */
1700       fprintf(stdout,"Dumping symbols...\n");
1701       infoSymbols(cctxt);
1702       return 0;
1703     }
1704
1705     if (strcmp(s,"variables") == 0) {
1706       /* dump out symbols we have read in */
1707       fprintf(stdout,"Dumping symbols...\n");
1708       infoSymbols(cctxt);
1709       return 0;
1710     }
1711
1712     fprintf(stdout,"Undefined info command: \"%s\".  Try \"help\n",s);
1713     return 0;
1714
1715 }
1716
1717 /*-----------------------------------------------------------------*/
1718 /* cmdQuit  - quit debugging                                       */
1719 /*-----------------------------------------------------------------*/
1720 int cmdQuit (char *s, context *cctxt)
1721 {   
1722     if (simactive)
1723         closeSimulator();
1724     return 1;
1725 }
1726
1727 /*-----------------------------------------------------------------*/
1728 /* cmdListSrc  - list src                                          */
1729 /*-----------------------------------------------------------------*/
1730 int cmdListSrc (char *s, context *cctxt)
1731 {   
1732     static int currline = 0;
1733     int i =0 ;
1734     int pline = 0;
1735     int llines = listLines;
1736
1737     while (*s && isspace(*s)) s++;
1738     
1739     /* if the user has spcified line numer then the line number
1740        can be of the following formats
1741        LINE          - just line number
1742        FILE:LINE     - filename line number
1743        FUNCTION      - list a function
1744        FILE:FUNCTION - function in file */
1745
1746     if (*s) {
1747         /* case a) LINE */
1748         if (isdigit(*s)) {
1749             sscanf(s,"%d",&pline);
1750             if (!cctxt || !cctxt->func || !cctxt->func->mod) {
1751               if (!list_mod) {
1752                 fprintf(stdout,"Sdcdb fails to have a proper context at %d.\n", __LINE__);
1753                 return 0;
1754               }
1755             }
1756             else
1757               list_mod = cctxt->func->mod;
1758         }
1759         else {
1760             char *bp;
1761             function *func = NULL;
1762             
1763             /* if ':' present then FILE:LINE || FILE:FUNCTION */
1764             if ((bp = strchr(s,':'))) {
1765                 *bp = '\0';
1766                 bp ++;
1767                 if (isdigit(*bp)) {
1768                     /* FILE:LINE */
1769                     list_mod=NULL;  /* bug fix 2-09-02, moduleWithCName expects mod to be null */
1770                     if (srcMode == SRC_CMODE) {
1771                         if (!applyToSet(modules,moduleWithCName,s,&list_mod)) {
1772                             fprintf (stderr,"No c source file named %s.\n",s);
1773                             return 0;
1774                         }
1775                     } else {
1776                         if (!applyToSet(modules,moduleWithAsmName,s,&list_mod)) {
1777                             fprintf (stderr,"No source file named %s.\n",s);
1778                             return 0;
1779                         }
1780                     }
1781                     sscanf(bp,"%d",&pline);
1782                 } else {
1783                     /* FILE:FUCTION */
1784                     if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) {
1785                         fprintf(stdout,"Function \"%s\" not defined.\n",bp);
1786                         return 0;
1787                     }
1788                     list_mod = func->mod;
1789                     if (srcMode == SRC_CMODE) {
1790                         pline = func->entryline;
1791                         llines = func->exitline - func->entryline + 1;
1792                     } else {
1793                         pline = func->aentryline;
1794                         llines = func->aexitline - func->aentryline + 1;
1795                     }
1796                 }
1797             }
1798             else {
1799                 /* FUNCTION */
1800                 if (!applyToSet(functions,funcWithName,s,&func)) {
1801                     fprintf(stderr,"Function \"%s\" not defined.\n",s); 
1802                     return 0;
1803                 }
1804                 else {
1805                     list_mod = func->mod;
1806                     if (srcMode == SRC_CMODE) {
1807                         pline = func->entryline;
1808                         llines = func->exitline - func->entryline + 1; 
1809                     } else {
1810                         pline = func->aentryline;
1811                         llines = func->aexitline - func->aentryline + 1; 
1812                     }
1813                 }
1814             }
1815         }
1816     } else {
1817         /* if no line specified & we had listed
1818            before then continue from that listing */
1819         if (currline)
1820             pline = currline ;
1821         else {
1822             if (!cctxt || !cctxt->func || !cctxt->func->mod) {
1823               fprintf(stdout,"Missing context at %d. Try list filename:lineno\n", __LINE__);
1824               return 0;
1825             }
1826             list_mod = cctxt->func->mod;
1827             if (srcMode == SRC_CMODE)
1828                 pline = cctxt->cline;
1829             else
1830                 pline = cctxt->asmline;
1831         }
1832     }
1833
1834     if (!list_mod) {
1835       fprintf(stdout,"Sdcdb fails to have a valid module context at %d.\n", __LINE__);
1836       return 0;
1837     }
1838     
1839     if (llines > listLines) llines = listLines;
1840
1841     if ( infomode )
1842     {
1843             fprintf(stdout,"Line %d of \"%s\" starts at address 0x%08x.\n",pline,
1844                     list_mod->c_name, list_mod->cLines[pline]->addr);
1845         infomode=0;
1846         return 0;
1847     }
1848     for ( i = 0 ; i < llines ; i++ ) {
1849         if (srcMode == SRC_CMODE) {
1850             if ( (pline + i) >= list_mod->ncLines )
1851                 break;
1852             fprintf(stdout,"%d\t%s",pline + i,
1853                     list_mod->cLines[pline +i]->src);
1854         } else {
1855             if ( (pline + i) >= list_mod->nasmLines )
1856                 break;
1857             fprintf(stdout,"%d\t%s",pline + i,
1858                     list_mod->asmLines[pline +i]->src);
1859         }
1860     }
1861     currline = pline + i ;
1862     return 0;
1863 }
1864
1865 static void setValBasic(symbol *sym, char *val)
1866 {
1867     union 
1868     {   
1869         float f;     
1870         unsigned long val;
1871         long         sval;
1872         struct {
1873             short    lo;
1874             short    hi;
1875         } i;
1876         unsigned char b[4];
1877     }v;
1878
1879     if (IS_FLOAT(sym->type))    
1880         v.f = strtof(val,NULL);    
1881     else
1882         if (IS_PTR(sym->type))
1883             v.sval = strtol(val,NULL,0);
1884         else
1885     {
1886             if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) 
1887         {
1888             if (IS_CHAR(sym->etype))
1889             { 
1890                 v.b[0] = val[0];
1891             }
1892             else
1893                 if (IS_INT(sym->etype)) 
1894                     if (IS_LONG(sym->etype))
1895                         if (SPEC_USIGN(sym->etype))
1896                             v.val = strtol(val,NULL,0);
1897                         else
1898                             v.sval = strtol(val,NULL,0);
1899                     else
1900                         v.i.lo = strtol(val,NULL,0);
1901                 else
1902                     v.sval = strtol(val,NULL,0);
1903             } 
1904         else
1905             v.sval = strtol(val,NULL,0);
1906     }
1907     simSetValue(sym->addr,sym->addrspace,sym->size,v.sval);     
1908 }
1909
1910 /*-----------------------------------------------------------------*/
1911 /* printValBasic - print value of basic types                      */
1912 /*-----------------------------------------------------------------*/
1913 static void printValBasic(symbol *sym,unsigned addr,char mem, int size)
1914 {
1915     union {     
1916         float f;     
1917         unsigned long val;
1918         long         sval;
1919         struct {
1920             short    lo;
1921             short    hi;
1922         } i;
1923         unsigned char b[4];
1924     }v;
1925     union {
1926         unsigned char b[4];
1927     }v1;
1928     
1929     v.val = simGetValue(addr,mem,size);
1930     /* if this a floating point number then */
1931     if (IS_FLOAT(sym->type))    
1932         fprintf(stdout,"%f",v.f);    
1933     else
1934         if (IS_PTR(sym->type))
1935             fprintf(stdout,"0x%x",v.val);
1936         else
1937             if (IS_SPEC(sym->type) && IS_INTEGRAL(sym->type)) {
1938                 if (IS_CHAR(sym->etype))
1939         { 
1940                     if ( isprint(v.val))
1941                 fprintf(stdout,"%d 0x%x '%c'",v.val,v.val,v.val);
1942             else
1943                 fprintf(stdout,"%d 0x%x '\\%o'",v.val,v.val,v.val);
1944                 }
1945         else
1946                     if (IS_INT(sym->etype)) 
1947                         if (IS_LONG(sym->etype))
1948                             if (SPEC_USIGN(sym->etype))
1949                                 fprintf(stdout,"%d 0x%x",v.val,v.val);
1950                             else
1951                                 fprintf(stdout,"%d 0x%x",v.sval,v.sval);
1952                         else
1953                             fprintf(stdout,"%d 0x%x",v.i.lo,v.i.lo);
1954                     else
1955                         fprintf(stdout,"0x%x",v.val);
1956             } else
1957                 fprintf(stdout,"0x%x",v.val);
1958                 
1959     
1960 }
1961
1962 /*-----------------------------------------------------------------*/
1963 /* printValFunc  - prints function values                          */
1964 /*-----------------------------------------------------------------*/
1965 static void printValFunc (symbol *sym)
1966 {
1967     fprintf(stdout,"print function not yet implemented");
1968 }
1969
1970 /*-----------------------------------------------------------------*/
1971 /* printArrayValue - will print the values of array elements       */
1972 /*-----------------------------------------------------------------*/
1973 static void printArrayValue (symbol *sym, char space, unsigned int addr)
1974 {
1975         link *elem_type = sym->type->next;
1976         int i;
1977         
1978         fprintf(stdout," { ");
1979         for (i = 0 ; i < DCL_ELEM(sym->type) ; i++) {           
1980                 if (IS_AGGREGATE(elem_type)) {
1981                         printValAggregates(sym,elem_type,space,addr);                  
1982                 } else {
1983                         printValBasic(sym,addr,space,getSize(elem_type));
1984                 }
1985                 addr += getSize(elem_type);
1986                 if (i != DCL_ELEM(sym->type) -1)
1987                         fprintf(stdout,",");
1988         }
1989
1990         fprintf(stdout,"}");            
1991 }
1992
1993 /*-----------------------------------------------------------------*/
1994 /* printStructValue - prints structures elements                   */
1995 /*-----------------------------------------------------------------*/
1996 static void printStructValue (symbol *sym,link *type, char space, unsigned int addr) 
1997 {
1998         symbol *fields = SPEC_STRUCT(type)->fields;
1999
2000         fprintf(stdout," { ");
2001         while (fields) {
2002                 fprintf(stdout,"%s = ",fields->name);
2003                 if (IS_AGGREGATE(fields->type)) {
2004                         printValAggregates(fields,fields->type,space, addr);
2005                 } else {
2006                         printValBasic(fields,addr,space,getSize(fields->type));
2007                 }
2008                 addr += getSize(fields->type);
2009                 fields = fields->next;
2010         }
2011         fprintf(stdout,"}");
2012 }
2013
2014 /*-----------------------------------------------------------------*/
2015 /* printValAggregates - print value of aggregates                  */
2016 /*-----------------------------------------------------------------*/
2017 static void printValAggregates (symbol *sym, link *type,char space,unsigned int addr)
2018 {
2019
2020         if (IS_ARRAY(type)) {
2021                 printArrayValue(sym, space, addr);
2022                 return ;
2023         }
2024
2025         if (IS_STRUCT(type)) { 
2026                 printStructValue(sym,sym->type,space, addr); 
2027                 return; 
2028         } 
2029 }
2030
2031 /*-----------------------------------------------------------------*/
2032 /* setSymValue - set     value of a symbol                         */
2033 /*-----------------------------------------------------------------*/
2034 static void setSymValue(symbol *sym, char *val, context *cctxt)
2035 {
2036     if (sym->isonstack) 
2037     {
2038         symbol *bp = symLookup("bp",cctxt);
2039         if (!bp) 
2040         {
2041             fprintf(stdout,"cannot determine stack frame\n");
2042             return ;
2043         }
2044
2045         sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
2046             + sym->offset ;      
2047     }
2048     /* arrays & structures first */
2049     if (IS_AGGREGATE(sym->type))
2050         {
2051     }
2052     else
2053         /* functions */
2054         if (IS_FUNC(sym->type))
2055     {
2056     }
2057         else
2058     {
2059         setValBasic(sym,val);
2060     }
2061 }
2062
2063 /*-----------------------------------------------------------------*/
2064 /* printSymValue - print value of a symbol                         */
2065 /*-----------------------------------------------------------------*/
2066 static void printSymValue (symbol *sym, context *cctxt, int flg, int dnum)
2067 {
2068     static int stack = 1;
2069     unsigned long val;
2070     /* if it is on stack then compute address & fall thru */
2071     if (sym->isonstack) {
2072         symbol *bp = symLookup("bp",cctxt);
2073         if (!bp) {
2074             fprintf(stdout,"cannot determine stack frame\n");
2075             return ;
2076         }
2077
2078         sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
2079           + sym->offset ;      
2080     }
2081     
2082     /* get the value from the simulator and
2083        print it */
2084     switch (flg)
2085     {
2086         case 0: 
2087         default:
2088             break;
2089         case 1: 
2090             fprintf(stdout,"$%d = ",stack++);
2091             break;
2092         case 2: 
2093             fprintf(stdout,"%d: %s = ",dnum,sym->name);
2094             break;
2095     }
2096     /* arrays & structures first */
2097     if (IS_AGGREGATE(sym->type))
2098         printValAggregates(sym,sym->type,sym->addrspace,sym->addr);
2099     else
2100         /* functions */
2101         if (IS_FUNC(sym->type))
2102             printValFunc(sym);
2103         else 
2104             printValBasic(sym,sym->addr,sym->addrspace,sym->size);
2105     if ( flg > 0 ) fprintf(stdout,"\n");
2106             //fprintf(stdout,"(BASIC %x,%c,%d)\n",sym->addr,sym->addrspace,sym->size);
2107         
2108 }
2109
2110 /*-----------------------------------------------------------------*/
2111 /* printStructInfo - print out structure information               */
2112 /*-----------------------------------------------------------------*/
2113 static void printStructInfo (structdef *sdef)
2114 {
2115     symbol *field = sdef->fields ;
2116     int i = 0 ;
2117     
2118     while (field) {
2119         i += field->offset;
2120         field = field->next;
2121     }
2122
2123     fprintf(stdout,"%s %s {\n",(i ? "struct" : "union" ), sdef->tag);
2124     field = sdef->fields;
2125     while (field) {
2126         printTypeInfo (field->type);
2127         fprintf(stdout," %s ;\n",field->name);
2128         field = field->next ;
2129     }
2130
2131     fprintf(stdout,"}\n");
2132
2133 }
2134
2135 /*-----------------------------------------------------------------*/
2136 /* printTypeInfo - print out the type information                  */
2137 /*-----------------------------------------------------------------*/
2138 static void printTypeInfo(link *p)
2139 {
2140     if (!p)
2141         return ;
2142
2143     if (IS_DECL(p)) {
2144         switch (DCL_TYPE(p))  {
2145         case FUNCTION:
2146             printTypeInfo (p->next);
2147             fprintf(stdout,"()");
2148             break;
2149         case ARRAY:
2150             printTypeInfo (p->next);
2151             fprintf(stdout,"[%d]",DCL_ELEM(p));
2152             break;
2153         
2154         case IPOINTER:
2155         case PPOINTER:
2156         case POINTER:
2157             printTypeInfo (p->next);
2158             fprintf(stdout,"(_near *)");
2159             break;
2160
2161         case FPOINTER:
2162             printTypeInfo (p->next);
2163             fprintf(stdout,"(_xdata *)");
2164             break;
2165
2166         case CPOINTER:
2167             printTypeInfo( p->next);
2168             fprintf(stdout,"(_code *)");
2169             break;
2170             
2171         case GPOINTER:
2172             printTypeInfo( p->next);
2173             fprintf(stdout,"(_generic *)");
2174             break;                   
2175         }
2176     } else {
2177         switch (SPEC_NOUN(p)) { /* depending on the specifier type */
2178         case V_INT:
2179             (IS_LONG(p) ? fputs("long ",stdout) : 
2180              ( IS_SHORT(p) ? fputs("short ",stdout) : 
2181                fputs("int ",stdout))) ;
2182             break;
2183         case V_FLOAT:
2184              fputs("float ",stdout);
2185              break;
2186
2187         case V_CHAR:
2188             fputs ("char ",stdout);
2189             break;
2190
2191         case V_VOID:
2192             fputs("void ",stdout);
2193             break;
2194
2195         case V_STRUCT:
2196             printStructInfo (SPEC_STRUCT(p));
2197             break;
2198
2199         case V_SBIT:
2200             fputs("sbit ",stdout);
2201             break;
2202
2203         case V_BIT:
2204             fprintf(stdout,": %d" ,SPEC_BLEN(p));       
2205             break;
2206         }
2207     }
2208 }
2209
2210 /*-----------------------------------------------------------------*/
2211 /* cmdPrint - print value of variable                              */
2212 /*-----------------------------------------------------------------*/
2213 int cmdPrint (char *s, context *cctxt)
2214 {   
2215     symbol *sym ;
2216     char *bp = s+strlen(s) -1;
2217
2218     while (isspace(*s)) s++;
2219     if (!*s) return 0;
2220     while (isspace(*bp)) bp--;
2221     bp++ ;
2222     *bp = '\0';
2223
2224     if ((sym = symLookup(s,cctxt))) {
2225         printSymValue(sym,cctxt,1,0);
2226     } else {
2227         fprintf(stdout,
2228                 "No symbol \"%s\" in current context.\n",              
2229                 s);
2230     }
2231     return 0;
2232 }
2233
2234 /*-----------------------------------------------------------------*/
2235 /* cmdOutput - print value of variable without number and newline  */
2236 /*-----------------------------------------------------------------*/
2237 int cmdOutput (char *s, context *cctxt)
2238 {   
2239     symbol *sym ;
2240     char *bp = s+strlen(s) -1;
2241
2242     while (isspace(*s)) s++;
2243     if (!*s) return 0;
2244     while (isspace(*bp)) bp--;
2245     bp++ ;
2246     *bp = '\0';
2247
2248     if ((sym = symLookup(s,cctxt))) {
2249         printSymValue(sym,cctxt,0,0);
2250     } else {
2251         fprintf(stdout,
2252                 "No symbol \"%s\" in current context.",        
2253                 s);
2254     }
2255     return 0;
2256 }
2257
2258 typedef struct _dsymbol
2259 {
2260     char *name;
2261     int  dnum;
2262 } dsymbol;
2263
2264 /** find display entry with this number */
2265
2266 DEFSETFUNC(dsymWithNumber)
2267 {
2268     dsymbol *dsym = item;
2269     V_ARG(int , dnum);
2270     V_ARG(dsymbol **,dsymp);
2271
2272     if ( dsym->dnum == dnum )
2273     {
2274         *dsymp = dsym;
2275         return 1;
2276     }
2277     return 0;
2278 }
2279
2280 /*-----------------------------------------------------------------*/
2281 /* displayAll  - display all valid variables                       */
2282 /*-----------------------------------------------------------------*/
2283 void displayAll(context *cctxt)
2284 {
2285     dsymbol *dsym;
2286     symbol  *sym;
2287     if ( !dispsymbols )
2288         return;
2289     for (dsym = setFirstItem(dispsymbols);
2290          dsym ;
2291          dsym = setNextItem(dispsymbols)) 
2292     {
2293         if ( (sym = symLookup(dsym->name,cctxt)))
2294             printSymValue(sym,cctxt,2,dsym->dnum);            
2295     }
2296 }
2297
2298 /*-----------------------------------------------------------------*/
2299 /* cmdDisplay  - display value of variable                         */
2300 /*-----------------------------------------------------------------*/
2301 int cmdDisplay (char *s, context *cctxt)
2302 {   
2303     symbol *sym ;
2304     char *bp = s+strlen(s) -1;
2305     static int dnum = 1;
2306
2307     while (isspace(*s)) s++;
2308     if (!*s)
2309     {
2310         displayAll(cctxt);
2311         return 0;
2312     }
2313     while (isspace(*bp)) bp--;
2314     bp++ ;
2315     *bp = '\0';
2316
2317     if ((sym = symLookup(s,cctxt))) 
2318     {
2319         dsymbol *dsym = (dsymbol *)Safe_calloc(1,sizeof(dsymbol));
2320         dsym->dnum = dnum++ ;
2321         dsym->name = sym->name;
2322         addSetHead(&dispsymbols,dsym);
2323     }
2324     else
2325     {
2326         fprintf(stdout,"No symbol \"%s\" in current context.\n",               
2327                 s);
2328     }
2329     return 0;
2330 }
2331
2332 /*-----------------------------------------------------------------*/
2333 /* cmdUnDisplay  - undisplay value of variable                              */
2334 /*-----------------------------------------------------------------*/
2335 int cmdUnDisplay (char *s, context *cctxt)
2336 {   
2337     dsymbol *dsym;
2338     int dnum;
2339
2340     while (isspace(*s)) s++;
2341     if (!*s)
2342     {
2343         deleteSet(&dispsymbols);
2344         return 0;
2345     }
2346     while ( s && *s )
2347     {
2348         dnum = strtol(s,&s,10);
2349         if (applyToSetFTrue(dispsymbols,dsymWithNumber,dnum,&dsym)) 
2350         {
2351             deleteSetItem(&dispsymbols,dsym);
2352         } 
2353         else
2354         {
2355             fprintf(stdout,"Arguments must be display numbers.\n");    
2356         }
2357     }
2358     return 0;
2359 }
2360
2361 /*-----------------------------------------------------------------*/
2362 /* cmdPrintType - print type of a variable                         */
2363 /*-----------------------------------------------------------------*/
2364 int cmdPrintType (char *s, context *cctxt)
2365 {   
2366         symbol *sym ;
2367     char *bp = s+strlen(s) -1;
2368
2369     while (isspace(*s)) s++;
2370     if (!*s) return 0;
2371     while (isspace(*bp)) bp--;
2372     bp++ ;
2373     *bp = '\0';
2374
2375     if ((sym = symLookup(s,cctxt))) {
2376         printTypeInfo(sym->type);
2377         fprintf(stdout,"\n");
2378     } else {
2379         fprintf(stdout,
2380                 "No symbol \"%s\" in current context.\n",
2381                 s);
2382     }
2383     return 0;   
2384 }
2385
2386 /*-----------------------------------------------------------------*/
2387 /* cmdClrUserBp - clear user break point                           */
2388 /*-----------------------------------------------------------------*/
2389 int cmdClrUserBp (char *s, context *cctxt)
2390 {   
2391     char *bp ;    
2392     function *func = NULL;
2393         
2394     /* clear break point location specification can be of the following
2395        forms
2396        a) <nothing>        - break point at current location
2397        b) lineno           - number of the current module
2398        c) filename:lineno  - line number of the given file
2399        e) filename:function- function X in file Y (useful for static functions)
2400        f) function         - function entry point
2401     */
2402
2403     if (!cctxt) {
2404         fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
2405         return 0;
2406     }
2407
2408     /* white space skip */
2409     while (*s && isspace(*s)) s++;
2410     
2411     /* null terminate it after stripping trailing blanks*/
2412     bp = s + strlen(s);
2413     while (bp != s && isspace(*bp)) bp--;
2414     *bp = '\0';
2415
2416     /* case a) nothing */
2417     /* if nothing given then current location : we know
2418        the current execution location from the currentContext */
2419     if (! *s ) {
2420
2421         /* if current context is known */
2422         if (cctxt->func) 
2423             /* clear the break point @ current location */
2424             clearUSERbp (cctxt->addr);
2425         else
2426             fprintf(stderr,"No default breakpoint address now.\n");
2427                         
2428         goto ret ;
2429     }
2430
2431     /* case b) lineno */
2432     /* check if line number */
2433     if (isdigit(*s)) {
2434         /* get the lineno */
2435         int line = atoi(s);
2436
2437         /* if current context not present then we must get the module
2438            which has main & set the break point @ line number provided
2439            of that module : if current context known then set the bp 
2440            at the line number given for the current module 
2441         */
2442         if (cctxt->func) {
2443             if (!cctxt->func->mod) {
2444                 if (!applyToSet(functions,funcWithName,"main"))
2445                     fprintf(stderr,"Function \"main\" not defined.\n");
2446                 else 
2447                     clearBPatModLine(func->mod,line);
2448             } else 
2449                 clearBPatModLine(cctxt->func->mod,line);                        
2450         }
2451         
2452         goto ret;
2453     }
2454
2455     if ((bp = strchr(s,':'))) {
2456         
2457         module *mod = NULL;
2458         *bp = '\0';
2459         
2460         if (!applyToSet(modules,moduleWithCName,s,&mod)) {
2461             fprintf (stderr,"No source file named %s.\n",s);
2462             goto ret;
2463         }
2464
2465         /* case c) filename:lineno */
2466         if (isdigit(*(bp +1))) {                    
2467          
2468             clearBPatModLine (mod,atoi(bp+1));      
2469             goto ret;
2470             
2471         }
2472         /* case d) filename:function */
2473         if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func)) 
2474             fprintf(stderr,"Function \"%s\" not defined.\n",bp+1); 
2475         else
2476             clearBPatModLine (mod,func->entryline);
2477         
2478         goto ret;
2479     }
2480             
2481     /* case e) function */
2482     if (!applyToSet(functions,funcWithName,s,&func))
2483         fprintf(stderr,"Function \"%s\" not defined.\n",s); 
2484     else
2485         clearBPatModLine(func->mod,func->entryline);
2486
2487  ret:    
2488     return 0;        
2489 }
2490
2491
2492 /*-----------------------------------------------------------------*/
2493 /* cmdSimulator - send command to simulator                        */
2494 /*-----------------------------------------------------------------*/
2495 int cmdSimulator (char *s, context *cctxt)
2496 {   
2497   char tmpstr[82];
2498
2499     if (strlen(s) > 80) {
2500       printf("error 3A\n");
2501       exit(1);
2502     }
2503     strcpy(tmpstr, s);
2504     strcat(tmpstr, "\n");
2505     sendSim(tmpstr);
2506     waitForSim(200,NULL);
2507     fprintf(stdout,"%s",simResponse());
2508     return 0;
2509 }
2510
2511 /*-----------------------------------------------------------------*/
2512 /* cmdFrame - Frame command                                        */
2513 /*-----------------------------------------------------------------*/
2514 int cmdFrame (char *s, context *cctxt)
2515 {   
2516     function *func ;
2517
2518     if ((func = STACK_PEEK(callStack))) {
2519         fprintf(stdout,"#0  %s () at %s:%d\n",
2520                 func->sym->name,func->mod->c_name,cctxt->cline);
2521
2522         if (cctxt->cline < func->mod->ncLines)      
2523             fprintf(stdout,"%d\t%s",
2524                     cctxt->cline,
2525                     func->mod->cLines[cctxt->cline]->src);
2526     } else
2527         fprintf(stdout,"No stack.\n");
2528     return 0;
2529 }
2530
2531 /*-----------------------------------------------------------------*/
2532 /* cmdFinish - exec till end of current function                   */
2533 /*-----------------------------------------------------------------*/
2534 int cmdFinish (char *s, context *ctxt)
2535 {
2536     if (!ctxt || ! ctxt->func) {
2537         fprintf(stdout,"The program is not running.\n");
2538         return 0;
2539     }
2540
2541     if (srcMode == SRC_CMODE) {
2542         setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, 
2543                        stepBpCB, ctxt->func->mod->c_name, 
2544                        ctxt->func->exitline);
2545     } else {
2546         setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP, 
2547                        stepBpCB, ctxt->func->mod->asm_name, 
2548                        ctxt->func->aexitline);
2549     }
2550
2551     simGo(-1);
2552     return 0;
2553     
2554 }
2555
2556
2557 /*-----------------------------------------------------------------*/
2558 /* cmdShow - show command                                          */
2559 /*-----------------------------------------------------------------*/
2560 int cmdShow (char *s, context *cctxt)
2561 {
2562     /* skip white space */
2563     while (*s && isspace(*s)) s++ ;
2564
2565     if (strcmp(s,"copying") == 0) {
2566         fputs(copying,stdout);
2567         return 0;
2568     }
2569     
2570     if (strcmp(s,"warranty") == 0) {
2571         fputs(warranty,stdout);
2572         return 0;
2573     }
2574
2575     return 0;
2576 }
2577