79dba8d30df0ccf2437d8fbbb99eef2af4f10e9f
[fw/sdcc] / debugger / mcs51 / cmd.c
1 /*-------------------------------------------------------------------------
2     cmd.c - source  file for debugger command execution
3         Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
4
5    This program is free software; you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by the
7    Free Software Foundation; either version 2, or (at your option) any
8    later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19    In other words, you are welcome to use, share and improve this program.
20    You are forbidden to forbid anyone else to use, share and improve
21    what you give them.   Help stamp out software-hoarding!
22 -------------------------------------------------------------------------*/
23
24 #include "sdcdb.h"
25 #include "symtab.h"
26 #include "simi.h"
27 #include "break.h"
28 #include "cmd.h"
29 #include "newalloc.h"
30
31 /* default number of lines to list out */
32 #define LISTLINES 10
33 static int listlines = LISTLINES;
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,int,int);
332 static  int printOrSetSymValue (symbol *sym, context *cctxt,
333                                 int flg, int dnum, int fmt,
334                                 char *rs, char *val, char cmp);
335
336 int srcMode = SRC_CMODE ;
337 set *dispsymbols = NULL   ; /* set of displayable symbols */
338 static int currentFrame = 0;        /* actual displayed frame     */
339 /*-----------------------------------------------------------------*/
340 /* funcWithName - returns function with name                       */
341 /*-----------------------------------------------------------------*/
342 DEFSETFUNC(funcWithName)
343 {
344     function *func = item;
345     V_ARG(char *,name);
346     V_ARG(function **,funcp);
347
348     if (*funcp)
349         return 0;
350
351     if (strcmp(func->sym->name,name) == 0) {
352         *funcp = func;
353         return 1;
354     }
355
356     return 0;
357 }
358
359 /*-----------------------------------------------------------------*/
360 /* symWithAddr - look for symbol with sfr / sbit address           */
361 /*-----------------------------------------------------------------*/
362 DEFSETFUNC(symWithAddr)
363 {
364     symbol *sym = item;
365     V_ARG(unsigned long,laddr);
366     V_ARG(int    ,laddrspace);
367     V_ARG(symbol **,rsym);
368
369     if (*rsym)
370         return 0;
371
372     if ( sym->addr == laddr &&
373          sym->addrspace == laddrspace )
374     {
375         *rsym = sym;
376         return 1;
377     }
378
379     return 0;
380 }
381
382 /*-----------------------------------------------------------------*/
383 /* setBPatModLine - set break point at the line specified for the  */
384 /*-----------------------------------------------------------------*/
385 static void setBPatModLine (module *mod, int line, char bpType )
386 {
387     int next_line;
388
389     /* look for the first executable line after the line
390        specified & get the break point there */
391
392     if ( line < 0 )
393         return;
394
395     if (srcMode == SRC_CMODE && line > mod->ncLines) {
396         fprintf(stderr,"No line %d in file \"%s\".\n",
397                 line,mod->c_name);
398         return ;
399     }
400
401     if (srcMode == SRC_AMODE && line > mod->nasmLines) {
402         fprintf(stderr,"No line %d in file \"%s\".\n",
403                 line,mod->asm_name);
404         return ;
405     }
406
407     next_line = line;
408     for ( ; next_line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ;
409           next_line++ ) {
410         if (srcMode == SRC_CMODE) {
411             if (mod->cLines[next_line]->addr != INT_MAX) {
412                 setBreakPoint (mod->cLines[next_line]->addr, CODE, bpType,
413                                userBpCB, mod->c_name, next_line);
414                 return;
415 //              break;
416             }
417         }
418         else {
419            if (mod->asmLines[next_line]->addr != INT_MAX) {
420                setBreakPoint (mod->asmLines[next_line]->addr, CODE, bpType,
421                               userBpCB, mod->asm_name, next_line);
422                 return;
423 //             break;
424            }
425         }
426     }
427
428         fprintf(stderr,"No line %d or after in file \"%s\"..\n",
429                         line,mod->c_name);
430
431     return;
432 }
433
434 /*-----------------------------------------------------------------*/
435 /* clearBPatModLine - clr break point at the line specified        */
436 /*-----------------------------------------------------------------*/
437 static void clearBPatModLine (module *mod, int line)
438 {
439     /* look for the first executable line after the line
440        specified & get the break point there */
441     if (srcMode == SRC_CMODE && line > mod->ncLines) {
442         fprintf(stderr,"No line %d in file \"%s\".\n",
443                 line,mod->c_name);
444         return ;
445     }
446
447     if (srcMode == SRC_AMODE && line > mod->ncLines) {
448         fprintf(stderr,"No line %d in file \"%s\".\n",
449                 line,mod->c_name);
450         return ;
451     }
452
453     for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ;
454           line++ ) {
455         if (srcMode == SRC_CMODE)
456             if (mod->cLines[line]->addr) {
457                 clearUSERbp (mod->cLines[line]->addr);
458                 break;
459             }
460         else
461             if (mod->asmLines[line]->addr) {
462                 clearUSERbp (mod->asmLines[line]->addr);
463                 break;
464             }
465     }
466
467     return;
468 }
469
470 /*-----------------------------------------------------------------*/
471 /* moduleLineWithAddr - finds and returns a line  with a given address */
472 /*-----------------------------------------------------------------*/
473 DEFSETFUNC(moduleLineWithAddr)
474 {
475     module *mod = item;
476     int i;
477
478     V_ARG(unsigned int,addr);
479     V_ARG(module **,rmod);
480     V_ARG(int *,line);
481
482     if (*rmod)
483         return 0;
484
485     for (i=0; i < mod->nasmLines; i++ )
486     {
487         if ( mod->asmLines[i]->addr == addr)
488         {
489             *rmod = mod ;
490             if (line )
491             {
492                 *line = 0;
493                 for ( i=0; i < mod->ncLines; i++ )
494                 {
495                     if ( mod->cLines[i]->addr > addr)
496                         break;
497                     *line = i;
498                 }
499                 return 1;
500             }
501         }
502     }
503
504     return 0;
505 }
506
507 /*-----------------------------------------------------------------*/
508 /* funcWithNameModule - returns functions with a name module combo */
509 /*-----------------------------------------------------------------*/
510 DEFSETFUNC(funcWithNameModule)
511 {
512     function *func = item;
513     V_ARG(char *,fname);
514     V_ARG(char *,mname);
515     V_ARG(function **,funcp);
516
517     if (*funcp)
518         return 0;
519
520     if (strcmp(func->sym->name,fname) == 0 &&
521         strcmp(func->mod->c_name,mname) == 0) {
522         *funcp = func;
523         return 1;
524     }
525
526     return 0;
527 }
528
529 /*-----------------------------------------------------------------*/
530 /* funcInAddr - given an address returns the function              */
531 /*-----------------------------------------------------------------*/
532 DEFSETFUNC(funcInAddr)
533 {
534     function *func = item;
535     V_ARG(unsigned int,addr);
536     V_ARG(function **,funcp);
537
538     if (*funcp)
539         return 0;
540
541     /* in the address range */
542     if (func->sym->addr <= addr &&
543         func->sym->eaddr >= addr) {
544
545         *funcp = func;
546         return 1;
547     }
548
549     return 0;
550 }
551
552 /*-----------------------------------------------------------------*/
553 /* setStepBp - will set STEP Bp @ function entry points            */
554 /*-----------------------------------------------------------------*/
555 DEFSETFUNC(setStepBp)
556 {
557     function *func = item;
558
559     if (func->sym && func->sym->addr ) {
560
561         /* set the entry break point */
562         setBreakPoint (func->sym->addr , CODE , STEP ,
563                        stepBpCB ,func->mod->c_name , func->entryline);
564
565         return 1;
566     }
567
568     return 0;
569 }
570
571 /*-----------------------------------------------------------------*/
572 /* setStepEPBp - sets a given type of bp @ the execution point     */
573 /*-----------------------------------------------------------------*/
574 DEFSETFUNC(setStepEPBp)
575 {
576     exePoint *ep = item;
577     V_ARG(int,bptype);
578     V_ARG(char *,mname);
579
580     setBreakPoint (ep->addr, CODE, bptype,
581                    stepBpCB, mname, ep->line);
582     return 1;
583 }
584
585 /*-----------------------------------------------------------------*/
586 /* setNextEPBp - sets a given type of bp @ the execution point     */
587 /*-----------------------------------------------------------------*/
588 DEFSETFUNC(setNextEPBp)
589 {
590     exePoint *ep = item;
591     V_ARG(int,bptype);
592     V_ARG(char *,mname);
593
594     setBreakPoint (ep->addr, CODE, bptype,
595                    nextBpCB, mname, ep->line);
596     return 1;
597 }
598
599 /*-----------------------------------------------------------------*/
600 /* lineAtAddr - for execution points returns the one with addr     */
601 /*-----------------------------------------------------------------*/
602 DEFSETFUNC(lineAtAddr)
603 {
604     exePoint *ep = item;
605     V_ARG(unsigned int,addr);
606     V_ARG(int *,line);
607     V_ARG(int *,block);
608     V_ARG(int *,level);
609
610     /* address must be an exact match */
611     if (ep->addr == addr) {
612         *line = ep->line;
613         if (block)
614             *block = ep->block ;
615         if (level)
616             *level = ep->level ;
617         return 1;
618     }
619
620     return 0;
621
622 }
623
624 /*-----------------------------------------------------------------*/
625 /* lineNearAddr - for execution points returns the one with addr   */
626 /*-----------------------------------------------------------------*/
627 DEFSETFUNC(lineNearAddr)
628 {
629     exePoint *ep = item;
630     V_ARG(unsigned int,addr);
631     V_ARG(int *,line);
632     V_ARG(int *,block);
633     V_ARG(int *,level);
634
635     /* the line in which the address is */
636     if (ep->addr <= addr) {
637         *line = ep->line;
638         if (block)
639             *block = ep->block ;
640         if (level)
641             *level = ep->level ;
642         return 1;
643     }
644
645     return 0;
646
647 }
648
649 /*-----------------------------------------------------------------*/
650 /* discoverContext - find out the current context of the bp        */
651 /*-----------------------------------------------------------------*/
652 context *discoverContext (unsigned addr, function *func)
653 {
654     module   *mod  = NULL;
655     int line = 0;
656
657     /* find the function we are in */
658     if (!func && !applyToSet(functions,funcInAddr,addr,&func)) {
659         if (!applyToSet(functions,funcWithName,"_main",&func) ||
660             !applyToSet(modules,moduleLineWithAddr,addr,&mod,NULL))
661         {
662             fprintf(stderr, "addr 0x%x in no module/function (runtime env?)\n",addr);
663             return NULL;
664         }
665         currCtxt->func = func;
666         currCtxt->addr = addr;
667         currCtxt->modName = mod->name;
668         currCtxt->cline = func->exitline;
669     }
670     else
671     {
672         currCtxt->func = func;
673         currCtxt->addr = func->laddr = addr;
674         currCtxt->modName = func->modName;
675
676         /* find the c line number */
677         if(applyToSet(func->cfpoints,lineAtAddr,addr,
678                   &line,&currCtxt->block,&currCtxt->level))
679             currCtxt->cline = func->lline = line;
680         else if(applyToSet(func->cfpoints,lineNearAddr,addr,
681                   &line,&currCtxt->block,&currCtxt->level))
682             currCtxt->cline = func->lline = line;
683         else
684             currCtxt->cline = -1;
685     }
686     /* find the asm line number */
687     line = 0;
688     if (applyToSet(func->afpoints,lineAtAddr,addr,
689                    &line,NULL,NULL))
690         currCtxt->asmline = line;
691     else
692         currCtxt->asmline = -1;
693
694     return currCtxt ;
695 }
696
697
698 /*-----------------------------------------------------------------*/
699 /* simGo - send 'go' cmd to simulator and wait till a break occurs */
700 /*-----------------------------------------------------------------*/
701 void simGo (unsigned int gaddr)
702 {
703     unsigned int addr ;
704     context *ctxt;
705     int rv;
706     stopCommandList();
707  top:
708     if ( userinterrupt )
709     {
710         userinterrupt = 0;
711         return;
712     }
713     if ( gaddr == 0 )
714     {
715         function *func = NULL;;
716         if (applyToSet(functions,funcInAddr,gaddr,&func))
717             STACK_PUSH(callStack,func);
718     }
719     addr = simGoTillBp (gaddr);
720
721     /* got the pc for the break point now first
722        discover the program context i.e. module, function
723        linenumber of the source etc, etc etc */
724     currentFrame = 0;
725     ctxt = discoverContext (addr, NULL);
726
727     /* dispatch all the break point call back functions */
728     rv = dispatchCB (addr,ctxt);
729
730     /* the dispatch call back function will return
731        non-zero if an user break point has been hit
732        if not then we continue with the execution
733        of the program */
734     if (!rv)
735     {
736         if ( gaddr == 0 )
737             gaddr = -1;
738         if ( gaddr == -1 || doingSteps == 1 )
739             goto top ;
740     }
741
742 }
743
744 /*-----------------------------------------------------------------*/
745 /* preparePrint - common parse function for  set variable,         */
746 /*                output, print and display                        */
747 /*-----------------------------------------------------------------*/
748 static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
749 {
750     char *bp;
751     char save_ch ;
752     int ptr = 0;
753
754     *fmt = FMT_NON;
755     *sym = NULL;
756
757     s = trim(s);
758     if (!*s)
759         return (char *)0;
760
761     if ( *s == '/' )
762     {
763         /* format of printout */
764         switch ( *++s )
765         {
766             case 'x':
767                 *fmt = FMT_HEX ;
768                 break;
769             case 'o':
770                 *fmt = FMT_OCT ;
771                 break;
772             default:
773             case 'd':
774                 *fmt = FMT_DEZ ;
775                 break;
776             case 't':
777                 *fmt = FMT_BIN ;
778                 break;
779         }
780         s++;
781         s = trim_left(s);
782     }
783     while (*s == '*') {
784         ptr++;
785         s++;
786     }
787     for ( bp = s; *bp && ( isalnum( *bp ) || *bp == '_' || *bp == '$'); bp++ );
788     save_ch = *bp;
789     if ( *bp )
790         *bp = '\0';
791
792     if ( *s )
793         *sym = symLookup(s,cctxt);
794     *bp = save_ch;
795     while (ptr--)
796         strcat(bp,"*");
797
798     if ( ! *sym )
799         fprintf(stdout,"No symbol \"%s\" in current context.\n", s);
800     return bp;
801 }
802
803 static int printAsmLine( function *func, module *m, unsigned saddr, unsigned eaddr)
804 {
805     int i,j,delta;
806     unsigned symaddr;
807     unsigned lastaddr = saddr+1;
808     char *symname;
809
810     if ( func )
811     {
812         symaddr = func->sym->addr;
813         symname = func->sym->name;
814     }
815     else
816     {
817         symaddr = saddr;
818         symname = "" ;
819     }
820     for (j=0,i=0; i < m->nasmLines; i++ )
821     {
822         if ( saddr >= 0 && m->asmLines[i]->addr < saddr)
823         {
824                 continue;
825         }
826         if ( eaddr >= 0 && m->asmLines[i]->addr > eaddr)
827         {
828                 continue;
829         }
830         if ( func &&
831             (m->asmLines[i]->addr < func->sym->addr ||
832              m->asmLines[i]->addr > func->sym->eaddr ))
833         {
834             continue;
835         }
836         delta = m->asmLines[i]->addr - symaddr;
837         if ( delta >= 0 )
838         {
839             j++;
840             lastaddr = m->asmLines[i]->addr;
841             printf("0x%08x <%s",lastaddr,symname);
842             if (delta > 0) printf("+%d",delta);
843             printf(">:\t%s",m->asmLines[i]->src);
844         }
845     }
846     return lastaddr;
847 }
848
849 /*-----------------------------------------------------------------*/
850 /* cmdDisasm - disassemble  asm instruction                        */
851 /*-----------------------------------------------------------------*/
852 static int cmdDisasm (char *s, context *cctxt, int args)
853 {
854     function *func = NULL;
855     long  saddr = -1;
856     long  eaddr = -1;
857     int   found = 0;
858     module *modul;
859     /* white space skip */
860
861     if ( args > 0 )
862     {
863         s = trim_left(s);
864
865         if ( isdigit(*s))
866         {
867             saddr = strtol(s,&s,0);
868             if ( args > 1 )
869             {
870                 s = trim_left(s);
871
872                 if ( isdigit(*s))
873                     eaddr = strtol(s,0,0);
874             }
875             else
876                 eaddr = saddr+1;
877         }
878     }
879
880     if ( eaddr == -1 )
881     {
882         /* no start or only start so dump function */
883         if ( saddr == -1 )
884         {
885             func = cctxt->func;
886         }
887         else
888         {
889             applyToSet(functions,funcInAddr,saddr,&func);
890         }
891         if ( func )
892         {
893             printf("Dump of assembler code for function %s:\n",func->sym->name);
894             printAsmLine(func,func->mod,-1,-1);
895             printf("End of assembler dump.\n");
896             return 0;
897         }
898         else
899         {
900             if (applyToSet(modules,moduleLineWithAddr,saddr,&modul,NULL))
901             {
902                 eaddr = saddr + 5;
903                 printf("Dump of assembler code:\n");
904                 printAsmLine(NULL,modul,saddr,eaddr);
905                 printf("End of assembler dump.\n");
906                 return 0;
907             }
908         }
909     }
910     else
911     {
912         if ( args > 1 )
913             printf("Dump of assembler code from 0x%08lx to 0x%08lx:\n",saddr,eaddr);
914         found = 0;
915         while ( saddr < eaddr )
916         {
917             func = NULL;
918             if (applyToSet(functions,funcInAddr,saddr,&func))
919             {
920                 found = 1;
921                 modul = func->mod;
922             }
923             else
924             {
925                 if ( found )
926                     break;
927                 if (!applyToSet(modules,moduleLineWithAddr,saddr,&modul,NULL))
928                     break;
929             }
930             saddr = printAsmLine(func,modul,saddr,eaddr) + 1;
931         }
932         if( saddr >= eaddr)
933         {
934             if ( args > 1 )
935                 printf("End of assembler dump.\n");
936             return 0;
937         }
938
939     }
940     fprintf(stderr,"No function contains specified address.\n");
941     if( saddr >= 0 )
942     {
943         char lbuf[64];
944         sprintf(lbuf,"dis 0x%lx 0 %ld\n",saddr,( eaddr == -1 )?1L:eaddr-saddr);
945         sendSim(lbuf);
946         waitForSim(1000, NULL);
947         fputs(simResponse(),stdout);
948     }
949     return 0;
950 }
951 /*-----------------------------------------------------------------*/
952 /* cmdDisasm1 - disassemble one asm instruction                    */
953 /*-----------------------------------------------------------------*/
954 int cmdDisasm1 (char *s, context *cctxt)
955 {
956     return cmdDisasm( s, cctxt, 1);
957 }
958
959 /*-----------------------------------------------------------------*/
960 /* cmdDisasmF - disassemble asm instructions                       */
961 /*-----------------------------------------------------------------*/
962 int cmdDisasmF(char *s, context *cctxt)
963 {
964     return cmdDisasm( s, cctxt, 2);
965 }
966
967 static int commonSetUserBp(char *s, context *cctxt, char bpType)
968 {
969     char *bp ;
970     function *func = NULL;
971
972     /* user break point location specification can be of the following
973        forms
974        a) <nothing>        - break point at current location
975        b) lineno           - number of the current module
976        c) filename:lineno  - line number of the given file
977        e) filename:function- function X in file Y (useful for static functions)
978        f) function         - function entry point
979        g) *addr            - break point at address
980     */
981
982     if (!cctxt) {
983         fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
984         return 0;
985     }
986     /* trim left and right */
987     s = trim(s);
988
989     /* case a) nothing */
990     /* if nothing given then current location : we know
991        the current execution location from the currentContext */
992     if (! *s ) {
993
994         /* if current context is known */
995         if (cctxt->func) {
996         Dprintf(D_break, ("commonSetUserBp: a) cctxtaddr:%x \n",cctxt->addr));
997             if (srcMode == SRC_CMODE)
998                 /* set the break point */
999                 setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
1000                                 cctxt->func->mod->c_name, cctxt->cline);
1001             else
1002                 setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
1003                                 cctxt->func->mod->asm_name, cctxt->asmline);
1004
1005         }
1006         else
1007             fprintf(stderr,"No default breakpoint address now.\n");
1008
1009         goto ret ;
1010     }
1011     /* case g) *addr */
1012     if ( *s == '*' && isdigit(*(s+1)))
1013     {
1014         int  line   = 0;
1015         long braddr = strtol(s+1,0,0);
1016         if (!applyToSet(functions,funcInAddr,braddr,&func))
1017         {
1018             module *modul;
1019             if (!applyToSet(modules,moduleLineWithAddr,braddr,&modul,&line))
1020             {
1021                 fprintf(stderr,"Address 0x%08lx not exists in code.\n",braddr);
1022             }
1023             else
1024             {
1025                 Dprintf(D_break, ("commonSetUserBp: g) addr:%lx \n",braddr));
1026                 setBreakPoint ( braddr , CODE , bpType , userBpCB ,
1027                             modul->c_name,line);
1028             }
1029             goto ret ;
1030         }
1031                 else
1032         {
1033             int line = func->exitline;
1034             if ( !applyToSet(func->cfpoints,lineAtAddr,braddr,
1035                                   &line,NULL,NULL))
1036                 applyToSet(func->cfpoints,lineNearAddr,braddr,&line,NULL,NULL);
1037             setBreakPoint ( braddr , CODE , bpType , userBpCB ,
1038                             func->mod->c_name,line);
1039         }
1040         goto ret ;
1041     }
1042     /* case b) lineno */
1043     /* check if line number */
1044     if ( !strchr(s,':') && isdigit(*s)) {
1045         /* get the lineno */
1046         int line = atoi(s) -1;
1047     Dprintf(D_break, ("commonSetUserBp: b) line:%d \n",line));
1048     if ( line < 0 )
1049     {
1050                 fprintf(stdout,"linenumber <= 0\n");
1051         goto ret;
1052     }
1053         /* if current context not present then we must get the module
1054            which has main & set the break point @ line number provided
1055            of that module : if current context known then set the bp
1056            at the line number given for the current module
1057         */
1058         if (cctxt->func) {
1059             if (!cctxt->func->mod) {
1060                 if (!applyToSet(functions,funcWithName,"main"))
1061                     fprintf(stderr,"Function \"main\" not defined.\n");
1062                 else
1063                     setBPatModLine(func->mod,line, bpType);
1064             } else
1065                 setBPatModLine(cctxt->func->mod,line, bpType);
1066         } else {
1067                 if (list_mod) {
1068                         setBPatModLine(list_mod,line, bpType);
1069                 } else {
1070                   fprintf(stdout,"Sdcdb fails to have module symbol context at %d\n", __LINE__);
1071                 }
1072         }
1073
1074         goto ret;
1075     }
1076
1077     if ((bp = strchr(s,':'))) {
1078
1079         module *mod = NULL;
1080         *bp = '\0';
1081
1082         if (srcMode == SRC_CMODE) {
1083             if (!applyToSet(modules,moduleWithCName,s,&mod)) {
1084                 fprintf (stderr,"No source file named %s.\n",s);
1085                 goto ret;
1086             }
1087         } else {
1088             if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
1089                 fprintf (stderr,"No source file named %s.\n",s);
1090                 goto ret;
1091             }
1092         }
1093
1094         /* case c) filename:lineno */
1095         if (isdigit(*(bp +1))) {
1096         Dprintf(D_break, ("commonSetUserBp: c) line:%d \n",atoi(bp+1)));
1097             setBPatModLine (mod,atoi(bp+1)-1,bpType);
1098             goto ret;
1099
1100         }
1101         /* case d) filename:function */
1102         if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func))
1103             fprintf(stderr,"Function \"%s\" not defined.\n",bp+1);
1104         else
1105         Dprintf(D_break, ("commonSetUserBp: d) \n"));
1106             setBPatModLine (mod,
1107                             (srcMode == SRC_CMODE ?
1108                              func->entryline :
1109                              func->aentryline),bpType);
1110
1111         goto ret;
1112     }
1113
1114     /* case e) function */
1115     Dprintf(D_break, ("commonSetUserBp: e) \n"));
1116     if (!applyToSet(functions,funcWithName,s,&func))
1117         fprintf(stderr,"Function \"%s\" not defined.\n",s);
1118     else
1119         setBPatModLine(func->mod,
1120                        (srcMode == SRC_CMODE ?
1121                         func->entryline :
1122                         func->aentryline),bpType);
1123
1124  ret:
1125     return 0;
1126 }
1127
1128 /*-----------------------------------------------------------------*/
1129 /* cmdSetTmpUserBp - settempory break point at the user specified location   */
1130 /*-----------------------------------------------------------------*/
1131 int cmdSetTmpUserBp (char *s, context *cctxt)
1132 {
1133     return commonSetUserBp(s, cctxt, TMPUSER );
1134 }
1135
1136 /*-----------------------------------------------------------------*/
1137 /* cmdSetUserBp - set break point at the user specified location   */
1138 /*-----------------------------------------------------------------*/
1139 int cmdSetUserBp (char *s, context *cctxt)
1140 {
1141     return commonSetUserBp(s, cctxt, USER );
1142 }
1143
1144 /*-----------------------------------------------------------------*/
1145 /* cmdJump - set program counter                                   */
1146 /*-----------------------------------------------------------------*/
1147 int cmdJump (char *s, context *cctxt)
1148 {
1149     char *bp;
1150     function *func = NULL;
1151     if (STACK_EMPTY(callStack))
1152     {
1153         fprintf(stdout,"The program is not running.\n");
1154         return 0;
1155     }
1156
1157     /* trim left and right */
1158     s = trim(s);
1159
1160     if (! *s )
1161     {
1162         fprintf(stdout,"No argument: need line or *addr.\n");
1163         return 0;
1164     }
1165     if ( *s == '*' && isdigit(*(s+1)))
1166     {
1167         unsigned int addr = atoi(s);
1168         if (cctxt && cctxt->func &&
1169             cctxt->func->sym->addr <= addr &&
1170             cctxt->func->sym->eaddr >= addr)
1171         {
1172             simSetPC(addr);
1173             return 0;
1174         }
1175         fprintf(stdout,"Warning addr 0x%x outside actual function.\n",addr);
1176         simSetPC(addr);
1177         return 0;
1178     }
1179     if (isdigit(*s))
1180     {
1181         /* get the lineno */
1182         int line = atoi(s) -1;
1183         if (!cctxt || !cctxt->func || !cctxt->func->mod)
1184         {
1185                     fprintf(stderr,"Function not defined.\n");
1186             return 0;
1187         }
1188         if (line >= cctxt->func->entryline &&
1189             line <= cctxt->func->exitline )
1190         {
1191             simSetPC(cctxt->func->mod->cLines[line]->addr);
1192             return 0;
1193         }
1194         if (line >= cctxt->func->mod->ncLines )
1195         {
1196                     fprintf(stderr,"line not in module.\n");
1197             return 0;
1198         }
1199         fprintf(stdout,"Warning line %d outside actual function.\n",line+1);
1200         simSetPC(cctxt->func->mod->cLines[line]->addr);
1201         return 0;
1202     }
1203     if ((bp = strchr(s,':')))
1204     {
1205         int line;
1206         module *mod = NULL;
1207         *bp++ = '\0';
1208         if (!applyToSet(modules,moduleWithCName,s,&mod))
1209         {
1210             fprintf (stderr,"No source file named %s.\n",s);
1211             return 0;
1212         }
1213         if (!isdigit(*bp))
1214         {
1215             fprintf (stderr,"No line number.\n");
1216             return 0;
1217         }
1218         line = atoi(bp) -1;
1219         if (line >= mod->ncLines )
1220         {
1221                     fprintf(stderr,"line not in module.\n");
1222             return 0;
1223         }
1224         if ( mod != cctxt->func->mod ||
1225              line < cctxt->func->entryline ||
1226              line > cctxt->func->exitline )
1227         {
1228             fprintf(stdout,"Warning line %d outside actual function.\n",
1229                     line+1);
1230         }
1231         simSetPC(mod->cLines[line]->addr);
1232     }
1233     return 0;
1234 }
1235
1236 /*-----------------------------------------------------------------*/
1237 /* cmdListAsm - list assembler source code                         */
1238 /*-----------------------------------------------------------------*/
1239 int cmdListAsm (char *s, context *cctxt)
1240 {
1241     if (  cctxt && cctxt->func)
1242     {
1243         /* actual line */
1244         if ( cctxt->addr != INT_MAX )
1245         {
1246             if (printAsmLine(cctxt->func,cctxt->func->mod,
1247                          (long)cctxt->addr,(long)cctxt->addr))
1248             return 0;
1249         }
1250     }
1251     return 0;
1252 }
1253
1254 /*-----------------------------------------------------------------*/
1255 /* cmdSetOption - set debugger options                             */
1256 /*-----------------------------------------------------------------*/
1257 int cmdSetOption (char *s, context *cctxt)
1258 {
1259     s = trim_left(s);
1260     if (strncmp(s,"srcmode",7) == 0 ) {
1261         if (srcMode == SRC_CMODE)
1262             srcMode = SRC_AMODE;
1263         else
1264             srcMode = SRC_CMODE;
1265         fprintf(stderr,"source mode set to '%s'\n",
1266                 (srcMode == SRC_CMODE ? "C" : "asm"));
1267         return 0;
1268     }
1269
1270     if (strncmp(s,"listsize ",9) == 0)
1271     {
1272         listlines = strtol(s+9,0,0);
1273         if ( listlines < LISTLINES )
1274             listlines = LISTLINES;
1275         return 0;
1276     }
1277
1278 #ifdef SDCDB_DEBUG
1279     if (strncmp(s,"debug ",6) == 0)
1280     {
1281         sdcdbDebug = strtol(s+6,0,0);
1282         return 0;
1283     }
1284 #endif
1285     if (strncmp(s,"variable ",9) == 0)
1286     {
1287         symbol *sym ;
1288         int fmt;
1289         char *rs;
1290         s += 9;
1291         if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
1292             return 0;
1293         s = rs;
1294         while (*s && *s != '=') s++;
1295         *s++ = '\0';
1296         s = trim_left(s);
1297         if (*s && sym)
1298         {
1299             printOrSetSymValue(sym,cctxt,0,0,0,rs,s,'\0');
1300             return 0;
1301         }
1302         else
1303             fprintf(stdout,"No new value for \"%s\".\n",s);
1304         return 0;
1305     }
1306
1307
1308     fprintf(stderr,"'set %s' command not yet implemented\n",s);
1309     return 0;
1310 }
1311
1312 /*-----------------------------------------------------------------*/
1313 /* cmdContinue - continue till next break point                    */
1314 /*-----------------------------------------------------------------*/
1315 int cmdContinue (char *s, context *cctxt)
1316 {
1317     if (STACK_EMPTY(callStack)) {
1318         fprintf(stdout,"The program is not being run.\n");
1319         return 0;
1320     }
1321
1322     fprintf(stdout,"Continuing.\n");
1323     simGo(-1);
1324     showfull = 1;
1325     return 0;
1326 }
1327
1328 /*-----------------------------------------------------------------*/
1329 /* cmdIgnore - set ignorecount for breakpoint                      */
1330 /*-----------------------------------------------------------------*/
1331 int cmdIgnore (char *s, context *cctxt)
1332 {
1333     int bpnum, cnt ;
1334     s = trim_left(s);
1335     if (!*s )
1336     {
1337         fprintf(stdout,"Argument required (breakpoint number).\n");
1338         return 0;
1339     }
1340     bpnum = strtol(s,&s,10);
1341     s = trim_left(s);
1342     if (!*s )
1343     {
1344         fprintf(stdout,"Second argument (specified ignore-count) is missing.");
1345         return 0;
1346     }
1347     cnt = strtol(s,0,10);
1348     setUserbpIgnCount(bpnum,cnt);
1349     return 0;
1350 }
1351
1352 /*-----------------------------------------------------------------*/
1353 /* cmdCondition - set condition for breakpoint                     */
1354 /*-----------------------------------------------------------------*/
1355 int cmdCondition (char *s, context *cctxt)
1356 {
1357     int bpnum ;
1358     s = trim_left(s);
1359     if (!*s )
1360     {
1361         fprintf(stdout,"Argument required (breakpoint number).\n");
1362         return 0;
1363     }
1364     bpnum = strtol(s,&s,10);
1365     s = trim_left(s);
1366     if (*s)
1367         s = Safe_strdup(s);
1368     else
1369         s = NULL;
1370     setUserbpCondition(bpnum,s);
1371     return 0;
1372 }
1373
1374 /*-----------------------------------------------------------------*/
1375 /* cmdCommands - set commands for breakpoint                       */
1376 /*-----------------------------------------------------------------*/
1377 int cmdCommands (char *s, context *cctxt)
1378 {
1379     int bpnum ;
1380     char *cmds,*line;
1381     s = trim_left(s);
1382
1383     if (!*s )
1384         bpnum = getLastBreakptNumber();
1385     else
1386         bpnum = strtol(s,0,10);
1387
1388     cmds = NULL;
1389     while ((line = getNextCmdLine()))
1390     {
1391         line = trim_left(line);
1392         if (!strncmp(line,"end",3))
1393             break;
1394         if (! cmds )
1395         {
1396             cmds = Safe_strdup(line);
1397         }
1398         else
1399         {
1400             cmds = Safe_realloc( cmds, strlen(cmds) + 1 + strlen(line));
1401             strcat(cmds,line);
1402         }
1403     }
1404     setUserbpCommand(bpnum,cmds);
1405     return 0;
1406 }
1407
1408 /*-----------------------------------------------------------------*/
1409 /* cmdDelUserBp - delete user break point                          */
1410 /*-----------------------------------------------------------------*/
1411 int cmdDelUserBp (char *s, context *cctxt)
1412 {
1413     int bpnum ;
1414     s = trim_left(s);
1415
1416     if (!*s ) {
1417         if (userBpPresent) {
1418             char buffer[10];
1419             fprintf (stdout,"Delete all breakpoints? (y or n) ");
1420             fflush(stdout);
1421             fgets(buffer,sizeof(buffer),stdin);
1422             if (toupper(buffer[0]) == 'Y')
1423                 deleteUSERbp(-1);
1424         }
1425         return 0;
1426     }
1427
1428     /* determine the break point number */
1429     if (sscanf(s,"%d",&bpnum) == 1)
1430         deleteUSERbp(bpnum);
1431
1432     return 0;
1433 }
1434
1435 /*-----------------------------------------------------------------*/
1436 /* cmdStepi - single step exactly one instruction                   */
1437 /*-----------------------------------------------------------------*/
1438 int cmdStepi (char *s, context *cctxt)
1439 {
1440
1441     if (0 /*STACK_EMPTY(callStack)*/)
1442         fprintf(stdout,"The program is not being run.\n");
1443     else
1444     {
1445         doingSteps = 2;
1446             simGo(2);
1447         doingSteps = 0;
1448         showfull = 1;
1449     }
1450     return 0;
1451 }
1452
1453 /*-----------------------------------------------------------------*/
1454 /* cmdStep - single step thru C source file                        */
1455 /*-----------------------------------------------------------------*/
1456 int cmdStep (char *s, context *cctxt)
1457 {
1458     function *func = NULL;
1459
1460     if (STACK_EMPTY(callStack))
1461         fprintf(stdout,"The program is not being run.\n");
1462     else {
1463         /* if we are @ the end of a function then set
1464            break points at execution points of the
1465            function in the call stack... */
1466         if (cctxt->addr == cctxt->func->sym->eaddr) {
1467             if ((func = STACK_PEEK(callStack))) {
1468                 if (srcMode == SRC_CMODE)
1469                     applyToSet (func->cfpoints,setStepEPBp,STEP,
1470                                 func->mod->c_name);
1471                 else
1472                     applyToSet (func->afpoints,setStepEPBp,STEP,
1473                                 func->mod->asm_name);
1474             }
1475         } else {
1476             /* set breakpoints at all function entry points
1477                and all exepoints of this functions & for
1478                all functions one up in the call stack */
1479
1480             /* all function entry points */
1481             applyToSet(functions,setStepBp);
1482
1483             if (srcMode == SRC_CMODE) {
1484                 /* for all execution points in this function */
1485                 applyToSet(cctxt->func->cfpoints,setStepEPBp,STEP,
1486                            cctxt->func->mod->c_name);
1487
1488                 /* set a break point @ the current function's
1489                    exit */
1490                 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP ,
1491                                stepBpCB, cctxt->func->mod->c_name,
1492                                cctxt->func->exitline);
1493
1494                 /* now break point @ callers execution points */
1495                 if ((func = STACK_PPEEK(callStack))) {
1496                     applyToSet (func->cfpoints,setStepEPBp,STEP,
1497                                 func->mod->c_name);
1498                     /* set bp @ callers exit point */
1499                     setBreakPoint (func->sym->eaddr, CODE, STEP ,
1500                                    stepBpCB, func->mod->c_name,
1501                                    func->exitline);
1502                 }
1503             } else {
1504                 /* for all execution points in this function */
1505                 applyToSet(cctxt->func->afpoints,setStepEPBp,STEP,
1506                            cctxt->func->mod->asm_name);
1507
1508                 /* set a break point @ the current function's
1509                    exit */
1510                 setBreakPoint (cctxt->func->sym->eaddr, CODE, STEP ,
1511                                stepBpCB, cctxt->func->mod->asm_name,
1512                                cctxt->func->aexitline);
1513
1514                 /* now break point @ callers execution points */
1515                 if ((func = STACK_PPEEK(callStack))) {
1516
1517                     applyToSet (func->afpoints,setStepEPBp,STEP,
1518                                 func->mod->asm_name);
1519
1520                     /* set bp @ callers exit point */
1521                     setBreakPoint (func->sym->eaddr, CODE, STEP ,
1522                                    stepBpCB, func->mod->asm_name,
1523                                    func->aexitline);
1524                 }
1525             }
1526         }
1527
1528         doingSteps = 1;
1529         simGo(2);
1530         doingSteps = 0;
1531         showfull = 1;
1532     }
1533     return 0;
1534 }
1535
1536 /*-----------------------------------------------------------------*/
1537 /* cmdNexti - next instruction but proceed function call           */
1538 /*-----------------------------------------------------------------*/
1539 int cmdNexti (char *s, context *cctxt)
1540 {
1541     if (STACK_EMPTY(callStack))
1542         fprintf(stdout,"The program is not being run.\n");
1543     else
1544     {
1545         doingSteps = 2;
1546             simGo(1);
1547         doingSteps = 0;
1548         showfull = 1;
1549     }
1550     return 0;
1551 }
1552
1553 /*-----------------------------------------------------------------*/
1554 /* cmdNext - next executable C statement file                      */
1555 /*-----------------------------------------------------------------*/
1556 int cmdNext (char *s, context *cctxt)
1557 {
1558     function *func = NULL;
1559     /* next is almost the same as step except we don't
1560        we don't set break point for all function entry
1561        points */
1562     if (STACK_EMPTY(callStack))
1563         fprintf(stdout,"The program is not being run.\n");
1564     else {
1565         /* if we are @ the end of a function then set
1566            break points at execution points of the
1567            function in the call stack... */
1568         if (cctxt->addr == cctxt->func->sym->eaddr) {
1569             if ((func = STACK_PEEK(callStack))) {
1570                 if (srcMode == SRC_CMODE)
1571                     applyToSet (func->cfpoints,setStepEPBp,NEXT,
1572                                 func->mod->c_name);
1573                 else
1574                     applyToSet (func->afpoints,setStepEPBp,NEXT,
1575                                 func->mod->asm_name);
1576             }
1577         } else {
1578             if (srcMode == SRC_CMODE) {
1579                 /* for all execution points in this function */
1580                 applyToSet(cctxt->func->cfpoints,setNextEPBp,NEXT,
1581                            cctxt->func->mod->c_name);
1582                 /* set a break point @ the current function's
1583                    exit */
1584                 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT ,
1585                                nextBpCB, cctxt->func->mod->c_name,
1586                                cctxt->func->exitline);
1587
1588                 /* now break point @ callers execution points */
1589                 if ((func = STACK_PPEEK(callStack))) {
1590                     applyToSet (func->cfpoints,setNextEPBp,NEXT ,
1591                                 func->mod->c_name);
1592                     /* set bp @ callers exit point */
1593                     setBreakPoint (func->sym->eaddr, CODE, NEXT ,
1594                                    stepBpCB, func->mod->c_name,
1595                                    func->exitline);
1596                 }
1597             } else {
1598                 /* for all execution points in this function */
1599                 applyToSet(cctxt->func->afpoints,setNextEPBp,NEXT,
1600                            cctxt->func->mod->asm_name);
1601                 /* set a break point @ the current function's
1602                    exit */
1603                 setBreakPoint (cctxt->func->sym->eaddr, CODE, NEXT ,
1604                                nextBpCB, cctxt->func->mod->asm_name,
1605                                cctxt->func->aexitline);
1606
1607                 /* now break point @ callers execution points */
1608                 if ((func = STACK_PPEEK(callStack))) {
1609                     applyToSet (func->cfpoints,setNextEPBp,NEXT ,
1610                                 func->mod->asm_name);
1611                     /* set bp @ callers exit point */
1612                     setBreakPoint (func->sym->eaddr, CODE, NEXT ,
1613                                    stepBpCB, func->mod->asm_name,
1614                                    func->aexitline);
1615                 }
1616             }
1617         }
1618         doingSteps = 1;
1619         simGo(1);
1620         doingSteps = 0;
1621         showfull = 1;
1622     }
1623     return 0;
1624 }
1625
1626 /*-----------------------------------------------------------------*/
1627 /* cmdRun  - run till next break point                             */
1628 /*-----------------------------------------------------------------*/
1629 int cmdRun (char *s, context *cctxt)
1630 {
1631     char buff[10];
1632     if (STACK_EMPTY(callStack)) {
1633         fprintf(stdout,"Starting program\n");
1634     if ( ! simactive )
1635     {
1636         fprintf(stdout,"No executable file specified.\nUse the \"file\" command.\n");
1637         return 0;
1638     }
1639     resetHitCount();
1640         simGo(0);
1641     } else {
1642
1643         fprintf(stdout,
1644                 "The program being debugged has been started already.\n");
1645         fprintf(stdout,"Start it from the beginning? (y or n) ");
1646         fflush(stdout);
1647
1648         fgets(buff,sizeof(buff),stdin);
1649         if (toupper(buff[0]) == 'Y') {
1650             simReset();
1651         resetHitCount();
1652             simGo(0);
1653         }
1654     }
1655     showfull = 1;
1656     return 0;
1657 }
1658
1659 /*-----------------------------------------------------------------
1660  cmdListSymbols - list symbols
1661 |-----------------------------------------------------------------*/
1662 int cmdListSymbols (char *s, context *cctxt)
1663 {
1664     int our_verbose = 0;
1665     symbol *sy;
1666     int i;
1667
1668     if (strstr(s, "v1")) {
1669       our_verbose = 1;
1670     } else if (strstr(s, "v2")) {
1671       our_verbose = 2;
1672     }
1673
1674     printf("[symbols]\n");
1675     sy = setFirstItem(symbols);
1676     i = 0;
1677     for (;;) {
1678       if (sy == NULL)
1679         break;
1680       if (our_verbose <= 1)
1681         printf("<%s>", sy->name);
1682
1683       if (our_verbose > 1) {
1684         printf("  %d) name:%s, size:%d, level:%d block:%d\n", i,
1685           sy->name, sy->size, sy->level, sy->block);
1686         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
1687           sy->isonstack, sy->isfunc, sy->offset, sy->addr);
1688         printf("    eaddr:%d, addr_type:%c, type:%p etype:%p\n",
1689           sy->eaddr, sy->addr_type, sy->type, sy->etype);
1690         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
1691           sy->scopetype, sy->sname, sy->rname, sy->addrspace);
1692         printf("    next:%p\n", sy->next);
1693       }
1694       ++i;
1695       sy = setNextItem(symbols);
1696     }
1697     printf("   %d symbols\n", i);
1698     return 0;
1699 }
1700
1701 /*-----------------------------------------------------------------
1702  cmdListFunctions - list functions.
1703 |-----------------------------------------------------------------*/
1704 int cmdListFunctions (char *s, context *cctxt)
1705 {
1706     function *f;
1707     int i;
1708     int our_verbose = 0;
1709
1710     if (strstr(s, "v1")) {
1711       our_verbose = 1;
1712     } else if (strstr(s, "v2")) {
1713       our_verbose = 2;
1714     }
1715
1716     printf("[functions]\n");
1717     f = setFirstItem(functions);
1718     i = 0;
1719     while (f != NULL) {
1720       if (our_verbose) {
1721         printf("  %d) sym:%p, fname:%s, modName:%s, mod:%p\n", i,
1722           f->sym, f->sym->name, f->modName, f->mod);
1723         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
1724                 f->entryline, f->aentryline, f->exitline, f->aexitline);
1725         printf("    cfpoints:%p, afpoints:%p, laddr:%x, lline:%d\n",
1726                 f->cfpoints, f->afpoints, f->laddr, f->lline);
1727       }
1728       else {
1729         printf("<%s>", f->sym->name);
1730       }
1731       ++i;
1732       f = setNextItem(functions);
1733     }
1734     printf("   %d functions\n", i);
1735     return 0;
1736 }
1737
1738 /*-----------------------------------------------------------------
1739  cmdListModules - list modules.
1740 |-----------------------------------------------------------------*/
1741 int cmdListModules (char *s, context *cctxt)
1742 {
1743     module *m;
1744     srcLine *cs, *as;
1745     int i, mi;
1746     int our_verbose = 0;
1747
1748     if (strstr(s, "v1")) {
1749       our_verbose = 1;
1750     } else if (strstr(s, "v2")) {
1751       our_verbose = 2;
1752     }
1753
1754     printf("[modules]\n");
1755     m = setFirstItem(modules);
1756     mi = 0;
1757     for (;;) {
1758       if (m == NULL)
1759         break;
1760
1761       if (our_verbose >= 0) {
1762       printf("  %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
1763         m->cfullname, m->afullname, m->name);
1764       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
1765               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
1766       printf("    cLines:%p, asmLines:%p\n",
1767               m->cLines, m->asmLines);
1768       }
1769       if (our_verbose >= 2) {
1770         if (m->ncLines) {
1771           printf("    [cLines] ");
1772           if ( our_verbose)
1773           for (i=0; i<m->ncLines; i++ ) {
1774               cs = m->cLines[i];
1775               printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1776                  i, cs->addr, cs->block, cs->level, cs->src);
1777           }
1778           if (!our_verbose)
1779               printf("%d records", i);
1780         }
1781         if (m->nasmLines) {
1782           printf("    [asmLines] ");
1783           if ( our_verbose)
1784           for (i=0; i<m->nasmLines; i++ ) {
1785               as = m->asmLines[i];
1786               printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1787                  i, as->addr, as->block, as->level, as->src);
1788           }
1789           if (!our_verbose)
1790               printf("%d records", i);
1791         }
1792         printf("\n");
1793       }
1794
1795       m = setNextItem(modules);
1796     }
1797     return 0;
1798 }
1799
1800 /*-----------------------------------------------------------------
1801  infoSymbols - This is really just a tool to dump all these
1802    huge program structures out into human readable form.
1803 |-----------------------------------------------------------------*/
1804 static void infoSymbols(context *ctxt)
1805 {
1806   int our_verbose = 0;
1807
1808   printf("[context:%p] func:%p modName:%s addr:%x\n",
1809     ctxt, ctxt->func, ctxt->modName, ctxt->addr);
1810
1811   printf("  cline:%d asmline:%d block:%d level:%d\n",
1812     ctxt->cline, ctxt->asmline, ctxt->block, ctxt->level);
1813
1814   printf("[globals] currCtxt:%p, modules:%p, functions:%p symbols:%p\n",
1815     currCtxt, modules, functions, symbols);
1816   printf("  nStructs:%d, structs:%p, ssdirl:%s\n",
1817     nStructs, structs, ssdirl);
1818
1819   /**************** modules *******************/
1820   {
1821     module *m;
1822     srcLine *cs, *as;
1823     int i, mi;
1824     printf("[modules]\n");
1825     m = setFirstItem(modules);
1826     mi = 0;
1827     for (;;) {
1828       if (m == NULL)
1829         break;
1830       printf("  %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
1831         m->cfullname, m->afullname, m->name);
1832       printf("    c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
1833               m->c_name, m->asm_name, m->ncLines, m->nasmLines);
1834       printf("    cLines:%p, asmLines:%p\n",
1835               m->cLines, m->asmLines);
1836       i = 0;
1837       if (m->cLines) {
1838         cs = m->cLines[i++];
1839         printf("    [cLines] ");
1840         while (cs) {
1841           if (our_verbose)
1842             printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1843                i, cs->addr, cs->block, cs->level, cs->src);
1844           cs = m->cLines[i++];
1845         }
1846         if (!our_verbose)
1847             printf("%d records", i);
1848       }
1849       i = 0;
1850       if (m->asmLines) {
1851         as = m->asmLines[i++];
1852         printf("    [asmLines] ");
1853         while (as) {
1854           if (our_verbose)
1855             printf("   (%d) addr:%x, block:%d, level:%d, src:%s\n",
1856                i, as->addr, as->block, as->level, as->src);
1857           as = m->asmLines[i++];
1858         }
1859         if (!our_verbose)
1860             printf("%d records", i);
1861       }
1862       printf("\n");
1863
1864       m = setNextItem(modules);
1865     }
1866   }
1867
1868   /**************** functions *******************/
1869   {
1870     function *f;
1871     int i;
1872     printf("[functions]\n");
1873     f = setFirstItem(functions);
1874     i = 0;
1875     for (;;) {
1876       if (f == NULL)
1877         break;
1878       if (our_verbose) {
1879         printf("  %d) sym:%p, modName:%s, mod:%p\n", i,
1880           f->sym, f->modName, f->mod);
1881         printf("    entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
1882                 f->entryline, f->aentryline, f->exitline, f->aexitline);
1883         printf("    cfpoints:%p, afpoints:%p, laddr:%x, lline:%d\n",
1884                 f->cfpoints, f->afpoints, f->laddr, f->lline);
1885       }
1886       ++i;
1887       f = setNextItem(functions);
1888     }
1889     if (!our_verbose)
1890       printf("   %d functions\n", i);
1891   }
1892
1893   /**************** symbols *******************/
1894   {
1895     symbol *s;
1896     int i;
1897     printf("[symbols]\n");
1898     s = setFirstItem(symbols);
1899     i = 0;
1900     for (;;) {
1901       if (s == NULL)
1902         break;
1903       if (our_verbose) {
1904         printf("  %d) name:%s, size:%d, level:%d block:%d\n", i,
1905           s->name, s->size, s->level, s->block);
1906         printf("    isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
1907           s->isonstack, s->isfunc, s->offset, s->addr);
1908         printf("    eaddr:%d, addr_type:%c, type:%p etype:%p\n",
1909           s->eaddr, s->addr_type, s->type, s->etype);
1910         printf("    scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
1911           s->scopetype, s->sname, s->rname, s->addrspace);
1912         printf("    next:%p\n", s->next);
1913       }
1914       ++i;
1915       s = setNextItem(symbols);
1916     }
1917     if (!our_verbose)
1918       printf("   %d symbols\n", i);
1919   }
1920
1921 }
1922
1923 /*-----------------------------------------------------------------*/
1924 /* infoRegisters - print register information                      */
1925 /*-----------------------------------------------------------------*/
1926 static void infoRegisters( int all, context *ctxt)
1927 {
1928     static int regaddrs[] = {0x81,0x82,0x83,0xb8,0xd0,0xe0,0xf0,0};
1929     unsigned long val;
1930     int i,j,*r;
1931
1932     i = simGetValue (0xd0,'I',1);
1933     fprintf(stdout,"IP  : 0x%04X  RegisterBank %d:\nR0-7:",ctxt->addr,(i>>3)&3);
1934     for ( j = 0; j < 8 ; j++ )
1935     {
1936         val = simGetValue (j,'R',1);
1937         fprintf(stdout," 0x%02lX",val);
1938     }
1939     fprintf(stdout,"\n");
1940     val = simGetValue (0xe0,'I',1);
1941     fprintf(stdout,"ACC : 0x%02lX %lu %c\n",val,val,(isprint(val) ? (char)val : '.'));
1942     val = simGetValue (0xf0,'I',1);
1943     fprintf(stdout,"B   : 0x%02lX %lu %c\n",val,val,(isprint(val) ? (char)val : '.'));
1944     val = simGetValue (0x82,'I',2);
1945     fprintf(stdout,"DPTR: 0x%04lX %lu\n",val,val);
1946     val = simGetValue (0x81,'I',1);
1947     fprintf(stdout,"SP  : 0x%02lX (0x%04lX)\n",val,simGetValue (val-1,'B',2));
1948     fprintf(stdout,"PSW : 0x%02X | CY : %c | AC : %c | OV : %c | P : %c\n",
1949             i,(i&0x80)?'1':'0',(i&0x40)?'1':'0',(i&4)?'1':'0',(i&1)?'1':'0');
1950     if ( all )
1951     {
1952         fprintf(stdout,"Special Function Registers:\n");
1953         r = regaddrs;
1954         for ( i = 0x80 ; i < 0x100 ; i++ )
1955         {
1956             symbol *sym = NULL;
1957             if ( *r && *r == i )
1958             {
1959                 /* skip normal registers */
1960                 r++ ;
1961                 continue;
1962             }
1963             if (applyToSetFTrue(sfrsymbols,symWithAddr,i,'I',&sym))
1964             {
1965                 val = simGetValue (sym->addr,sym->addrspace,sym->size);
1966                 fprintf(stdout,"%s : 0x%02lx",sym->name,val);
1967                 if ( !(i & 0x07 ))
1968                 {
1969                     for ( j = 0 ; j < 8 ; j++ )
1970                     {
1971                         sym = NULL;
1972                         if (applyToSetFTrue(sfrsymbols,symWithAddr,i+j,'J',&sym))
1973                         {
1974                             //val = simGetValue (sym->addr,sym->addrspace,sym->size);
1975                             fprintf(stdout," %s=%c",sym->name,(val&1)? '1':'0');
1976                         }
1977                         val >>= 1;
1978                     }
1979                 }
1980                 fprintf(stdout,"\n");
1981             }
1982         }
1983     }
1984 }
1985
1986 /*-----------------------------------------------------------------*/
1987 /* infoStack - print call stack information                        */
1988 /*-----------------------------------------------------------------*/
1989 static void infoStack(context *ctxt)
1990 {
1991     function *func ;
1992     int i = 0 ;
1993
1994     STACK_STARTWALK(callStack) ;
1995     while ((func = STACK_WALK(callStack))) {
1996     Dprintf(D_break, ("break: infoStack: %s %p (%p)\n",func->sym->name, w_callStack,p_callStack));
1997
1998         fprintf(stdout,"#%d  0x%08x in %s () at %s:%d\n",i++,
1999                 func->laddr,func->sym->name,
2000                 func->mod->c_name,func->lline+1);
2001     }
2002     if ( !i )
2003         fprintf(stdout,"no stack.\n");
2004 }
2005
2006 /*-----------------------------------------------------------------*/
2007 /* cmdWhere -  where command                                       */
2008 /*-----------------------------------------------------------------*/
2009 int cmdWhere(char *s, context *cctxt)
2010 {
2011         infoStack(cctxt);
2012         return 0;
2013 }
2014
2015
2016 static int infomode = 0;
2017 /*-----------------------------------------------------------------*/
2018 /* cmdInfo - info command                                          */
2019 /*-----------------------------------------------------------------*/
2020 int cmdInfo (char *s, context *cctxt)
2021 {
2022     /* trim left and_right*/
2023     s = trim(s);
2024
2025     /* list all break points */
2026     if (strncmp(s,"break",5) == 0) {
2027         listUSERbp();
2028         return 0;
2029     }
2030
2031     /* info frame same as frame */
2032     if (strncmp(s,"frame",5) == 0) {
2033         cmdFrame (s+5,cctxt);
2034         return 0;
2035     }
2036
2037     if (strncmp(s,"line",4) == 0) {
2038         infomode=1;
2039         cmdListSrc (s+4,cctxt);
2040         return 0;
2041     }
2042     if (strncmp(s,"source",6) == 0)
2043     {
2044         module *m;
2045         if ( s[6] == 's' )
2046         {
2047             int k = 0;
2048             fprintf(stdout,"Source files for which symbols have been read in:\n\n");
2049             for (m = setFirstItem(modules); m ; m = setNextItem(modules))
2050             {
2051                 fprintf(stdout,"%s%s, %s",k ? ", ":"",m->cfullname, m->afullname);
2052                 k = 1;
2053             }
2054             fprintf(stdout,"\n");
2055         }
2056         else
2057         {
2058             if (!cctxt || !cctxt->func || !cctxt->func->mod)
2059             {
2060                 fprintf(stdout,"No source file loaded\n");
2061                 return 0;
2062             }
2063             m = cctxt->func->mod;
2064             fprintf(stdout,"Current source file is %s\n",m->c_name);
2065             fprintf(stdout,"Located in %s\n",m->cfullname);
2066             fprintf(stdout,"Contains %d lines.\nSource language is c.\n",
2067                     m->ncLines);
2068         }
2069         return 0;
2070     }
2071     if (strcmp(s,"functions") == 0)
2072     {
2073         function *f;
2074         module *m = NULL;
2075         fprintf(stdout,"All defined functions:\n");
2076         for ( f = setFirstItem(functions); f ; f = setNextItem(functions))
2077         {
2078             if ( f->mod != m )
2079             {
2080                 m = f->mod;
2081                 fprintf(stdout,"\nFile %s\n", m->c_name);
2082             }
2083             fprintf(stdout,"%s();\n",f->sym->name);
2084         }
2085         return 0;
2086     }
2087     /* info stack display call stack */
2088     if (strcmp(s,"stack") == 0) {
2089         infoStack(cctxt);
2090         showfull = 1;
2091         return 0;
2092     }
2093
2094     /* info stack display call stack */
2095     if (strcmp(s,"registers") == 0) {
2096         infoRegisters(0,cctxt);
2097             return 0;
2098     }
2099
2100     /* info stack display call stack */
2101     if (strcmp(s,"all-registers") == 0)
2102     {
2103         infoRegisters(1,cctxt);
2104         return 0;
2105     }
2106
2107     /* info stack display call stack */
2108     if (strcmp(s,"symbols") == 0) {
2109       /* dump out symbols we have read in */
2110       fprintf(stdout,"Dumping symbols...\n");
2111       infoSymbols(cctxt);
2112       return 0;
2113     }
2114
2115     if (strcmp(s,"variables") == 0) {
2116       /* dump out symbols we have read in */
2117       fprintf(stdout,"Dumping symbols...\n");
2118       infoSymbols(cctxt);
2119       return 0;
2120     }
2121
2122     fprintf(stdout,"Undefined info command: \"%s\".  Try \"help\n",s);
2123     return 0;
2124
2125 }
2126
2127 /*-----------------------------------------------------------------*/
2128 /* cmdQuit  - quit debugging                                       */
2129 /*-----------------------------------------------------------------*/
2130 int cmdQuit (char *s, context *cctxt)
2131 {
2132     if (simactive)
2133         closeSimulator();
2134     return 1;
2135 }
2136
2137 /*-----------------------------------------------------------------*/
2138 /* cmdListSrc  - list src                                          */
2139 /*-----------------------------------------------------------------*/
2140 int cmdListSrc (char *s, context *cctxt)
2141 {
2142     static int currline = 0;
2143     int i =0 ;
2144     int pline = 0;
2145     int llines = listlines;
2146     function *func = NULL;
2147
2148
2149     s = trim_left(s);
2150
2151     /* if the user has spcified line numer then the line number
2152        can be of the following formats
2153        LINE          - just line number
2154        FILE:LINE     - filename line number
2155        FILE:LINE,LASTLINE  + last line
2156        FUNCTION      - list a function
2157        FILE:FUNCTION - function in file */
2158
2159     if (*s) {
2160         /* case a) LINE */
2161         if (isdigit(*s)) {
2162             if (!cctxt || !cctxt->func || !cctxt->func->mod) {
2163               if (!list_mod) {
2164                 fprintf(stdout,"Sdcdb fails to have a proper context at %d.\n", __LINE__);
2165                 return 0;
2166               }
2167             }
2168             else
2169               list_mod = cctxt->func->mod;
2170         pline = strtol(s,&s,10) - 1;
2171         if (s && (s = strchr(s,',')))
2172         {
2173             /* LINE,LASTLINE */
2174             llines = strtol(s+1,0,10);
2175             if ( llines > 0 )
2176                 llines -= pline+1;
2177             else
2178                 llines = listlines;
2179         }
2180         }
2181         else {
2182             char *bp;
2183
2184             /* if ':' present then FILE:LINE || FILE:FUNCTION */
2185             if ((bp = strchr(s,':'))) {
2186                 *bp = '\0';
2187                 bp ++;
2188                 if (isdigit(*bp)) {
2189                     /* FILE:LINE */
2190                     list_mod=NULL;  /* bug fix 2-09-02, moduleWithCName expects mod to be null */
2191                     if (srcMode == SRC_CMODE) {
2192                         if (!applyToSet(modules,moduleWithCName,s,&list_mod)) {
2193                             fprintf (stderr,"No c source file named %s.\n",s);
2194                             return 0;
2195                         }
2196                     } else {
2197                         if (!applyToSet(modules,moduleWithAsmName,s,&list_mod)) {
2198                             fprintf (stderr,"No source file named %s.\n",s);
2199                             return 0;
2200                         }
2201                     }
2202                     pline = strtol(bp,&bp,10) - 1;
2203             if (bp && (bp = strchr(bp,',')))
2204             {
2205                 /* FILE:LINE,LASTLINE */
2206                 llines = strtol(bp+1,0,10);
2207                 if ( llines > 0 )
2208                     llines -= pline+1;
2209                 else
2210                     llines = listlines;
2211             }
2212                 } else {
2213                     /* FILE:FUCTION */
2214                     if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) {
2215                         fprintf(stdout,"Function \"%s\" not defined.\n",bp);
2216                         return 0;
2217                     }
2218                     list_mod = func->mod;
2219                     if (srcMode == SRC_CMODE) {
2220                         pline = func->entryline;
2221                         llines = func->exitline - func->entryline + 1;
2222                     } else {
2223                         pline = func->aentryline;
2224                         llines = func->aexitline - func->aentryline + 1;
2225                     }
2226                 }
2227             }
2228             else {
2229                 /* FUNCTION */
2230             if (*s == '\'')
2231             {
2232                 /* 'FUNCTION' */
2233                 s++ ;
2234                 if ((bp = strrchr(s,'\'')))
2235                 {
2236                     *bp = '\0';
2237                 }
2238
2239             }
2240                 if (!applyToSet(functions,funcWithName,s,&func)) {
2241                     fprintf(stderr,"Function \"%s\" not defined.\n",s);
2242                     return 0;
2243                 }
2244                 else {
2245                     list_mod = func->mod;
2246                     if (srcMode == SRC_CMODE) {
2247                         pline = func->entryline;
2248                         llines = func->exitline - func->entryline + 1;
2249                     } else {
2250                         pline = func->aentryline;
2251                         llines = func->aexitline - func->aentryline + 1;
2252                     }
2253                 }
2254             }
2255         }
2256     } else {
2257         /* if no line specified & we had listed
2258            before then continue from that listing */
2259         if (currline)
2260             pline = currline ;
2261         else {
2262             if (!cctxt || !cctxt->func || !cctxt->func->mod) {
2263               fprintf(stdout,"Missing context at %d. Try list filename:lineno\n", __LINE__);
2264               return 0;
2265             }
2266             list_mod = cctxt->func->mod;
2267             if (srcMode == SRC_CMODE)
2268                 pline = cctxt->cline;
2269             else
2270                 pline = cctxt->asmline;
2271         }
2272     }
2273
2274     if (!list_mod) {
2275       fprintf(stdout,"Sdcdb fails to have a valid module context at %d.\n", __LINE__);
2276       return 0;
2277     }
2278
2279     if ( pline < 0 )
2280         return 0;
2281     if ( infomode )
2282     {
2283         unsigned firstaddr , lastaddr ;
2284             if ( pline  >= list_mod->ncLines )
2285             pline = cctxt->cline;
2286         firstaddr = lastaddr = list_mod->cLines[pline]->addr;
2287         if (!func && cctxt && cctxt->func )
2288             func = cctxt->func;
2289             fprintf(stdout,"Line %d of \"%s\" starts at address 0x%08x <%s+%d>",
2290                 pline+1,
2291                 list_mod->c_name, lastaddr,
2292                 func ? func->sym->name : "?",
2293                 func ? lastaddr -func->sym->addr : 0);
2294         llines = pline +1;
2295         for ( ; pline < list_mod->ncLines; pline++ )
2296         {
2297             if ( list_mod->cLines[pline]->addr > lastaddr )
2298             {
2299                 lastaddr = list_mod->cLines[pline]->addr -1;
2300                 break;
2301             }
2302         }
2303         fprintf(stdout," and ends at 0x%08x <%s+%d>.\n",
2304                 lastaddr,
2305                 func ? func->sym->name : "?",
2306                 func ? lastaddr -func->sym->addr : 0);
2307         infomode=0;
2308         if ( func )
2309             fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
2310                     func->mod->cfullname,
2311                     llines,firstaddr);
2312         else
2313             showfull=1;
2314         return 0;
2315     }
2316     for ( i = 0 ; i < llines ; i++ ) {
2317         if (srcMode == SRC_CMODE) {
2318             if ( (pline + i) >= list_mod->ncLines )
2319                 break;
2320             fprintf(stdout,"%d\t%s",pline + i,
2321                     list_mod->cLines[pline +i]->src);
2322         } else {
2323             if ( (pline + i) >= list_mod->nasmLines )
2324                 break;
2325             fprintf(stdout,"%d\t%s",pline + i,
2326                     list_mod->asmLines[pline +i]->src);
2327         }
2328     }
2329     currline = pline + i ;
2330     return 0;
2331 }
2332
2333 static unsigned long getValBasic(symbol *sym, link *type, char *val)
2334 {
2335     char *s;
2336     union
2337     {
2338         float f;
2339         unsigned long val;
2340         long         sval;
2341         struct {
2342             unsigned short    lo;
2343             unsigned short    hi;
2344         } i;
2345         unsigned char b[4];
2346     }v;
2347
2348     if (IS_FLOAT(type))
2349         v.f = strtod(val,NULL);
2350     else
2351         if (IS_PTR(type))
2352             v.val = strtol(val,NULL,0);
2353         else
2354     {
2355             if (IS_INTEGRAL(type))
2356         {
2357             link *etype;
2358             if ( type->next )
2359                 etype = type->next;
2360             else
2361                 etype = type;
2362             if (IS_CHAR(etype))
2363             {
2364                 if (( s = strchr(val,'\'')))
2365                 {
2366                     if ( s[1] == '\\' )
2367                         v.b[0] = strtol(s+2,NULL,8);
2368                     else
2369                         v.b[0] = s[1];
2370                 }
2371                 else
2372                 {
2373                     v.b[0] = strtol(val,NULL,0);
2374                 }
2375             }
2376             else
2377                 if (IS_INT(etype))
2378                     if (IS_LONG(etype))
2379                         v.val = strtol(val,NULL,0);
2380                     else
2381                         v.i.lo = strtol(val,NULL,0);
2382                 else
2383                     v.val = strtol(val,NULL,0);
2384             }
2385         else
2386             v.val = strtol(val,NULL,0);
2387     }
2388     return v.val;
2389 }
2390
2391 /*-----------------------------------------------------------------*/
2392 /* printFmtInteger - print value in bin,oct,dez or hex             */
2393 /*-----------------------------------------------------------------*/
2394 static void printFmtInteger(char *deffmt,int fmt, long val,
2395                             int sign, int size)
2396 {
2397     static char digits[] =
2398     {
2399         '0' , '1' , '2' , '3' , '4' , '5' ,
2400         '6' , '7' , '8' , '9' , 'a' , 'b' ,
2401         'c' , 'd' , 'e' , 'f' , 'g' , 'h'
2402     };
2403     static int radixOfFormat[] = { 0 , 2, 8 ,10, 16  };
2404     static int olenOfSize[]    = { 0 , 3, 6 , 8, 11  };
2405         char buf[40];
2406         char negative = 0;
2407         int charPos = 38;
2408     int radix;
2409
2410     if ( fmt == FMT_NON || fmt == FMT_DEZ )
2411     {
2412         fprintf(stdout,deffmt,val);
2413         return;
2414     }
2415     radix = radixOfFormat[fmt];
2416
2417     /*
2418     if ( sign && val < 0 )
2419         negative = 1;
2420     */
2421
2422         if (!negative)
2423             val = -val;
2424
2425         buf[39] = '\0';
2426     while (val <= -radix)
2427     {
2428             buf[charPos--] = digits[-(val % radix)];
2429             val = val / radix;
2430         }
2431         buf[charPos] = digits[-val];
2432
2433     switch ( fmt )
2434     {
2435         case FMT_OCT:
2436             radix = olenOfSize[size];
2437             break;
2438         case FMT_HEX:
2439             radix = size << 1;
2440             break;
2441         case FMT_BIN:
2442             radix = size << 3;
2443             break;
2444     }
2445
2446     while (charPos > 39 - radix )
2447     {
2448         buf[--charPos] = '0';
2449     }
2450     switch ( fmt )
2451     {
2452         case FMT_OCT:
2453             if ( buf[charPos] != '0' )
2454                 buf[--charPos] = '0';
2455             break;
2456         case FMT_HEX:
2457             buf[--charPos] = 'x';
2458             buf[--charPos] = '0';
2459             break;
2460     }
2461         if (negative) {
2462             buf[--charPos] = '-';
2463         }
2464     fputs(&buf[charPos],stdout);
2465 }
2466
2467 /*-----------------------------------------------------------------*/
2468 /* printValBasic - print value of basic types                      */
2469 /*-----------------------------------------------------------------*/
2470 static void printValBasic(symbol *sym, link *type,
2471                           char mem, unsigned addr,int size, int fmt)
2472 {
2473     union {
2474         float f;
2475         unsigned long val;
2476         long         sval;
2477         struct {
2478             unsigned short    lo;
2479             unsigned short    hi;
2480         } i;
2481         unsigned char b[4];
2482     }v;
2483
2484     v.val = simGetValue(addr,mem,size);
2485     /* if this a floating point number then */
2486     if (IS_FLOAT(type))
2487         fprintf(stdout,"%f",v.f);
2488     else
2489         if (IS_PTR(type))
2490             fprintf(stdout,"0x%0*lx",size<<1,v.val);
2491         else
2492         if (IS_INTEGRAL(type))
2493         {
2494             link *etype;
2495             if ( type->next )
2496                 etype = type->next;
2497             else
2498                 etype = type;
2499             if (IS_CHAR(etype))
2500             {
2501                 if ( isprint(v.val))
2502                     printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'%c'"),
2503                                     fmt,(long)v.val,0,size);
2504                 else
2505                     printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'\\%o'"),
2506                                     fmt,(long)v.val,0,size);
2507             }
2508             else
2509             {
2510                 if (IS_INT(etype))
2511                     if (IS_LONG(etype))
2512                         if (SPEC_USIGN(etype))
2513                             printFmtInteger("%u",fmt,(long)v.val,0,size);
2514                         else
2515                             printFmtInteger("%d",fmt,(long)v.sval,1,size);
2516                     else
2517                         if (SPEC_USIGN(etype))
2518                             printFmtInteger("%u",fmt,(long)v.i.lo,0,size);
2519                         else
2520                             printFmtInteger("%d",fmt,(long)v.i.lo,1,size);
2521                 else
2522                 {
2523                     if (IS_BITVAR(etype))
2524                         fprintf(stdout,"%c",(v.val?'1':'0'));
2525                     else
2526                         fprintf(stdout,"0x%0*lx",size<<1,v.val);
2527                 }
2528             }
2529             } else
2530             fprintf(stdout,"0x%0*lx",size<<1,v.val);
2531 }
2532
2533 /*-----------------------------------------------------------------*/
2534 /* printValFunc  - prints function values                          */
2535 /*-----------------------------------------------------------------*/
2536 static void printValFunc (symbol *sym, int fmt)
2537 {
2538     fprintf(stdout,"print function not yet implemented");
2539 }
2540
2541 static void
2542 do_indent(int indent) {
2543     while (indent--)
2544         fprintf(stdout, "  ");
2545
2546 }
2547
2548 /*-----------------------------------------------------------------*/
2549 /* printArrayValue - will print the values of array elements       */
2550 /*-----------------------------------------------------------------*/
2551 static void printArrayValue (symbol *sym,  link *type,
2552                              char space, unsigned int addr, int fmt,
2553                              int indent)
2554 {
2555     link *elem_type = type->next;
2556     int i;
2557     int col;
2558
2559     fprintf(stdout,"{");
2560     for (i = 0 ; i < DCL_ELEM(type) ; i++) {
2561         if (IS_AGGREGATE(elem_type)) {
2562             printValAggregates(sym,elem_type,space,addr,fmt,indent);
2563             col = 0;
2564         } else {
2565             printValBasic(sym,elem_type,space,addr,getSize(elem_type),fmt);
2566             col++;
2567         }
2568         addr += getSize(elem_type);
2569         if (i != DCL_ELEM(type) -1) {
2570             fprintf(stdout,",");
2571             if (col == 16) {
2572                 fprintf(stdout,"\n");
2573                 do_indent(indent);
2574                 col = 0;
2575             }
2576         }
2577     }
2578
2579     fprintf(stdout,"}");
2580 }
2581
2582 /*-----------------------------------------------------------------*/
2583 /* printStructValue - prints structures elements                   */
2584 /*-----------------------------------------------------------------*/
2585 static void printStructValue (symbol *sym, link *type,
2586                               char space, unsigned int addr, int fmt,
2587                               int indent)
2588 {
2589     symbol *fields = SPEC_STRUCT(type)->fields;
2590     int first = 1;
2591     do_indent (indent);
2592     fprintf(stdout,"{\n");
2593     while (fields) {
2594         do_indent(indent + 1);
2595         fprintf(stdout,"%s = ", fields->name);
2596         first = 0;
2597         if (IS_AGGREGATE(fields->type)) {
2598             printValAggregates(fields,fields->type,space, addr, fmt, indent + 1);
2599         } else {
2600             printValBasic(fields,fields->type,space,addr,getSize(fields->type), fmt);
2601         }
2602         fprintf(stdout,",\n");
2603         addr += getSize(fields->type);
2604         fields = fields->next;
2605     }
2606     do_indent(indent);
2607     fprintf(stdout,"}");
2608 }
2609
2610 /*-----------------------------------------------------------------*/
2611 /* printValAggregates - print value of aggregates                  */
2612 /*-----------------------------------------------------------------*/
2613 static void printValAggregates (symbol *sym, link *type,
2614                                 char space,unsigned int addr, int fmt,
2615                                 int indent)
2616 {
2617
2618         if (IS_ARRAY(type)) {
2619                 printArrayValue(sym, type, space, addr, fmt, indent);
2620                 return ;
2621         }
2622
2623         if (IS_STRUCT(type)) {
2624                 printStructValue(sym, type, space, addr, fmt, indent);
2625                 return;
2626         }
2627 }
2628
2629 /*-----------------------------------------------------------------*/
2630 /* printOrSetSymValue - print or set value of a symbol             */
2631 /*-----------------------------------------------------------------*/
2632 static int printOrSetSymValue (symbol *sym, context *cctxt,
2633                                 int flg, int dnum, int fmt, char *rs,
2634                                 char *val, char cmp )
2635 {
2636     static char fmtChar[] = " todx ";
2637     static int stack = 1;
2638         symbol *fields;
2639     link *type;
2640     unsigned int  addr;
2641     int size, n;
2642     char *s, *s2;
2643     char save_ch, save_ch2;
2644     int get_member = 0;
2645
2646     /* if it is on stack then compute address & fall thru */
2647     if (sym->isonstack)
2648     {
2649         symbol *bp = symLookup("bp",cctxt);
2650         if (!bp)
2651         {
2652             fprintf(stdout,"cannot determine stack frame\n");
2653             return 1;
2654         }
2655
2656         sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
2657             + sym->offset ;
2658     }
2659
2660     /* get the value from the simulator and
2661        print it */
2662     switch (flg)
2663     {
2664         case 0:
2665         default:
2666             break;
2667         case 1:
2668             fprintf(stdout,"$%d = ",stack++);
2669             break;
2670         case 2:
2671             fprintf(stdout,"%d: ", dnum);
2672             if ( fmt != FMT_NON )
2673                 fprintf(stdout,"/%c ",fmtChar[fmt]);
2674             fprintf(stdout,"%s%s = ",sym->name,rs);
2675             break;
2676     }
2677
2678     addr = sym->addr;
2679     type = sym->type;
2680     size = sym->size;
2681
2682     while ( *rs )
2683     {
2684         if ( *rs == '[' && (IS_ARRAY(type) || IS_PTR(type)))
2685         {
2686             s = rs+1;
2687             while ( *rs && *rs != ']' ) rs++ ;
2688             save_ch = *rs;
2689             *rs = '\0' ;
2690             if ( ! isdigit(*s ))
2691             {
2692                 /* index seems a variable */
2693                 for ( s2 = s; *s2 && ( isalnum( *s2 ) || *s2 == '_'); s2++ );
2694                 save_ch2 = *s2;
2695                 if ( *s2 )
2696                     *s2 = '\0';
2697                 fields = symLookup(s,cctxt);
2698                 *s2 = save_ch2;
2699                 if ( ! fields )
2700                 {
2701                     fprintf(stdout,"Unknown variable \"%s\" for index.\n", s);
2702                     return 1;
2703                 }
2704                 /* arrays & structures first */
2705                 if (! IS_INTEGRAL(fields->type))
2706                 {
2707                     fprintf(stdout,"Wrong type of variable \"%s\" for index \n", s);
2708                     return 1;
2709                 }
2710                 n = simGetValue(fields->addr,fields->addrspace,getSize(fields->type));
2711             }
2712             else
2713             {
2714                 n = strtol(s,0,0);
2715             }
2716             if ( IS_ARRAY(type) && (n < 0 || n >= DCL_ELEM(type)))
2717             {
2718                 fprintf(stdout,"Wrong index %d.\n", n);
2719                 return 1;
2720             }
2721             if (IS_PTR(type))
2722                 addr = simGetValue(addr, sym->addrspace, size);
2723             type = type->next;
2724             size = getSize(type);
2725             addr += size * n;
2726             *rs++ = save_ch;
2727         }
2728         else if ( (*rs == '.' || get_member) && IS_STRUCT(type))
2729         {
2730             s = rs+1;
2731             /* search structure element */
2732             for ( rs = s; *rs && ( isalnum( *rs ) || *rs == '_'); rs++ );
2733             save_ch = *rs;
2734             if ( *rs )
2735                 *rs = '\0';
2736             for (fields = SPEC_STRUCT(type)->fields; fields; fields = fields->next)
2737             {
2738                 if (!(strcmp(s,fields->name)))
2739                     break;
2740             }
2741             *rs = save_ch;
2742             if ( ! fields )
2743             {
2744                 fprintf(stdout,"Unknown field \"%s\" of structure\n", s);
2745                 return 1;
2746             }
2747             type = fields->type;
2748             size = getSize(type);
2749             addr += fields->offset;
2750         }
2751         else if ( *rs == '*' && IS_PTR(type))
2752         {
2753             addr = simGetValue(addr, sym->addrspace, size);
2754             type = type->next;
2755             size = getSize(type);
2756             rs++;
2757         }
2758         else if ( rs[0] == '-' && rs[1] == '>' &&
2759                  IS_PTR(type) && IS_STRUCT(type->next))
2760         {
2761             addr = simGetValue(addr, sym->addrspace, size);
2762             type = type->next;
2763             size = getSize(type);
2764             rs++;
2765             get_member = 1;
2766             continue;
2767         }
2768         else
2769             break;
2770         get_member = 0;
2771     }
2772
2773     /* arrays & structures first */
2774     if (IS_AGGREGATE(type))
2775     {
2776             if ( val )
2777         {
2778             fprintf(stdout,"Cannot set/compare aggregate variable\n");
2779             return 1;
2780         }
2781         else
2782             printValAggregates(sym,type,sym->addrspace,addr,fmt,0);
2783     }
2784     else
2785         /* functions */
2786         if (IS_FUNC(type))
2787     {
2788             if ( !val )
2789             printValFunc(sym,fmt);
2790         else
2791             return 1;
2792     }
2793         else
2794     {
2795             if ( val )
2796         {
2797             unsigned long newval;
2798             newval = getValBasic(sym,type,val);
2799
2800             if ( cmp )
2801             {
2802                 unsigned long lval;
2803                 lval = simGetValue(addr,sym->addrspace,size);
2804                 switch ( cmp )
2805                 {
2806                     case '<' : return ( lval <  newval ? 1:0 ); break;
2807                     case '>' : return ( lval >  newval ? 1:0 ); break;
2808                     case 'l' : return ( lval <= newval ? 1:0 ); break;
2809                     case 'g' : return ( lval >= newval ? 1:0 ); break;
2810                     case '=' : return ( lval == newval ? 1:0 ); break;
2811                     case '!' : return ( lval != newval ? 1:0 ); break;
2812                 }
2813             }
2814             else
2815             {
2816                 if ( sym->addrspace == 'I' && addr == 0xb8 )
2817                 {
2818                     /* Symbol with address of IP */
2819                     if ( cctxt ) cctxt->addr = newval;
2820                     simSetPC(cctxt->addr);
2821                 }
2822                 else
2823                     simSetValue(addr,sym->addrspace,size,newval);
2824                 return 1;
2825             }
2826         }
2827         else
2828             printValBasic(sym,type,sym->addrspace,addr,size,fmt);
2829     }
2830     if ( flg > 0 ) fprintf(stdout,"\n");
2831         return 0;
2832 }
2833
2834 /*-----------------------------------------------------------------*/
2835 /* printStructInfo - print out structure information               */
2836 /*-----------------------------------------------------------------*/
2837 static void printStructInfo (structdef *sdef)
2838 {
2839     symbol *field = sdef->fields ;
2840     int i = 0 ;
2841
2842     while (field) {
2843         i += field->offset;
2844         field = field->next;
2845     }
2846
2847     fprintf(stdout,"%s %s {\n",(i ? "struct" : "union" ), sdef->tag);
2848     field = sdef->fields;
2849     while (field) {
2850         printTypeInfo (field->type);
2851         fprintf(stdout," %s ;\n",field->name);
2852         field = field->next ;
2853     }
2854
2855     fprintf(stdout,"}\n");
2856
2857 }
2858
2859 /*-----------------------------------------------------------------*/
2860 /* printTypeInfo - print out the type information                  */
2861 /*-----------------------------------------------------------------*/
2862 static void printTypeInfo(link *p)
2863 {
2864     if (!p)
2865         return ;
2866
2867     if (IS_DECL(p)) {
2868         switch (DCL_TYPE(p))  {
2869         case FUNCTION:
2870             printTypeInfo (p->next);
2871             fprintf(stdout,"()");
2872             break;
2873         case ARRAY:
2874             printTypeInfo (p->next);
2875             fprintf(stdout,"[%d]",DCL_ELEM(p));
2876             break;
2877
2878         case IPOINTER:
2879         case PPOINTER:
2880         case POINTER:
2881             printTypeInfo (p->next);
2882             fprintf(stdout,"(_near *)");
2883             break;
2884
2885         case FPOINTER:
2886             printTypeInfo (p->next);
2887             fprintf(stdout,"(_xdata *)");
2888             break;
2889
2890         case CPOINTER:
2891             printTypeInfo( p->next);
2892             fprintf(stdout,"(_code *)");
2893             break;
2894
2895         case GPOINTER:
2896             printTypeInfo( p->next);
2897             fprintf(stdout,"(_generic *)");
2898             break;
2899         }
2900     } else {
2901         switch (SPEC_NOUN(p)) { /* depending on the specifier type */
2902         case V_INT:
2903             (IS_LONG(p) ? fputs("long ",stdout) :
2904              ( IS_SHORT(p) ? fputs("short ",stdout) :
2905                fputs("int ",stdout))) ;
2906             break;
2907         case V_FLOAT:
2908              fputs("float ",stdout);
2909              break;
2910
2911         case V_CHAR:
2912             fputs ("char ",stdout);
2913             break;
2914
2915         case V_VOID:
2916             fputs("void ",stdout);
2917             break;
2918
2919         case V_STRUCT:
2920             printStructInfo (SPEC_STRUCT(p));
2921             break;
2922
2923         case V_SBIT:
2924             fputs("sbit ",stdout);
2925             break;
2926
2927         case V_BIT:
2928             fprintf(stdout,": %d" ,SPEC_BLEN(p));
2929             break;
2930         }
2931     }
2932 }
2933
2934 /*-----------------------------------------------------------------*/
2935 /* conditionIsTrue - compare variable with constant value        */
2936 /*-----------------------------------------------------------------*/
2937 int conditionIsTrue( char *s, context *cctxt)
2938 {
2939     symbol *sym = NULL;
2940     int fmt;
2941     char *rs, *dup, cmp_char;
2942     dup = s = Safe_strdup(s);
2943     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )) || !sym)
2944         fmt = 1;
2945     else if (!( s =  strpbrk(rs,"<>=!")))
2946         fmt = 1;
2947     else
2948     {
2949         cmp_char = *s;
2950         *s++ = '\0';
2951         if ( *s == '=' )
2952         {
2953             /* if <= or >= an other char is used
2954              * == or !=  not checked in switch
2955              */
2956             switch( cmp_char )
2957             {
2958                 case '>': cmp_char = 'g' ; break;
2959                 case '<': cmp_char = 'l' ; break;
2960             }
2961             s++ ;
2962         }
2963         s = trim_left(s);
2964         fmt = printOrSetSymValue(sym,cctxt,0,0,0,rs,s,cmp_char);
2965     }
2966     Safe_free(dup);
2967     return fmt;
2968 }
2969
2970 /*-----------------------------------------------------------------*/
2971 /* cmdPrint - print value of variable                              */
2972 /*-----------------------------------------------------------------*/
2973 int cmdPrint (char *s, context *cctxt)
2974 {
2975     symbol *sym ;
2976     int fmt;
2977     char *rs;
2978     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
2979         return 0;
2980
2981     if ( sym )
2982     {
2983         printOrSetSymValue(sym,cctxt,1,0,fmt,rs,NULL,'\0');
2984     }
2985     return 0;
2986 }
2987
2988 /*-----------------------------------------------------------------*/
2989 /* cmdOutput - print value of variable without number and newline  */
2990 /*-----------------------------------------------------------------*/
2991 int cmdOutput (char *s, context *cctxt)
2992 {
2993     symbol *sym ;
2994     int fmt;
2995     char *rs;
2996     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
2997         return 0;
2998
2999     if ( sym )
3000     {
3001         printOrSetSymValue(sym,cctxt,0,0,fmt,rs,NULL,'\0');
3002     }
3003     return 0;
3004 }
3005
3006 /** find display entry with this number */
3007
3008 DEFSETFUNC(dsymWithNumber)
3009 {
3010     dsymbol *dsym = item;
3011     V_ARG(int , dnum);
3012     V_ARG(dsymbol **,dsymp);
3013
3014     if ( dsym->dnum == dnum )
3015     {
3016         *dsymp = dsym;
3017         return 1;
3018     }
3019     return 0;
3020 }
3021
3022 /*-----------------------------------------------------------------*/
3023 /* displayAll  - display all valid variables                       */
3024 /*-----------------------------------------------------------------*/
3025 void displayAll(context *cctxt)
3026 {
3027     dsymbol *dsym;
3028     symbol  *sym;
3029     if ( !dispsymbols )
3030         return;
3031     for (dsym = setFirstItem(dispsymbols);
3032          dsym ;
3033          dsym = setNextItem(dispsymbols))
3034     {
3035         if ( (sym = symLookup(dsym->name,cctxt)))
3036             printOrSetSymValue(sym,cctxt,2,dsym->dnum,dsym->fmt,
3037                                dsym->rs,NULL,'\0');
3038     }
3039 }
3040
3041 /*-----------------------------------------------------------------*/
3042 /* cmdDisplay  - display value of variable                         */
3043 /*-----------------------------------------------------------------*/
3044 int cmdDisplay (char *s, context *cctxt)
3045 {
3046     static int dnum = 1;
3047     symbol *sym ;
3048     int fmt;
3049     char *rs;
3050     if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
3051     {
3052         displayAll(cctxt);
3053         return 0;
3054     }
3055
3056     if ( sym )
3057     {
3058         dsymbol *dsym = (dsymbol *)Safe_calloc(1,sizeof(dsymbol));
3059         dsym->dnum = dnum++ ;
3060         dsym->name = sym->name;
3061         dsym->fmt  = fmt;
3062         dsym->rs   = gc_strdup(rs);
3063         addSetHead(&dispsymbols,dsym);
3064     }
3065     return 0;
3066 }
3067
3068 /*-----------------------------------------------------------------*/
3069 /* cmdUnDisplay  - undisplay value of variable                              */
3070 /*-----------------------------------------------------------------*/
3071 int cmdUnDisplay (char *s, context *cctxt)
3072 {
3073     dsymbol *dsym;
3074     int dnum;
3075
3076     s = trim_left(s);
3077     if (!*s)
3078     {
3079         for (dsym = setFirstItem(dispsymbols);
3080              dsym;
3081              dsym = setNextItem(dispsymbols))
3082         {
3083             Safe_free(dsym->rs);
3084             Safe_free(dsym);
3085         }
3086         deleteSet(&dispsymbols);
3087         return 0;
3088     }
3089     while ( s && *s )
3090     {
3091         dnum = strtol(s,&s,10);
3092         if (applyToSetFTrue(dispsymbols,dsymWithNumber,dnum,&dsym))
3093         {
3094             deleteSetItem(&dispsymbols,dsym);
3095             Safe_free(dsym->rs);
3096             Safe_free(dsym);
3097         }
3098         else
3099         {
3100             fprintf(stdout,"Arguments must be display numbers.\n");
3101         }
3102     }
3103     return 0;
3104 }
3105
3106 /*-----------------------------------------------------------------*/
3107 /* cmdPrintType - print type of a variable                         */
3108 /*-----------------------------------------------------------------*/
3109 int cmdPrintType (char *s, context *cctxt)
3110 {
3111     symbol *sym ;
3112
3113     /* trim left and right */
3114     s = trim(s);
3115     if (!*s) return 0;
3116
3117     if ((sym = symLookup(s,cctxt))) {
3118         printTypeInfo(sym->type);
3119         fprintf(stdout,"\n");
3120     } else {
3121         fprintf(stdout,
3122                 "No symbol \"%s\" in current context.\n",
3123                 s);
3124     }
3125     return 0;
3126 }
3127
3128 /*-----------------------------------------------------------------*/
3129 /* cmdClrUserBp - clear user break point                           */
3130 /*-----------------------------------------------------------------*/
3131 int cmdClrUserBp (char *s, context *cctxt)
3132 {
3133     char *bp ;
3134     function *func = NULL;
3135
3136     /* clear break point location specification can be of the following
3137        forms
3138        a) <nothing>        - break point at current location
3139        b) lineno           - number of the current module
3140        c) filename:lineno  - line number of the given file
3141        e) filename:function- function X in file Y (useful for static functions)
3142        f) function         - function entry point
3143     */
3144
3145     if (!cctxt) {
3146         fprintf(stdout,"No symbol table is loaded.  Use the \"file\" command.\n");
3147         return 0;
3148     }
3149
3150     /* trim left and right */
3151     s = trim(s);
3152
3153     /* case a) nothing */
3154     /* if nothing given then current location : we know
3155        the current execution location from the currentContext */
3156     if (! *s ) {
3157
3158         /* if current context is known */
3159         if (cctxt->func)
3160             /* clear the break point @ current location */
3161             clearUSERbp (cctxt->addr);
3162         else
3163             fprintf(stderr,"No default breakpoint address now.\n");
3164
3165         goto ret ;
3166     }
3167
3168     /* case b) lineno */
3169     /* check if line number */
3170     if (isdigit(*s)) {
3171         /* get the lineno */
3172         int line = atoi(s);
3173
3174         /* if current context not present then we must get the module
3175            which has main & set the break point @ line number provided
3176            of that module : if current context known then set the bp
3177            at the line number given for the current module
3178         */
3179         if (cctxt->func) {
3180             if (!cctxt->func->mod) {
3181                 if (!applyToSet(functions,funcWithName,"main"))
3182                     fprintf(stderr,"Function \"main\" not defined.\n");
3183                 else
3184                     clearBPatModLine(func->mod,line);
3185             } else
3186                 clearBPatModLine(cctxt->func->mod,line);
3187         }
3188
3189         goto ret;
3190     }
3191
3192     if ((bp = strchr(s,':'))) {
3193
3194         module *mod = NULL;
3195         *bp = '\0';
3196
3197         if (!applyToSet(modules,moduleWithCName,s,&mod)) {
3198             fprintf (stderr,"No source file named %s.\n",s);
3199             goto ret;
3200         }
3201
3202         /* case c) filename:lineno */
3203         if (isdigit(*(bp +1))) {
3204
3205             clearBPatModLine (mod,atoi(bp+1));
3206             goto ret;
3207
3208         }
3209         /* case d) filename:function */
3210         if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func))
3211             fprintf(stderr,"Function \"%s\" not defined.\n",bp+1);
3212         else
3213             clearBPatModLine (mod,func->entryline);
3214
3215         goto ret;
3216     }
3217
3218     /* case e) function */
3219     if (!applyToSet(functions,funcWithName,s,&func))
3220         fprintf(stderr,"Function \"%s\" not defined.\n",s);
3221     else
3222         clearBPatModLine(func->mod,func->entryline);
3223
3224  ret:
3225     return 0;
3226 }
3227
3228 /*-----------------------------------------------------------------*/
3229 /* cmdSimulator - send command to simulator                        */
3230 /*-----------------------------------------------------------------*/
3231 int cmdSimulator (char *s, context *cctxt)
3232 {
3233   char tmpstr[82];
3234
3235     if (strlen(s) > 80) {
3236       printf("error 3A\n");
3237       exit(1);
3238     }
3239     strcpy(tmpstr, s);
3240     strcat(tmpstr, "\n");
3241     sendSim(tmpstr);
3242     waitForSim(200,NULL);
3243     fprintf(stdout,"%s",simResponse());
3244     return 0;
3245 }
3246
3247 void setMainContext()
3248 {
3249     function *func = NULL;
3250     currentFrame = 0;
3251     if (!applyToSet(functions,funcWithName,"_main",&func) &&
3252         !applyToSet(functions,funcWithName,"main",&func))
3253             return;
3254
3255     discoverContext (func->sym->addr, func);
3256 }
3257
3258 function *needExtraMainFunction()
3259 {
3260     function *func = NULL;
3261     if (!applyToSet(functions,funcWithName,"_main",&func))
3262     {
3263         if (applyToSet(functions,funcWithName,"main",&func))
3264         {
3265             return func;
3266         }
3267     }
3268     return NULL;
3269 }
3270
3271 static void printFrame()
3272 {
3273     int i;
3274     function *func     = NULL;
3275     function *lastfunc = NULL;
3276
3277     if ( currentFrame < 0 )
3278     {
3279         currentFrame = 0;
3280         fprintf(stdout,"Bottom (i.e., innermost) frame selected; you cannot go down.\n");
3281         return;
3282     }
3283     STACK_STARTWALK(callStack) ;
3284     for ( i = 0; i <= currentFrame ; i++ )
3285     {
3286         func = STACK_WALK(callStack);
3287         if ( !func )
3288         {
3289             currentFrame = i-1;
3290             fprintf(stdout,"Initial frame selected; you cannot go up.\n");
3291             return;
3292         }
3293     }
3294     fprintf(stdout,"#%d  0x%08x in %s () at %s:%d\n",
3295             currentFrame,func->laddr,func->sym->name,func->mod->c_name,func->lline+1);
3296     fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
3297             func->mod->cfullname,func->lline+1,func->laddr);
3298
3299     discoverContext (func->laddr, func);
3300 }
3301
3302
3303 /*-----------------------------------------------------------------*/
3304 /* cmdUp -  Up command                                             */
3305 /*-----------------------------------------------------------------*/
3306 int cmdUp(char *s, context *cctxt)
3307 {
3308     s = trim_left(s);
3309     if ( *s )
3310         currentFrame += strtol(s,0,10);
3311     else
3312         currentFrame++ ;
3313
3314     printFrame();
3315         return 0;
3316 }
3317
3318 /*-----------------------------------------------------------------*/
3319 /* cmdDown - down command                                          */
3320 /*-----------------------------------------------------------------*/
3321 int cmdDown(char *s, context *cctxt)
3322 {
3323     s = trim_left(s);
3324     if ( *s )
3325         currentFrame -= strtol(s,0,10);
3326     else
3327         currentFrame-- ;
3328
3329     printFrame();
3330         return 0;
3331 }
3332 /*-----------------------------------------------------------------*/
3333 /* cmdFrame - Frame command                                        */
3334 /*-----------------------------------------------------------------*/
3335 int cmdFrame (char *s, context *cctxt)
3336 {
3337     function *func = NULL;
3338     int framenr = 0;
3339
3340     s = trim_left(s);
3341     if ( *s )
3342         currentFrame = strtol(s,0,10);
3343     printFrame();
3344     return 0;
3345 }
3346
3347 /*-----------------------------------------------------------------*/
3348 /* cmdFinish - exec till end of current function                   */
3349 /*-----------------------------------------------------------------*/
3350 int cmdFinish (char *s, context *ctxt)
3351 {
3352     if (STACK_EMPTY(callStack)) {
3353         fprintf(stdout,"The program is not running.\n");
3354         return 0;
3355     }
3356
3357     if (srcMode == SRC_CMODE) {
3358         setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
3359                        stepBpCB, ctxt->func->mod->c_name,
3360                        ctxt->func->exitline);
3361     } else {
3362         setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
3363                        stepBpCB, ctxt->func->mod->asm_name,
3364                        ctxt->func->aexitline);
3365     }
3366
3367     simGo(-1);
3368     showfull = 1;
3369     return 0;
3370
3371 }
3372
3373
3374 /*-----------------------------------------------------------------*/
3375 /* cmdShow - show command                                          */
3376 /*-----------------------------------------------------------------*/
3377 int cmdShow (char *s, context *cctxt)
3378 {
3379     /* skip white space */
3380     s = trim_left(s);
3381
3382     if (strcmp(s,"copying") == 0) {
3383         fputs(copying,stdout);
3384         return 0;
3385     }
3386
3387     if (strcmp(s,"warranty") == 0) {
3388         fputs(warranty,stdout);
3389         return 0;
3390     }
3391
3392     return 0;
3393 }
3394