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