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