1 /*-------------------------------------------------------------------------
2 cmd.c - source file for debugger command execution
3 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
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
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.
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.
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 -------------------------------------------------------------------------*/
31 /* default number of lines to list out */
33 static int listlines = LISTLINES;
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;
40 #if defined(__APPLE__) && defined(__MACH__)
42 {" GNU GENERAL PUBLIC LICENSE Version 2"};
43 static char *warranty=
47 " GNU GENERAL PUBLIC LICENSE\n"
48 " Version 2, June 1991\n"
50 " Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n"
51 " 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
52 " Everyone is permitted to copy and distribute verbatim copies\n"
53 " of this license document, but changing it is not allowed.\n"
57 " The licenses for most software are designed to take away your\n"
58 "freedom to share and change it. By contrast, the GNU General Public\n"
59 "License is intended to guarantee your freedom to share and change free\n"
60 "software--to make sure the software is free for all its users. This\n"
61 "General Public License applies to most of the Free Software\n"
62 "Foundation's software and to any other program whose authors commit to\n"
63 "using it. (Some other Free Software Foundation software is covered by\n"
64 "the GNU Library General Public License instead.) You can apply it to\n"
65 "your programs, too.\n"
67 " When we speak of free software, we are referring to freedom, not\n"
68 "price. Our General Public Licenses are designed to make sure that you\n"
69 "have the freedom to distribute copies of free software (and charge for\n"
70 "this service if you wish), that you receive source code or can get it\n"
71 "if you want it, that you can change the software or use pieces of it\n"
72 "in new free programs; and that you know you can do these things.\n"
74 " To protect your rights, we need to make restrictions that forbid\n"
75 "anyone to deny you these rights or to ask you to surrender the rights.\n"
76 "These restrictions translate to certain responsibilities for you if you\n"
77 "distribute copies of the software, or if you modify it.\n"
79 " For example, if you distribute copies of such a program, whether\n"
80 "gratis or for a fee, you must give the recipients all the rights that\n"
81 "you have. You must make sure that they, too, receive or can get the\n"
82 "source code. And you must show them these terms so they know their\n"
85 " We protect your rights with two steps: (1) copyright the software, and\n"
86 "(2) offer you this license which gives you legal permission to copy,\n"
87 "distribute and/or modify the software.\n"
89 " Also, for each author's protection and ours, we want to make certain\n"
90 "that everyone understands that there is no warranty for this free\n"
91 "software. If the software is modified by someone else and passed on, we\n"
92 "want its recipients to know that what they have is not the original, so\n"
93 "that any problems introduced by others will not reflect on the original\n"
94 "authors' reputations.\n"
96 " Finally, any free program is threatened constantly by software\n"
97 "patents. We wish to avoid the danger that redistributors of a free\n"
98 "program will individually obtain patent licenses, in effect making the\n"
99 "program proprietary. To prevent this, we have made it clear that any\n"
100 "patent must be licensed for everyone's free use or not licensed at all.\n"
102 " The precise terms and conditions for copying, distribution and\n"
103 "modification follow.\n"
105 " GNU GENERAL PUBLIC LICENSE\n"
106 " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n"
108 " 0. This License applies to any program or other work which contains\n"
109 "a notice placed by the copyright holder saying it may be distributed\n"
110 "under the terms of this General Public License. The \"Program\", below,\n"
111 "refers to any such program or work, and a \"work based on the Program\"\n"
112 "means either the Program or any derivative work under copyright law:\n"
113 "that is to say, a work containing the Program or a portion of it,\n"
114 "either verbatim or with modifications and/or translated into another\n"
115 "language. (Hereinafter, translation is included without limitation in\n"
116 "the term \"modification\".) Each licensee is addressed as \"you\".\n"
118 "Activities other than copying, distribution and modification are not\n"
119 "covered by this License; they are outside its scope. The act of\n"
120 "running the Program is not restricted, and the output from the Program\n"
121 "is covered only if its contents constitute a work based on the\n"
122 "Program (independent of having been made by running the Program).\n"
123 "Whether that is true depends on what the Program does.\n"
125 " 1. You may copy and distribute verbatim copies of the Program's\n"
126 "source code as you receive it, in any medium, provided that you\n"
127 "conspicuously and appropriately publish on each copy an appropriate\n"
128 "copyright notice and disclaimer of warranty; keep intact all the\n"
129 "notices that refer to this License and to the absence of any warranty;\n"
130 "and give any other recipients of the Program a copy of this License\n"
131 "along with the Program.\n"
133 "You may charge a fee for the physical act of transferring a copy, and\n"
134 "you may at your option offer warranty protection in exchange for a fee.\n"
136 " 2. You may modify your copy or copies of the Program or any portion\n"
137 "of it, thus forming a work based on the Program, and copy and\n"
138 "distribute such modifications or work under the terms of Section 1\n"
139 "above, provided that you also meet all of these conditions:\n"
141 " a) You must cause the modified files to carry prominent notices\n"
142 " stating that you changed the files and the date of any change.\n"
144 " b) You must cause any work that you distribute or publish, that in\n"
145 " whole or in part contains or is derived from the Program or any\n"
146 " part thereof, to be licensed as a whole at no charge to all third\n"
147 " parties under the terms of this License.\n"
149 " c) If the modified program normally reads commands interactively\n"
150 " when run, you must cause it, when started running for such\n"
151 " interactive use in the most ordinary way, to print or display an\n"
152 " announcement including an appropriate copyright notice and a\n"
153 " notice that there is no warranty (or else, saying that you provide\n"
154 " a warranty) and that users may redistribute the program under\n"
155 " these conditions, and telling the user how to view a copy of this\n"
156 " License. (Exception: if the Program itself is interactive but\n"
157 " does not normally print such an announcement, your work based on\n"
158 " the Program is not required to print an announcement.)\n"
160 "These requirements apply to the modified work as a whole. If\n"
161 "identifiable sections of that work are not derived from the Program,\n"
162 "and can be reasonably considered independent and separate works in\n"
163 "themselves, then this License, and its terms, do not apply to those\n"
164 "sections when you distribute them as separate works. But when you\n"
165 "distribute the same sections as part of a whole which is a work based\n"
166 "on the Program, the distribution of the whole must be on the terms of\n"
167 "this License, whose permissions for other licensees extend to the\n"
168 "entire whole, and thus to each and every part regardless of who wrote it.\n"
170 "Thus, it is not the intent of this section to claim rights or contest\n"
171 "your rights to work written entirely by you; rather, the intent is to\n"
172 "exercise the right to control the distribution of derivative or\n"
173 "collective works based on the Program.\n"
175 "In addition, mere aggregation of another work not based on the Program\n"
176 "with the Program (or with a work based on the Program) on a volume of\n"
177 "a storage or distribution medium does not bring the other work under\n"
178 "the scope of this License.\n"
180 " 3. You may copy and distribute the Program (or a work based on it,\n"
181 "under Section 2) in object code or executable form under the terms of\n"
182 "Sections 1 and 2 above provided that you also do one of the following:\n"
184 " a) Accompany it with the complete corresponding machine-readable\n"
185 " source code, which must be distributed under the terms of Sections\n"
186 " 1 and 2 above on a medium customarily used for software interchange; or,\n"
188 " b) Accompany it with a written offer, valid for at least three\n"
189 " years, to give any third party, for a charge no more than your\n"
190 " cost of physically performing source distribution, a complete\n"
191 " machine-readable copy of the corresponding source code, to be\n"
192 " distributed under the terms of Sections 1 and 2 above on a medium\n"
193 " customarily used for software interchange; or,\n"
195 " c) Accompany it with the information you received as to the offer\n"
196 " to distribute corresponding source code. (This alternative is\n"
197 " allowed only for noncommercial distribution and only if you\n"
198 " received the program in object code or executable form with such\n"
199 " an offer, in accord with Subsection b above.)\n"
201 "The source code for a work means the preferred form of the work for\n"
202 "making modifications to it. For an executable work, complete source\n"
203 "code means all the source code for all modules it contains, plus any\n"
204 "associated interface definition files, plus the scripts used to\n"
205 "control compilation and installation of the executable. However, as a\n"
206 "special exception, the source code distributed need not include\n"
207 "anything that is normally distributed (in either source or binary\n"
208 "form) with the major components (compiler, kernel, and so on) of the\n"
209 "operating system on which the executable runs, unless that component\n"
210 "itself accompanies the executable.\n"
212 "If distribution of executable or object code is made by offering\n"
213 "access to copy from a designated place, then offering equivalent\n"
214 "access to copy the source code from the same place counts as\n"
215 "distribution of the source code, even though third parties are not\n"
216 "compelled to copy the source along with the object code.\n"
218 " 4. You may not copy, modify, sublicense, or distribute the Program\n"
219 "except as expressly provided under this License. Any attempt\n"
220 "otherwise to copy, modify, sublicense or distribute the Program is\n"
221 "void, and will automatically terminate your rights under this License.\n"
222 "However, parties who have received copies, or rights, from you under\n"
223 "this License will not have their licenses terminated so long as such\n"
224 "parties remain in full compliance.\n"
226 " 5. You are not required to accept this License, since you have not\n"
227 "signed it. However, nothing else grants you permission to modify or\n"
228 "distribute the Program or its derivative works. These actions are\n"
229 "prohibited by law if you do not accept this License. Therefore, by\n"
230 "modifying or distributing the Program (or any work based on the\n"
231 "Program), you indicate your acceptance of this License to do so, and\n"
232 "all its terms and conditions for copying, distributing or modifying\n"
233 "the Program or works based on it.\n"
235 " 6. Each time you redistribute the Program (or any work based on the\n"
236 "Program), the recipient automatically receives a license from the\n"
237 "original licensor to copy, distribute or modify the Program subject to\n"
238 "these terms and conditions. You may not impose any further\n"
239 "restrictions on the recipients' exercise of the rights granted herein.\n"
240 "You are not responsible for enforcing compliance by third parties to\n"
243 " 7. If, as a consequence of a court judgment or allegation of patent\n"
244 "infringement or for any other reason (not limited to patent issues),\n"
245 "conditions are imposed on you (whether by court order, agreement or\n"
246 "otherwise) that contradict the conditions of this License, they do not\n"
247 "excuse you from the conditions of this License. If you cannot\n"
248 "distribute so as to satisfy simultaneously your obligations under this\n"
249 "License and any other pertinent obligations, then as a consequence you\n"
250 "may not distribute the Program at all. For example, if a patent\n"
251 "license would not permit royalty-free redistribution of the Program by\n"
252 "all those who receive copies directly or indirectly through you, then\n"
253 "the only way you could satisfy both it and this License would be to\n"
254 "refrain entirely from distribution of the Program.\n"
256 "If any portion of this section is held invalid or unenforceable under\n"
257 "any particular circumstance, the balance of the section is intended to\n"
258 "apply and the section as a whole is intended to apply in other\n"
261 "It is not the purpose of this section to induce you to infringe any\n"
262 "patents or other property right claims or to contest validity of any\n"
263 "such claims; this section has the sole purpose of protecting the\n"
264 "integrity of the free software distribution system, which is\n"
265 "implemented by public license practices. Many people have made\n"
266 "generous contributions to the wide range of software distributed\n"
267 "through that system in reliance on consistent application of that\n"
268 "system; it is up to the author/donor to decide if he or she is willing\n"
269 "to distribute software through any other system and a licensee cannot\n"
270 "impose that choice.\n"
272 "This section is intended to make thoroughly clear what is believed to\n"
273 "be a consequence of the rest of this License.\n"
275 " 8. If the distribution and/or use of the Program is restricted in\n"
276 "certain countries either by patents or by copyrighted interfaces, the\n"
277 "original copyright holder who places the Program under this License\n"
278 "may add an explicit geographical distribution limitation excluding\n"
279 "those countries, so that distribution is permitted only in or among\n"
280 "countries not thus excluded. In such case, this License incorporates\n"
281 "the limitation as if written in the body of this License.\n"
283 " 9. The Free Software Foundation may publish revised and/or new versions\n"
284 "of the General Public License from time to time. Such new versions will\n"
285 "be similar in spirit to the present version, but may differ in detail to\n"
286 "address new problems or concerns.\n"
288 "Each version is given a distinguishing version number. If the Program\n"
289 "specifies a version number of this License which applies to it and \"any\n"
290 "later version\", you have the option of following the terms and conditions\n"
291 "either of that version or of any later version published by the Free\n"
292 "Software Foundation. If the Program does not specify a version number of\n"
293 "this License, you may choose any version ever published by the Free Software\n"
296 " 10. If you wish to incorporate parts of the Program into other free\n"
297 "programs whose distribution conditions are different, write to the author\n"
298 "to ask for permission. For software which is copyrighted by the Free\n"
299 "Software Foundation, write to the Free Software Foundation; we sometimes\n"
300 "make exceptions for this. Our decision will be guided by the two goals\n"
301 "of preserving the free status of all derivatives of our free software and\n"
302 "of promoting the sharing and reuse of software generally.\n";
304 static char *warranty=
307 " 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"
308 "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n"
309 "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"
310 "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"
311 "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
312 "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n"
313 "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n"
314 "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"
315 "REPAIR OR CORRECTION.\n"
317 " 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"
318 "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"
319 "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"
320 "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"
321 "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"
322 "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"
323 "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"
324 "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"
325 "POSSIBILITY OF SUCH DAMAGES.\n";
328 static void printTypeInfo(link *);
329 static void printValAggregates (symbol *,link *,char,unsigned int,int,int);
330 static int printOrSetSymValue (symbol *sym, context *cctxt,
331 int flg, int dnum, int fmt,
332 char *rs, char *val, char cmp);
334 int srcMode = SRC_CMODE ;
335 set *dispsymbols = NULL ; /* set of displayable symbols */
336 static int currentFrame = 0; /* actual displayed frame */
337 /*-----------------------------------------------------------------*/
338 /* funcWithName - returns function with name */
339 /*-----------------------------------------------------------------*/
340 DEFSETFUNC(funcWithName)
342 function *func = item;
344 V_ARG(function **,funcp);
349 if (strcmp(func->sym->name,name) == 0) {
357 /*-----------------------------------------------------------------*/
358 /* symWithAddr - look for symbol with sfr / sbit address */
359 /*-----------------------------------------------------------------*/
360 DEFSETFUNC(symWithAddr)
363 V_ARG(unsigned long,laddr);
364 V_ARG(int ,laddrspace);
365 V_ARG(symbol **,rsym);
370 if ( sym->addr == laddr &&
371 sym->addrspace == laddrspace )
380 /*-----------------------------------------------------------------*/
381 /* setBPatModLine - set break point at the line specified for the */
382 /*-----------------------------------------------------------------*/
383 static void setBPatModLine (module *mod, int line, char bpType )
387 /* look for the first executable line after the line
388 specified & get the break point there */
393 if (srcMode == SRC_CMODE && line > mod->ncLines) {
394 fprintf(stderr,"No line %d in file \"%s\".\n",
399 if (srcMode == SRC_AMODE && line > mod->nasmLines) {
400 fprintf(stderr,"No line %d in file \"%s\".\n",
406 for ( ; next_line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ;
408 if (srcMode == SRC_CMODE) {
409 if (mod->cLines[next_line]->addr != INT_MAX) {
410 setBreakPoint (mod->cLines[next_line]->addr, CODE, bpType,
411 userBpCB, mod->c_name, next_line);
417 if (mod->asmLines[next_line]->addr != INT_MAX) {
418 setBreakPoint (mod->asmLines[next_line]->addr, CODE, bpType,
419 userBpCB, mod->asm_name, next_line);
426 fprintf(stderr,"No line %d or after in file \"%s\"..\n",
432 /*-----------------------------------------------------------------*/
433 /* clearBPatModLine - clr break point at the line specified */
434 /*-----------------------------------------------------------------*/
435 static void clearBPatModLine (module *mod, int line)
437 /* look for the first executable line after the line
438 specified & get the break point there */
439 if (srcMode == SRC_CMODE && line > mod->ncLines) {
440 fprintf(stderr,"No line %d in file \"%s\".\n",
445 if (srcMode == SRC_AMODE && line > mod->ncLines) {
446 fprintf(stderr,"No line %d in file \"%s\".\n",
451 for ( ; line < (srcMode == SRC_CMODE ? mod->ncLines : mod->nasmLines ) ;
453 if (srcMode == SRC_CMODE)
454 if (mod->cLines[line]->addr) {
455 clearUSERbp (mod->cLines[line]->addr);
459 if (mod->asmLines[line]->addr) {
460 clearUSERbp (mod->asmLines[line]->addr);
468 /*-----------------------------------------------------------------*/
469 /* moduleLineWithAddr - finds and returns a line with a given address */
470 /*-----------------------------------------------------------------*/
471 DEFSETFUNC(moduleLineWithAddr)
476 V_ARG(unsigned int,addr);
477 V_ARG(module **,rmod);
483 for (i=0; i < mod->nasmLines; i++ )
485 if ( mod->asmLines[i]->addr == addr)
491 for ( i=0; i < mod->ncLines; i++ )
493 if ( mod->cLines[i]->addr > addr)
505 /*-----------------------------------------------------------------*/
506 /* funcWithNameModule - returns functions with a name module combo */
507 /*-----------------------------------------------------------------*/
508 DEFSETFUNC(funcWithNameModule)
510 function *func = item;
513 V_ARG(function **,funcp);
518 if (strcmp(func->sym->name,fname) == 0 &&
519 strcmp(func->mod->c_name,mname) == 0) {
527 /*-----------------------------------------------------------------*/
528 /* funcInAddr - given an address returns the function */
529 /*-----------------------------------------------------------------*/
530 DEFSETFUNC(funcInAddr)
532 function *func = item;
533 V_ARG(unsigned int,addr);
534 V_ARG(function **,funcp);
539 /* in the address range */
540 if (func->sym->addr <= addr &&
541 func->sym->eaddr >= addr) {
550 /*-----------------------------------------------------------------*/
551 /* setStepBp - will set STEP Bp @ function entry points */
552 /*-----------------------------------------------------------------*/
553 DEFSETFUNC(setStepBp)
555 function *func = item;
557 if (func->sym && func->sym->addr ) {
559 /* set the entry break point */
560 setBreakPoint (func->sym->addr , CODE , STEP ,
561 stepBpCB ,func->mod->c_name , func->entryline);
569 /*-----------------------------------------------------------------*/
570 /* setStepEPBp - sets a given type of bp @ the execution point */
571 /*-----------------------------------------------------------------*/
572 DEFSETFUNC(setStepEPBp)
578 setBreakPoint (ep->addr, CODE, bptype,
579 stepBpCB, mname, ep->line);
583 /*-----------------------------------------------------------------*/
584 /* setNextEPBp - sets a given type of bp @ the execution point */
585 /*-----------------------------------------------------------------*/
586 DEFSETFUNC(setNextEPBp)
592 setBreakPoint (ep->addr, CODE, bptype,
593 nextBpCB, mname, ep->line);
597 /*-----------------------------------------------------------------*/
598 /* lineAtAddr - for execution points returns the one with addr */
599 /*-----------------------------------------------------------------*/
600 DEFSETFUNC(lineAtAddr)
603 V_ARG(unsigned int,addr);
608 /* address must be an exact match */
609 if (ep->addr == addr) {
622 /*-----------------------------------------------------------------*/
623 /* lineNearAddr - for execution points returns the one with addr */
624 /*-----------------------------------------------------------------*/
625 DEFSETFUNC(lineNearAddr)
628 V_ARG(unsigned int,addr);
633 /* the line in which the address is */
634 if (ep->addr <= addr) {
647 /*-----------------------------------------------------------------*/
648 /* discoverContext - find out the current context of the bp */
649 /*-----------------------------------------------------------------*/
650 context *discoverContext (unsigned addr, function *func, context *ctxt)
655 /* find the function we are in */
656 if (!func && !applyToSet(functions,funcInAddr,addr,&func)) {
657 if (!applyToSet(functions,funcWithName,"_main",&func) ||
658 !applyToSet(modules,moduleLineWithAddr,addr,&mod,NULL))
660 fprintf(stderr, "addr 0x%x in no module/function (runtime env?)\n",addr);
665 ctxt->modName = mod->name;
666 ctxt->cline = func->exitline;
671 ctxt->addr = func->laddr = addr;
672 ctxt->modName = func->modName;
674 /* find the c line number */
675 if(applyToSet(func->cfpoints,lineAtAddr,addr,
676 &line,&ctxt->block,&ctxt->level))
677 ctxt->cline = func->lline = line;
678 else if(applyToSet(func->cfpoints,lineNearAddr,addr,
679 &line,&ctxt->block,&ctxt->level))
680 ctxt->cline = func->lline = line;
684 /* find the asm line number */
686 if (applyToSet(func->afpoints,lineAtAddr,addr,
688 ctxt->asmline = line;
707 static struct instruction instructions[] = {
708 [0x28] = { .flags = 0, .len = 1 }, /* ADD A,Rn */
709 [0x29] = { .flags = 0, .len = 1 }, /* ADD A,Rn */
710 [0x2A] = { .flags = 0, .len = 1 }, /* ADD A,Rn */
711 [0x2B] = { .flags = 0, .len = 1 }, /* ADD A,Rn */
712 [0x2C] = { .flags = 0, .len = 1 }, /* ADD A,Rn */
713 [0x2D] = { .flags = 0, .len = 1 }, /* ADD A,Rn */
714 [0x2E] = { .flags = 0, .len = 1 }, /* ADD A,Rn */
715 [0x2F] = { .flags = 0, .len = 1 }, /* ADD A,Rn */
716 [0x25] = { .flags = 0, .len = 2 }, /* ADD A,direct */
717 [0x26] = { .flags = 0, .len = 1 }, /* ADD A,@Ri */
718 [0x27] = { .flags = 0, .len = 1 }, /* ADD A,@Ri */
719 [0x24] = { .flags = 0, .len = 2 }, /* ADD A,#data */
721 [0x38] = { .flags = 0, .len = 1 }, /* ADDC A,Rn */
722 [0x39] = { .flags = 0, .len = 1 }, /* ADDC A,Rn */
723 [0x3A] = { .flags = 0, .len = 1 }, /* ADDC A,Rn */
724 [0x3B] = { .flags = 0, .len = 1 }, /* ADDC A,Rn */
725 [0x3C] = { .flags = 0, .len = 1 }, /* ADDC A,Rn */
726 [0x3D] = { .flags = 0, .len = 1 }, /* ADDC A,Rn */
727 [0x3E] = { .flags = 0, .len = 1 }, /* ADDC A,Rn */
728 [0x3F] = { .flags = 0, .len = 1 }, /* ADDC A,Rn */
729 [0x35] = { .flags = 0, .len = 2 }, /* ADDC A,direct */
730 [0x36] = { .flags = 0, .len = 1 }, /* ADDC A,@Ri */
731 [0x37] = { .flags = 0, .len = 1 }, /* ADDC A,@Ri */
732 [0x34] = { .flags = 0, .len = 2 }, /* ADDC A,#data */
734 [0x98] = { .flags = 0, .len = 1 }, /* SUBB A,Rn */
735 [0x99] = { .flags = 0, .len = 1 }, /* SUBB A,Rn */
736 [0x9A] = { .flags = 0, .len = 1 }, /* SUBB A,Rn */
737 [0x9B] = { .flags = 0, .len = 1 }, /* SUBB A,Rn */
738 [0x9C] = { .flags = 0, .len = 1 }, /* SUBB A,Rn */
739 [0x9D] = { .flags = 0, .len = 1 }, /* SUBB A,Rn */
740 [0x9E] = { .flags = 0, .len = 1 }, /* SUBB A,Rn */
741 [0x9F] = { .flags = 0, .len = 1 }, /* SUBB A,Rn */
742 [0x95] = { .flags = 0, .len = 2 }, /* SUBB A,direct */
743 [0x96] = { .flags = 0, .len = 1 }, /* SUBB A,@Ri */
744 [0x97] = { .flags = 0, .len = 1 }, /* SUBB A,@Ri */
745 [0x94] = { .flags = 0, .len = 2 }, /* SUBB A,#data */
747 [0x08] = { .flags = 0, .len = 1 }, /* INC Rn */
748 [0x09] = { .flags = 0, .len = 1 }, /* INC Rn */
749 [0x0A] = { .flags = 0, .len = 1 }, /* INC Rn */
750 [0x0B] = { .flags = 0, .len = 1 }, /* INC Rn */
751 [0x0C] = { .flags = 0, .len = 1 }, /* INC Rn */
752 [0x0D] = { .flags = 0, .len = 1 }, /* INC Rn */
753 [0x0E] = { .flags = 0, .len = 1 }, /* INC Rn */
754 [0x0F] = { .flags = 0, .len = 1 }, /* INC Rn */
755 [0x05] = { .flags = 0, .len = 2 }, /* INC direct */
756 [0x06] = { .flags = 0, .len = 1 }, /* INC @Ri */
757 [0x07] = { .flags = 0, .len = 1 }, /* INC @Ri */
758 [0x04] = { .flags = 0, .len = 1 }, /* INC A */
760 [0xA3] = { .flags = 0, .len = 1 }, /* INC DPTR */
762 [0x18] = { .flags = 0, .len = 1 }, /* DEC Rn */
763 [0x19] = { .flags = 0, .len = 1 }, /* DEC Rn */
764 [0x1A] = { .flags = 0, .len = 1 }, /* DEC Rn */
765 [0x1B] = { .flags = 0, .len = 1 }, /* DEC Rn */
766 [0x1C] = { .flags = 0, .len = 1 }, /* DEC Rn */
767 [0x1D] = { .flags = 0, .len = 1 }, /* DEC Rn */
768 [0x1E] = { .flags = 0, .len = 1 }, /* DEC Rn */
769 [0x1F] = { .flags = 0, .len = 1 }, /* DEC Rn */
770 [0x15] = { .flags = 0, .len = 2 }, /* DEC direct */
771 [0x16] = { .flags = 0, .len = 1 }, /* DEC @Ri */
772 [0x17] = { .flags = 0, .len = 1 }, /* DEC @Ri */
773 [0x14] = { .flags = 0, .len = 1 }, /* DEC A */
775 [0xA4] = { .flags = 0, .len = 1 }, /* MUL AB */
776 [0x84] = { .flags = 0, .len = 1 }, /* DIV AB */
778 [0xD4] = { .flags = 0, .len = 1 }, /* DA A */
780 [0x58] = { .flags = 0, .len = 1 }, /* ANL A,Rn */
781 [0x59] = { .flags = 0, .len = 1 }, /* ANL A,Rn */
782 [0x5A] = { .flags = 0, .len = 1 }, /* ANL A,Rn */
783 [0x5B] = { .flags = 0, .len = 1 }, /* ANL A,Rn */
784 [0x5C] = { .flags = 0, .len = 1 }, /* ANL A,Rn */
785 [0x5D] = { .flags = 0, .len = 1 }, /* ANL A,Rn */
786 [0x5E] = { .flags = 0, .len = 1 }, /* ANL A,Rn */
787 [0x5F] = { .flags = 0, .len = 1 }, /* ANL A,Rn */
788 [0x55] = { .flags = 0, .len = 2 }, /* ANL A,direct */
789 [0x56] = { .flags = 0, .len = 1 }, /* ANL A,@Ri */
790 [0x57] = { .flags = 0, .len = 1 }, /* ANL A,@Ri */
791 [0x54] = { .flags = 0, .len = 2 }, /* ANL A,#data */
792 [0x52] = { .flags = 0, .len = 2 }, /* ANL direct,A */
793 [0x53] = { .flags = 0, .len = 3 }, /* ANL direct,#data */
795 [0x48] = { .flags = 0, .len = 1 }, /* ORL A,Rn */
796 [0x49] = { .flags = 0, .len = 1 }, /* ORL A,Rn */
797 [0x4A] = { .flags = 0, .len = 1 }, /* ORL A,Rn */
798 [0x4B] = { .flags = 0, .len = 1 }, /* ORL A,Rn */
799 [0x4C] = { .flags = 0, .len = 1 }, /* ORL A,Rn */
800 [0x4D] = { .flags = 0, .len = 1 }, /* ORL A,Rn */
801 [0x4E] = { .flags = 0, .len = 1 }, /* ORL A,Rn */
802 [0x4F] = { .flags = 0, .len = 1 }, /* ORL A,Rn */
803 [0x45] = { .flags = 0, .len = 2 }, /* ORL A,direct */
804 [0x46] = { .flags = 0, .len = 1 }, /* ORL A,@Ri */
805 [0x47] = { .flags = 0, .len = 1 }, /* ORL A,@Ri */
806 [0x44] = { .flags = 0, .len = 2 }, /* ORL A,#data */
807 [0x42] = { .flags = 0, .len = 2 }, /* ORL direct,A */
808 [0x43] = { .flags = 0, .len = 3 }, /* ORL direct,#data */
810 [0x68] = { .flags = 0, .len = 1 }, /* XRL A,Rn */
811 [0x69] = { .flags = 0, .len = 1 }, /* XRL A,Rn */
812 [0x6A] = { .flags = 0, .len = 1 }, /* XRL A,Rn */
813 [0x6B] = { .flags = 0, .len = 1 }, /* XRL A,Rn */
814 [0x6C] = { .flags = 0, .len = 1 }, /* XRL A,Rn */
815 [0x6D] = { .flags = 0, .len = 1 }, /* XRL A,Rn */
816 [0x6E] = { .flags = 0, .len = 1 }, /* XRL A,Rn */
817 [0x6F] = { .flags = 0, .len = 1 }, /* XRL A,Rn */
818 [0x65] = { .flags = 0, .len = 2 }, /* XRL A,direct */
819 [0x66] = { .flags = 0, .len = 1 }, /* XRL A,@Ri */
820 [0x67] = { .flags = 0, .len = 1 }, /* XRL A,@Ri */
821 [0x64] = { .flags = 0, .len = 2 }, /* XRL A,#data */
822 [0x62] = { .flags = 0, .len = 2 }, /* XRL direct,A */
823 [0x63] = { .flags = 0, .len = 3 }, /* XRL direct,#data */
825 [0xE4] = { .flags = 0, .len = 1 }, /* CLR A */
826 [0xF4] = { .flags = 0, .len = 1 }, /* CPL A */
828 [0x23] = { .flags = 0, .len = 1 }, /* RL A */
829 [0x33] = { .flags = 0, .len = 1 }, /* RLC A */
830 [0x03] = { .flags = 0, .len = 1 }, /* RR A */
831 [0x13] = { .flags = 0, .len = 1 }, /* RRC A */
833 [0xC4] = { .flags = 0, .len = 1 }, /* SWAP A */
835 [0xE8] = { .flags = 0, .len = 1 }, /* MOV A,Rn */
836 [0xE9] = { .flags = 0, .len = 1 }, /* MOV A,Rn */
837 [0xEA] = { .flags = 0, .len = 1 }, /* MOV A,Rn */
838 [0xEB] = { .flags = 0, .len = 1 }, /* MOV A,Rn */
839 [0xEC] = { .flags = 0, .len = 1 }, /* MOV A,Rn */
840 [0xED] = { .flags = 0, .len = 1 }, /* MOV A,Rn */
841 [0xEE] = { .flags = 0, .len = 1 }, /* MOV A,Rn */
842 [0xEF] = { .flags = 0, .len = 1 }, /* MOV A,Rn */
843 [0xE5] = { .flags = 0, .len = 2 }, /* MOV A,direct */
844 [0xE6] = { .flags = 0, .len = 1 }, /* MOV A,@Ri */
845 [0xE7] = { .flags = 0, .len = 1 }, /* MOV A,@Ri */
846 [0x74] = { .flags = 0, .len = 2 }, /* MOV A,#data */
848 [0xF8] = { .flags = 0, .len = 1 }, /* MOV Rn,A */
849 [0xF9] = { .flags = 0, .len = 1 }, /* MOV Rn,A */
850 [0xFA] = { .flags = 0, .len = 1 }, /* MOV Rn,A */
851 [0xFB] = { .flags = 0, .len = 1 }, /* MOV Rn,A */
852 [0xFC] = { .flags = 0, .len = 1 }, /* MOV Rn,A */
853 [0xFD] = { .flags = 0, .len = 1 }, /* MOV Rn,A */
854 [0xFE] = { .flags = 0, .len = 1 }, /* MOV Rn,A */
855 [0xFF] = { .flags = 0, .len = 1 }, /* MOV Rn,A */
857 [0xA8] = { .flags = 0, .len = 2 }, /* MOV Rn,direct */
858 [0xA9] = { .flags = 0, .len = 2 }, /* MOV Rn,direct */
859 [0xAA] = { .flags = 0, .len = 2 }, /* MOV Rn,direct */
860 [0xAB] = { .flags = 0, .len = 2 }, /* MOV Rn,direct */
861 [0xAC] = { .flags = 0, .len = 2 }, /* MOV Rn,direct */
862 [0xAD] = { .flags = 0, .len = 2 }, /* MOV Rn,direct */
863 [0xAE] = { .flags = 0, .len = 2 }, /* MOV Rn,direct */
864 [0xAF] = { .flags = 0, .len = 2 }, /* MOV Rn,direct */
866 [0x78] = { .flags = 0, .len = 2 }, /* MOV Rn,#data */
867 [0x79] = { .flags = 0, .len = 2 }, /* MOV Rn,#data */
868 [0x7A] = { .flags = 0, .len = 2 }, /* MOV Rn,#data */
869 [0x7B] = { .flags = 0, .len = 2 }, /* MOV Rn,#data */
870 [0x7C] = { .flags = 0, .len = 2 }, /* MOV Rn,#data */
871 [0x7D] = { .flags = 0, .len = 2 }, /* MOV Rn,#data */
872 [0x7E] = { .flags = 0, .len = 2 }, /* MOV Rn,#data */
873 [0x7F] = { .flags = 0, .len = 2 }, /* MOV Rn,#data */
875 [0xF5] = { .flags = 0, .len = 2 }, /* MOV direct,A */
876 [0x88] = { .flags = 0, .len = 2 }, /* MOV direct,Rn */
877 [0x89] = { .flags = 0, .len = 2 }, /* MOV direct,Rn */
878 [0x8A] = { .flags = 0, .len = 2 }, /* MOV direct,Rn */
879 [0x8B] = { .flags = 0, .len = 2 }, /* MOV direct,Rn */
880 [0x8C] = { .flags = 0, .len = 2 }, /* MOV direct,Rn */
881 [0x8D] = { .flags = 0, .len = 2 }, /* MOV direct,Rn */
882 [0x8E] = { .flags = 0, .len = 2 }, /* MOV direct,Rn */
883 [0x8F] = { .flags = 0, .len = 2 }, /* MOV direct,Rn */
884 [0x85] = { .flags = 0, .len = 3 }, /* MOV direct,direct */
885 [0x86] = { .flags = 0, .len = 2 }, /* MOV direct,@Ri */
886 [0x87] = { .flags = 0, .len = 2 }, /* MOV direct,@Ri */
887 [0x75] = { .flags = 0, .len = 3 }, /* MOV direct,#data */
889 [0xF6] = { .flags = 0, .len = 1 }, /* MOV @Ri,A */
890 [0xF7] = { .flags = 0, .len = 1 }, /* MOV @Ri,A */
891 [0xA6] = { .flags = 0, .len = 2 }, /* MOV @Ri,direct */
892 [0xA7] = { .flags = 0, .len = 2 }, /* MOV @Ri,direct */
893 [0x76] = { .flags = 0, .len = 2 }, /* MOV @Ri,#data */
894 [0x77] = { .flags = 0, .len = 2 }, /* MOV @Ri,#data */
897 [0x90] = { .flags = 0, .len = 3 }, /* MOV DPTR,#data16 */
899 [0x93] = { .flags = 0, .len = 1 }, /* MOVC A,@A+DPTR */
900 [0x83] = { .flags = 0, .len = 1 }, /* MOVC A,@A+PC */
902 [0xE2] = { .flags = 0, .len = 1 }, /* MOVX A,@Ri */
903 [0xE3] = { .flags = 0, .len = 1 }, /* MOVX A,@Ri */
904 [0xE0] = { .flags = 0, .len = 1 }, /* MOVX A,@DPTR */
905 [0xF2] = { .flags = 0, .len = 1 }, /* MOVX @Ri,A */
906 [0xF3] = { .flags = 0, .len = 1 }, /* MOVX @Ri,A */
907 [0xF0] = { .flags = 0, .len = 1 }, /* MOVX @DPTR,A */
909 [0xC0] = { .flags = 0, .len = 2 }, /* PUSH direct */
910 [0xD0] = { .flags = 0, .len = 2 }, /* POP direct */
911 [0xF5] = { .flags = 0, .len = 2 }, /* MOV direct,A */
912 [0xF5] = { .flags = 0, .len = 2 }, /* MOV direct,A */
913 [0xF5] = { .flags = 0, .len = 2 }, /* MOV direct,A */
914 [0xF5] = { .flags = 0, .len = 2 }, /* MOV direct,A */
916 [0xC8] = { .flags = 0, .len = 1 }, /* XCH A,Rn */
917 [0xC9] = { .flags = 0, .len = 1 }, /* XCH A,Rn */
918 [0xCA] = { .flags = 0, .len = 1 }, /* XCH A,Rn */
919 [0xCB] = { .flags = 0, .len = 1 }, /* XCH A,Rn */
920 [0xCC] = { .flags = 0, .len = 1 }, /* XCH A,Rn */
921 [0xCD] = { .flags = 0, .len = 1 }, /* XCH A,Rn */
922 [0xCE] = { .flags = 0, .len = 1 }, /* XCH A,Rn */
923 [0xCF] = { .flags = 0, .len = 1 }, /* XCH A,Rn */
924 [0xC5] = { .flags = 0, .len = 2 }, /* XCH A,direct */
925 [0xC6] = { .flags = 0, .len = 1 }, /* XCH A,@Ri */
926 [0xC7] = { .flags = 0, .len = 1 }, /* XCH A,@Ri */
927 [0xD6] = { .flags = 0, .len = 1 }, /* XCHD A,@Ri */
928 [0xD7] = { .flags = 0, .len = 1 }, /* XCHD A,@Ri */
930 [0x11] = { .flags = IS_CALL, .len = 2 }, /* ACALL addr11 */
931 [0x31] = { .flags = IS_CALL, .len = 2 }, /* ACALL addr11 */
932 [0x51] = { .flags = IS_CALL, .len = 2 }, /* ACALL addr11 */
933 [0x71] = { .flags = IS_CALL, .len = 2 }, /* ACALL addr11 */
934 [0x91] = { .flags = IS_CALL, .len = 2 }, /* ACALL addr11 */
935 [0xb1] = { .flags = IS_CALL, .len = 2 }, /* ACALL addr11 */
936 [0xd1] = { .flags = IS_CALL, .len = 2 }, /* ACALL addr11 */
937 [0xf1] = { .flags = IS_CALL, .len = 2 }, /* ACALL addr11 */
938 [0x12] = { .flags = IS_CALL, .len = 3 }, /* LCALL addr16 */
940 [0x22] = { .flags = IS_RET, .len = 1 }, /* RET */
941 [0x32] = { .flags = IS_RET, .len = 1 }, /* RETI */
943 [0x01] = { .flags = IS_BRANCH, .len = 2 }, /* AJMP addr11 */
944 [0x21] = { .flags = IS_BRANCH, .len = 2 }, /* AJMP addr11 */
945 [0x41] = { .flags = IS_BRANCH, .len = 2 }, /* AJMP addr11 */
946 [0x61] = { .flags = IS_BRANCH, .len = 2 }, /* AJMP addr11 */
947 [0x81] = { .flags = IS_BRANCH, .len = 2 }, /* AJMP addr11 */
948 [0xa1] = { .flags = IS_BRANCH, .len = 2 }, /* AJMP addr11 */
949 [0xc1] = { .flags = IS_BRANCH, .len = 2 }, /* AJMP addr11 */
950 [0xe1] = { .flags = IS_BRANCH, .len = 2 }, /* AJMP addr11 */
951 [0x02] = { .flags = IS_BRANCH, .len = 3 }, /* LJMP addr16 */
953 [0x80] = { .flags = IS_BRANCH, .len = 2 }, /* SJMP rel */
955 [0x73] = { .flags = IS_BRANCH, .len = 1 }, /* JMP @A+DPTR */
957 [0x60] = { .flags = IS_BRANCH, .len = 2 }, /* JZ rel */
958 [0x70] = { .flags = IS_BRANCH, .len = 2 }, /* JNZ rel */
959 [0x40] = { .flags = IS_BRANCH, .len = 2 }, /* JC rel */
960 [0x50] = { .flags = IS_BRANCH, .len = 2 }, /* JNC rel */
961 [0x20] = { .flags = IS_BRANCH, .len = 3 }, /* JB bit,rel */
962 [0x30] = { .flags = IS_BRANCH, .len = 3 }, /* JNB bit,rel */
963 [0x10] = { .flags = IS_BRANCH, .len = 3 }, /* JBC bit,direct rel */
965 [0xB5] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE A,direct rel */
966 [0xB4] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE A,#data rel */
967 [0xB8] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE Rn,#data rel */
968 [0xB9] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE Rn,#data rel */
969 [0xBA] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE Rn,#data rel */
970 [0xBB] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE Rn,#data rel */
971 [0xBC] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE Rn,#data rel */
972 [0xBD] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE Rn,#data rel */
973 [0xBE] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE Rn,#data rel */
974 [0xBF] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE Rn,#data rel */
975 [0xB6] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE @Ri,direct rel */
976 [0xB7] = { .flags = IS_BRANCH, .len = 3 }, /* CJNE @Ri,direct rel */
978 [0xD8] = { .flags = IS_BRANCH, .len = 2 }, /* DNJZ Rn,rel */
979 [0xD9] = { .flags = IS_BRANCH, .len = 2 }, /* DNJZ Rn,rel */
980 [0xDA] = { .flags = IS_BRANCH, .len = 2 }, /* DNJZ Rn,rel */
981 [0xDB] = { .flags = IS_BRANCH, .len = 2 }, /* DNJZ Rn,rel */
982 [0xDC] = { .flags = IS_BRANCH, .len = 2 }, /* DNJZ Rn,rel */
983 [0xDD] = { .flags = IS_BRANCH, .len = 2 }, /* DNJZ Rn,rel */
984 [0xDE] = { .flags = IS_BRANCH, .len = 2 }, /* DNJZ Rn,rel */
985 [0xDF] = { .flags = IS_BRANCH, .len = 2 }, /* DNJZ Rn,rel */
986 [0xD5] = { .flags = IS_BRANCH, .len = 3 }, /* DNJZ direct,rel */
988 [0x00] = { .flags = 0, .len = 1 }, /* NOP */
990 [0xC3] = { .flags = 0, .len = 1 }, /* CLR C */
991 [0xC2] = { .flags = 0, .len = 2 }, /* CLR bit */
992 [0xD3] = { .flags = 0, .len = 1 }, /* SETB C */
993 [0xD2] = { .flags = 0, .len = 2 }, /* SETB bit */
995 [0xB3] = { .flags = 0, .len = 1 }, /* CPL C */
996 [0xB2] = { .flags = 0, .len = 2 }, /* CPL bit */
998 [0x82] = { .flags = 0, .len = 2 }, /* ANL C,bit */
999 [0xB0] = { .flags = 0, .len = 2 }, /* ANL C,/bit */
1000 [0x72] = { .flags = 0, .len = 2 }, /* ORL C,bit */
1001 [0xA0] = { .flags = 0, .len = 2 }, /* ORL C,/bit */
1003 [0xA2] = { .flags = 0, .len = 2 }, /* MOV C,bit */
1004 [0x92] = { .flags = 0, .len = 2 }, /* MOV bit,C */
1006 [0xA5] = { .flags = 0, .len = 1 }, /* TRAP */
1014 #define MOV_direct_A 0xF5
1015 #define MOV_A_direct 0xE5
1016 #define ADD_A_imm 0x24
1020 #define LJMP_addr16 0x02
1021 #define SJMP_rel 0x80
1023 static int stack_change(unsigned addr)
1026 unsigned char direct;
1028 insn = simGetValue(addr, 'C', 1);
1035 direct = simGetValue(addr+1, 'C', 1);
1037 unsigned char add_insn;
1038 unsigned char add_direct;
1040 add_insn = simGetValue(addr-2, 'C', 1);
1041 if (add_insn == ADD_A_imm) {
1042 add_direct = simGetValue(addr-1, 'C', 1);
1043 return (signed char) add_direct;
1057 do_indent(int indent);
1062 #define DPC(x) do { do_indent(indent); printf x; } while (0);
1065 static int pc_change(unsigned addr, unsigned addrs[2], int indent)
1072 insn = simGetValue(addr, 'C', 1);
1073 if (instructions[insn].flags & IS_RET)
1076 if (!(instructions[insn].flags & IS_BRANCH)) {
1077 addrs[0] = addr + instructions[insn].len;
1081 if (insn == LJMP_addr16) {
1082 addrs[0] = ((simGetValue(addr+1, 'C', 1) << 8) |
1083 (simGetValue(addr+2, 'C', 1)));
1084 DPC(("0x%04x LJMP 0x%04x\n", addr, addrs[0]));
1089 if ((insn & 0x1f) == 0x01) {
1090 unsigned char direct = simGetValue(addr+1,'C', 1);
1092 addrs[0] = ((addr + 2) & 0xf800) | ((insn & 0xe0) << 3) | direct;
1093 DPC(("0x%04x AJMP 0x%04x\n", addr, addrs[0]));
1097 /* otherwise, relative branch */
1098 len = instructions[insn].len;
1100 delta = (signed char) simGetValue(addr+len-1, 'C', 1);
1101 new_addr = (addr + len) + delta;
1103 if (insn == SJMP_rel || (addr + len) == new_addr) {
1104 addrs[0] = new_addr;
1105 DPC(("0x%04x SJMP 0x%04x\n", addr, addrs[0]));
1108 addrs[0] = (addr + len) & 0xffff;
1109 addrs[1] = new_addr & 0xffff;
1111 DPC(("0x%04x SJMP 0x%04x 0x%04x\n", addr, addrs[0], addrs[1]));
1115 #define SEARCH_LOOP 0x8000
1116 #define SEARCH_EXPIRED 0x8001
1118 #define MAX_STACK_BRANCH_TRACE 8192
1119 static unsigned stack_branch_trace[MAX_STACK_BRANCH_TRACE];
1122 been_here(unsigned pc, int ntrace)
1126 for (t = 0; t < ntrace; t++)
1127 if (stack_branch_trace[t] == pc)
1132 #define MAX_SEARCH 100
1134 #define indent (MAX_SEARCH - search)
1137 stack_depth(unsigned pc, int search, int ntrace)
1147 change += stack_change(pc);
1148 n = pc_change(pc, new_pc, MAX_SEARCH - search);
1153 if (new_pc[0] <= pc) {
1154 if (been_here(pc, ntrace)) {
1155 DPC(("0x%04x loop 1\n", pc));
1158 stack_branch_trace[ntrace++] = pc;
1164 DPC(("0x%04x max depth\n", pc));
1165 return SEARCH_EXPIRED;
1168 if (been_here(pc, ntrace))
1170 DPC(("0x%04x loop 2\n", pc));
1173 stack_branch_trace[ntrace++] = pc;
1175 for (s = 0; s < search - 1; s++) {
1180 d = stack_depth(new_pc[i], search-1, ntrace);
1181 if (d == SEARCH_LOOP) {
1182 for (j = i; j < n-1; j++)
1183 new_pc[j] = new_pc[j+1];
1187 if (d != SEARCH_EXPIRED) {
1188 DPC(("success %d\n", d + change));
1194 DPC(("0x%04x loop 3\n", pc));
1198 DPC(("search expired\n"));
1199 return SEARCH_EXPIRED;
1207 symbol *start_stack = symLookup("__start_stack", NULL);
1209 return start_stack->addr;
1214 frameStart(unsigned int *bpp, unsigned int *pcp)
1223 sp = simGetValue(0x81,'I',1);
1224 depth = stack_depth(pc, MAX_SEARCH, 0);
1225 if (depth == SEARCH_LOOP || depth == SEARCH_EXPIRED)
1235 frameNext(unsigned int *bpp, unsigned int *pcp)
1237 unsigned int bp = *bpp;
1240 symbol *start_stack;
1242 if (bp < stack_start())
1244 pc = simGetValue(bp - 1, 'B', 2);
1247 depth = stack_depth(pc, MAX_SEARCH, 0);
1248 if (depth == SEARCH_LOOP || depth == SEARCH_EXPIRED)
1251 bp = bp - 2 + depth;
1257 static int running = 0;
1259 static int is_running(void) {
1263 static int set_running(int run) {
1267 /*-----------------------------------------------------------------*/
1268 /* simGo - send 'go' cmd to simulator and wait till a break occurs */
1269 /*-----------------------------------------------------------------*/
1270 void simGo (unsigned int gaddr)
1277 if ( userinterrupt )
1285 function *func = NULL;;
1286 if (applyToSet(functions,funcInAddr,gaddr,&func))
1287 STACK_PUSH(callStack,func);
1290 addr = simGoTillBp (gaddr);
1292 /* got the pc for the break point now first
1293 discover the program context i.e. module, function
1294 linenumber of the source etc, etc etc */
1296 ctxt = discoverContext (addr, NULL, currCtxt);
1298 /* dispatch all the break point call back functions */
1299 rv = dispatchCB (addr,ctxt);
1301 /* the dispatch call back function will return
1302 non-zero if an user break point has been hit
1303 if not then we continue with the execution
1309 if ( gaddr == -1 || doingSteps == 1 )
1315 /*-----------------------------------------------------------------*/
1316 /* preparePrint - common parse function for set variable, */
1317 /* output, print and display */
1318 /*-----------------------------------------------------------------*/
1319 static char *preparePrint(char *s, context *cctxt, int *fmt, symbol **sym)
1334 /* format of printout */
1358 for ( bp = s; *bp && ( isalnum( *bp ) || *bp == '_' || *bp == '$'); bp++ );
1364 *sym = symLookup(s,cctxt);
1370 fprintf(stdout,"No symbol \"%s\" in current context.\n", s);
1374 static int printAsmLine( function *func, module *m, unsigned saddr, unsigned eaddr)
1378 unsigned lastaddr = saddr+1;
1383 symaddr = func->sym->addr;
1384 symname = func->sym->name;
1391 for (j=0,i=0; i < m->nasmLines; i++ )
1393 if ( saddr >= 0 && m->asmLines[i]->addr < saddr)
1397 if ( eaddr >= 0 && m->asmLines[i]->addr > eaddr)
1402 (m->asmLines[i]->addr < func->sym->addr ||
1403 m->asmLines[i]->addr > func->sym->eaddr ))
1407 delta = m->asmLines[i]->addr - symaddr;
1411 lastaddr = m->asmLines[i]->addr;
1412 printf("0x%08x <%s",lastaddr,symname);
1413 if (delta > 0) printf("+%d",delta);
1414 printf(">:\t%s",m->asmLines[i]->src);
1420 /*-----------------------------------------------------------------*/
1421 /* cmdDisasm - disassemble asm instruction */
1422 /*-----------------------------------------------------------------*/
1423 static int cmdDisasm (char *s, context *cctxt, int args)
1425 function *func = NULL;
1430 /* white space skip */
1438 saddr = strtol(s,&s,0);
1444 eaddr = strtol(s,0,0);
1453 /* no start or only start so dump function */
1460 applyToSet(functions,funcInAddr,saddr,&func);
1464 printf("Dump of assembler code for function %s:\n",func->sym->name);
1465 printAsmLine(func,func->mod,-1,-1);
1466 printf("End of assembler dump.\n");
1471 if (applyToSet(modules,moduleLineWithAddr,saddr,&modul,NULL))
1474 printf("Dump of assembler code:\n");
1475 printAsmLine(NULL,modul,saddr,eaddr);
1476 printf("End of assembler dump.\n");
1484 printf("Dump of assembler code from 0x%08lx to 0x%08lx:\n",saddr,eaddr);
1486 while ( saddr < eaddr )
1489 if (applyToSet(functions,funcInAddr,saddr,&func))
1498 if (!applyToSet(modules,moduleLineWithAddr,saddr,&modul,NULL))
1501 saddr = printAsmLine(func,modul,saddr,eaddr) + 1;
1506 printf("End of assembler dump.\n");
1511 fprintf(stderr,"No function contains specified address.\n");
1515 sprintf(lbuf,"dis 0x%lx 0 %ld\n",saddr,( eaddr == -1 )?1L:eaddr-saddr);
1517 waitForSim(1000, NULL);
1518 fputs(simResponse(),stdout);
1522 /*-----------------------------------------------------------------*/
1523 /* cmdDisasm1 - disassemble one asm instruction */
1524 /*-----------------------------------------------------------------*/
1525 int cmdDisasm1 (char *s, context *cctxt)
1527 return cmdDisasm( s, cctxt, 1);
1530 /*-----------------------------------------------------------------*/
1531 /* cmdDisasmF - disassemble asm instructions */
1532 /*-----------------------------------------------------------------*/
1533 int cmdDisasmF(char *s, context *cctxt)
1535 return cmdDisasm( s, cctxt, 2);
1538 static int commonSetUserBp(char *s, context *cctxt, char bpType)
1541 function *func = NULL;
1543 /* user break point location specification can be of the following
1545 a) <nothing> - break point at current location
1546 b) lineno - number of the current module
1547 c) filename:lineno - line number of the given file
1548 e) filename:function- function X in file Y (useful for static functions)
1549 f) function - function entry point
1550 g) *addr - break point at address
1554 fprintf(stdout,"No symbol table is loaded. Use the \"file\" command.\n");
1557 /* trim left and right */
1560 /* case a) nothing */
1561 /* if nothing given then current location : we know
1562 the current execution location from the currentContext */
1565 /* if current context is known */
1567 Dprintf(D_break, ("commonSetUserBp: a) cctxtaddr:%x \n",cctxt->addr));
1568 if (srcMode == SRC_CMODE)
1569 /* set the break point */
1570 setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
1571 cctxt->func->mod->c_name, cctxt->cline);
1573 setBreakPoint ( cctxt->addr , CODE , bpType , userBpCB ,
1574 cctxt->func->mod->asm_name, cctxt->asmline);
1578 fprintf(stderr,"No default breakpoint address now.\n");
1583 if ( *s == '*' && isdigit(*(s+1)))
1586 long braddr = strtol(s+1,0,0);
1587 if (!applyToSet(functions,funcInAddr,braddr,&func))
1590 if (!applyToSet(modules,moduleLineWithAddr,braddr,&modul,&line))
1592 fprintf(stderr,"Address 0x%08lx not exists in code.\n",braddr);
1596 Dprintf(D_break, ("commonSetUserBp: g) addr:%lx \n",braddr));
1597 setBreakPoint ( braddr , CODE , bpType , userBpCB ,
1598 modul->c_name,line);
1604 int line = func->exitline;
1605 if ( !applyToSet(func->cfpoints,lineAtAddr,braddr,
1607 applyToSet(func->cfpoints,lineNearAddr,braddr,&line,NULL,NULL);
1608 setBreakPoint ( braddr , CODE , bpType , userBpCB ,
1609 func->mod->c_name,line);
1613 /* case b) lineno */
1614 /* check if line number */
1615 if ( !strchr(s,':') && isdigit(*s)) {
1616 /* get the lineno */
1617 int line = atoi(s) -1;
1618 Dprintf(D_break, ("commonSetUserBp: b) line:%d \n",line));
1621 fprintf(stdout,"linenumber <= 0\n");
1624 /* if current context not present then we must get the module
1625 which has main & set the break point @ line number provided
1626 of that module : if current context known then set the bp
1627 at the line number given for the current module
1630 if (!cctxt->func->mod) {
1631 if (!applyToSet(functions,funcWithName,"main"))
1632 fprintf(stderr,"Function \"main\" not defined.\n");
1634 setBPatModLine(func->mod,line, bpType);
1636 setBPatModLine(cctxt->func->mod,line, bpType);
1639 setBPatModLine(list_mod,line, bpType);
1641 fprintf(stdout,"Sdcdb fails to have module symbol context at %d\n", __LINE__);
1648 if ((bp = strchr(s,':'))) {
1653 if (srcMode == SRC_CMODE) {
1654 if (!applyToSet(modules,moduleWithCName,s,&mod)) {
1655 fprintf (stderr,"No source file named %s.\n",s);
1659 if (!applyToSet(modules,moduleWithAsmName,s,&mod)) {
1660 fprintf (stderr,"No source file named %s.\n",s);
1665 /* case c) filename:lineno */
1666 if (isdigit(*(bp +1))) {
1667 Dprintf(D_break, ("commonSetUserBp: c) line:%d \n",atoi(bp+1)));
1668 setBPatModLine (mod,atoi(bp+1)-1,bpType);
1672 /* case d) filename:function */
1673 if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func))
1674 fprintf(stderr,"Function \"%s\" not defined.\n",bp+1);
1676 Dprintf(D_break, ("commonSetUserBp: d) \n"));
1677 setBPatModLine (mod,
1678 (srcMode == SRC_CMODE ?
1680 func->aentryline),bpType);
1685 /* case e) function */
1686 Dprintf(D_break, ("commonSetUserBp: e) \n"));
1687 if (!applyToSet(functions,funcWithName,s,&func))
1688 fprintf(stderr,"Function \"%s\" not defined.\n",s);
1690 setBPatModLine(func->mod,
1691 (srcMode == SRC_CMODE ?
1693 func->aentryline),bpType);
1699 /*-----------------------------------------------------------------*/
1700 /* cmdSetTmpUserBp - settempory break point at the user specified location */
1701 /*-----------------------------------------------------------------*/
1702 int cmdSetTmpUserBp (char *s, context *cctxt)
1704 return commonSetUserBp(s, cctxt, TMPUSER );
1707 /*-----------------------------------------------------------------*/
1708 /* cmdSetUserBp - set break point at the user specified location */
1709 /*-----------------------------------------------------------------*/
1710 int cmdSetUserBp (char *s, context *cctxt)
1712 return commonSetUserBp(s, cctxt, USER );
1715 /*-----------------------------------------------------------------*/
1716 /* cmdJump - set program counter */
1717 /*-----------------------------------------------------------------*/
1718 int cmdJump (char *s, context *cctxt)
1721 function *func = NULL;
1724 fprintf(stdout,"The program is not running.\n");
1728 /* trim left and right */
1733 fprintf(stdout,"No argument: need line or *addr.\n");
1736 if ( *s == '*' && isdigit(*(s+1)))
1738 unsigned int addr = atoi(s);
1739 if (cctxt && cctxt->func &&
1740 cctxt->func->sym->addr <= addr &&
1741 cctxt->func->sym->eaddr >= addr)
1746 fprintf(stdout,"Warning addr 0x%x outside actual function.\n",addr);
1752 /* get the lineno */
1753 int line = atoi(s) -1;
1754 if (!cctxt || !cctxt->func || !cctxt->func->mod)
1756 fprintf(stderr,"Function not defined.\n");
1759 if (line >= cctxt->func->entryline &&
1760 line <= cctxt->func->exitline )
1762 simSetPC(cctxt->func->mod->cLines[line]->addr);
1765 if (line >= cctxt->func->mod->ncLines )
1767 fprintf(stderr,"line not in module.\n");
1770 fprintf(stdout,"Warning line %d outside actual function.\n",line+1);
1771 simSetPC(cctxt->func->mod->cLines[line]->addr);
1774 if ((bp = strchr(s,':')))
1779 if (!applyToSet(modules,moduleWithCName,s,&mod))
1781 fprintf (stderr,"No source file named %s.\n",s);
1786 fprintf (stderr,"No line number.\n");
1790 if (line >= mod->ncLines )
1792 fprintf(stderr,"line not in module.\n");
1795 if ( mod != cctxt->func->mod ||
1796 line < cctxt->func->entryline ||
1797 line > cctxt->func->exitline )
1799 fprintf(stdout,"Warning line %d outside actual function.\n",
1802 simSetPC(mod->cLines[line]->addr);
1807 /*-----------------------------------------------------------------*/
1808 /* cmdListAsm - list assembler source code */
1809 /*-----------------------------------------------------------------*/
1810 int cmdListAsm (char *s, context *cctxt)
1812 if ( cctxt && cctxt->func)
1815 if ( cctxt->addr != INT_MAX )
1817 if (printAsmLine(cctxt->func,cctxt->func->mod,
1818 (long)cctxt->addr,(long)cctxt->addr))
1825 /*-----------------------------------------------------------------*/
1826 /* cmdSetOption - set debugger options */
1827 /*-----------------------------------------------------------------*/
1828 int cmdSetOption (char *s, context *cctxt)
1831 if (strncmp(s,"srcmode",7) == 0 ) {
1832 if (srcMode == SRC_CMODE)
1833 srcMode = SRC_AMODE;
1835 srcMode = SRC_CMODE;
1836 fprintf(stderr,"source mode set to '%s'\n",
1837 (srcMode == SRC_CMODE ? "C" : "asm"));
1841 if (strncmp(s,"listsize ",9) == 0)
1843 listlines = strtol(s+9,0,0);
1844 if ( listlines < LISTLINES )
1845 listlines = LISTLINES;
1850 if (strncmp(s,"debug ",6) == 0)
1852 sdcdbDebug = strtol(s+6,0,0);
1856 if (strncmp(s,"variable ",9) == 0)
1862 if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
1865 while (*s && *s != '=') s++;
1870 printOrSetSymValue(sym,cctxt,0,0,0,rs,s,'\0');
1874 fprintf(stdout,"No new value for \"%s\".\n",s);
1879 fprintf(stderr,"'set %s' command not yet implemented\n",s);
1883 /*-----------------------------------------------------------------*/
1884 /* cmdContinue - continue till next break point */
1885 /*-----------------------------------------------------------------*/
1886 int cmdContinue (char *s, context *cctxt)
1888 if (!is_running()) {
1889 fprintf(stdout,"The program is not being run.\n");
1893 fprintf(stdout,"Continuing.\n");
1899 /*-----------------------------------------------------------------*/
1900 /* cmdIgnore - set ignorecount for breakpoint */
1901 /*-----------------------------------------------------------------*/
1902 int cmdIgnore (char *s, context *cctxt)
1908 fprintf(stdout,"Argument required (breakpoint number).\n");
1911 bpnum = strtol(s,&s,10);
1915 fprintf(stdout,"Second argument (specified ignore-count) is missing.");
1918 cnt = strtol(s,0,10);
1919 setUserbpIgnCount(bpnum,cnt);
1923 /*-----------------------------------------------------------------*/
1924 /* cmdCondition - set condition for breakpoint */
1925 /*-----------------------------------------------------------------*/
1926 int cmdCondition (char *s, context *cctxt)
1932 fprintf(stdout,"Argument required (breakpoint number).\n");
1935 bpnum = strtol(s,&s,10);
1941 setUserbpCondition(bpnum,s);
1945 /*-----------------------------------------------------------------*/
1946 /* cmdCommands - set commands for breakpoint */
1947 /*-----------------------------------------------------------------*/
1948 int cmdCommands (char *s, context *cctxt)
1955 bpnum = getLastBreakptNumber();
1957 bpnum = strtol(s,0,10);
1960 while ((line = getNextCmdLine()))
1962 line = trim_left(line);
1963 if (!strncmp(line,"end",3))
1967 cmds = Safe_strdup(line);
1971 cmds = Safe_realloc( cmds, strlen(cmds) + 1 + strlen(line));
1975 setUserbpCommand(bpnum,cmds);
1979 /*-----------------------------------------------------------------*/
1980 /* cmdDelUserBp - delete user break point */
1981 /*-----------------------------------------------------------------*/
1982 int cmdDelUserBp (char *s, context *cctxt)
1988 if (userBpPresent) {
1990 fprintf (stdout,"Delete all breakpoints? (y or n) ");
1992 fgets(buffer,sizeof(buffer),stdin);
1993 if (toupper(buffer[0]) == 'Y')
1999 /* determine the break point number */
2000 if (sscanf(s,"%d",&bpnum) == 1)
2001 deleteUSERbp(bpnum);
2006 /*-----------------------------------------------------------------*/
2007 /* cmdStepi - single step exactly one instruction */
2008 /*-----------------------------------------------------------------*/
2009 int cmdStepi (char *s, context *cctxt)
2013 fprintf(stdout,"The program is not being run.\n");
2024 static unsigned line_start_addr(context *ctx, int line)
2026 function *func = ctx->func;
2027 module *mod = func->mod;
2031 if (srcMode == SRC_CMODE)
2032 nlines = mod->ncLines;
2034 nlines = mod->nasmLines;
2037 if (srcMode == SRC_CMODE)
2038 addr = mod->cLines[line]->addr;
2040 addr = mod->asmLines[line]->addr;
2042 } while (addr == 0x7fffffff && line < nlines);
2043 if (addr == 0x7fffffff)
2044 addr = func->sym->eaddr;
2048 static unsigned line_end_addr(context *ctx, int line)
2050 function *func = ctx->func;
2051 module *mod = func->mod;
2052 int next_line, nlines;
2053 unsigned start_addr = line_start_addr(ctx, line);
2054 unsigned next_addr = func->sym->eaddr + 1;
2057 if (srcMode == SRC_CMODE)
2058 nlines = mod->ncLines;
2060 nlines = mod->nasmLines;
2061 for (next_line = 0; next_line < nlines; next_line++) {
2062 if (next_line == line)
2064 if (srcMode == SRC_CMODE)
2065 addr = mod->cLines[next_line]->addr;
2067 addr = mod->asmLines[next_line]->addr;
2068 if (start_addr < addr && addr < next_addr)
2074 BP_CALLBACK(step_bp_callback)
2080 static int do_step(context *ctx, int into)
2082 function *func = ctx->func;
2083 module *mod = func->mod;
2090 unsigned start_addr, end_addr, addr;
2092 unsigned char flags;
2094 if (srcMode == SRC_CMODE) {
2095 lines = mod->cLines;
2096 nlines = mod->ncLines;
2097 start_l = ctx->cline;
2099 lines = mod->asmLines;
2100 nlines = mod->nasmLines;
2101 start_l = ctx->asmline;
2105 flags = IS_BRANCH|IS_RET;
2108 line = lines[start_l];
2109 start = line_start_addr(ctx, start_l);
2110 end = line_end_addr(ctx, start_l);
2112 while (start <= ctx->addr && ctx->addr < end) {
2114 for (addr = ctx->addr; addr < end; addr += len) {
2115 insn = simGetValue(addr, 'C', 1);
2116 if (instructions[insn].flags & flags)
2118 len = instructions[insn].len;
2120 fprintf(stderr, "Unknown opcode 0x%02x\n", insn);
2124 if (addr != ctx->addr) {
2125 setBreakPoint(addr, CODE, STEP,
2127 mod->name, start_l);
2129 /* run to breakpoint */
2133 /* step over instruction at breakpoint */
2134 if (start <= ctx->addr && ctx->addr < end) {
2140 stepBpCB(ctx->addr, NULL, ctx);
2144 /*-----------------------------------------------------------------*/
2145 /* cmdStep - single step thru C source file */
2146 /*-----------------------------------------------------------------*/
2147 int cmdStep (char *s, context *cctxt)
2149 function *func = NULL;
2152 fprintf(stdout,"The program is not being run.\n");
2158 /*-----------------------------------------------------------------*/
2159 /* cmdNexti - next instruction but proceed function call */
2160 /*-----------------------------------------------------------------*/
2161 int cmdNexti (char *s, context *cctxt)
2164 fprintf(stdout,"The program is not being run.\n");
2175 /*-----------------------------------------------------------------*/
2176 /* cmdNext - next executable C statement file */
2177 /*-----------------------------------------------------------------*/
2178 int cmdNext (char *s, context *cctxt)
2180 function *func = NULL;
2181 /* next is almost the same as step except we don't
2182 we don't set break point for all function entry
2185 fprintf(stdout,"The program is not being run.\n");
2191 /*-----------------------------------------------------------------*/
2192 /* cmdRun - run till next break point */
2193 /*-----------------------------------------------------------------*/
2194 int cmdRun (char *s, context *cctxt)
2198 if (!is_running()) {
2199 fprintf(stdout,"Starting program\n");
2202 fprintf(stdout,"No executable file specified.\nUse the \"file\" command.\n");
2210 "The program being debugged has been started already.\n");
2211 fprintf(stdout,"Start it from the beginning? (y or n) ");
2214 fgets(buff,sizeof(buff),stdin);
2215 if (toupper(buff[0]) == 'Y') {
2226 /*-----------------------------------------------------------------
2227 cmdListSymbols - list symbols
2228 |-----------------------------------------------------------------*/
2229 int cmdListSymbols (char *s, context *cctxt)
2231 int our_verbose = 0;
2235 if (strstr(s, "v1")) {
2237 } else if (strstr(s, "v2")) {
2241 printf("[symbols]\n");
2242 sy = setFirstItem(symbols);
2247 if (our_verbose <= 1)
2248 printf("<%s>", sy->name);
2250 if (our_verbose > 1) {
2251 printf(" %d) name:%s, size:%d, level:%d block:%d\n", i,
2252 sy->name, sy->size, sy->level, sy->block);
2253 printf(" isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
2254 sy->isonstack, sy->isfunc, sy->offset, sy->addr);
2255 printf(" eaddr:%d, addr_type:%c, type:%p etype:%p\n",
2256 sy->eaddr, sy->addr_type, sy->type, sy->etype);
2257 printf(" scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
2258 sy->scopetype, sy->sname, sy->rname, sy->addrspace);
2259 printf(" next:%p\n", sy->next);
2262 sy = setNextItem(symbols);
2264 printf(" %d symbols\n", i);
2268 /*-----------------------------------------------------------------
2269 cmdListFunctions - list functions.
2270 |-----------------------------------------------------------------*/
2271 int cmdListFunctions (char *s, context *cctxt)
2275 int our_verbose = 0;
2277 if (strstr(s, "v1")) {
2279 } else if (strstr(s, "v2")) {
2283 printf("[functions]\n");
2284 f = setFirstItem(functions);
2288 printf(" %d) sym:%p, fname:%s, modName:%s, mod:%p\n", i,
2289 f->sym, f->sym->name, f->modName, f->mod);
2290 printf(" entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
2291 f->entryline, f->aentryline, f->exitline, f->aexitline);
2292 printf(" cfpoints:%p, afpoints:%p, laddr:%x, lline:%d\n",
2293 f->cfpoints, f->afpoints, f->laddr, f->lline);
2296 printf("<%s>", f->sym->name);
2299 f = setNextItem(functions);
2301 printf(" %d functions\n", i);
2305 /*-----------------------------------------------------------------
2306 cmdListModules - list modules.
2307 |-----------------------------------------------------------------*/
2308 int cmdListModules (char *s, context *cctxt)
2313 int our_verbose = 0;
2315 if (strstr(s, "v1")) {
2317 } else if (strstr(s, "v2")) {
2321 printf("[modules]\n");
2322 m = setFirstItem(modules);
2328 if (our_verbose >= 0) {
2329 printf(" %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
2330 m->cfullname, m->afullname, m->name);
2331 printf(" c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
2332 m->c_name, m->asm_name, m->ncLines, m->nasmLines);
2333 printf(" cLines:%p, asmLines:%p\n",
2334 m->cLines, m->asmLines);
2336 if (our_verbose >= 2) {
2338 printf(" [cLines] ");
2340 for (i=0; i<m->ncLines; i++ ) {
2342 printf(" (%d) addr:%x, block:%d, level:%d, src:%s\n",
2343 i, cs->addr, cs->block, cs->level, cs->src);
2346 printf("%d records", i);
2349 printf(" [asmLines] ");
2351 for (i=0; i<m->nasmLines; i++ ) {
2352 as = m->asmLines[i];
2353 printf(" (%d) addr:%x, block:%d, level:%d, src:%s\n",
2354 i, as->addr, as->block, as->level, as->src);
2357 printf("%d records", i);
2362 m = setNextItem(modules);
2367 /*-----------------------------------------------------------------
2368 infoSymbols - This is really just a tool to dump all these
2369 huge program structures out into human readable form.
2370 |-----------------------------------------------------------------*/
2371 static void infoSymbols(context *ctxt)
2373 int our_verbose = 0;
2375 printf("[context:%p] func:%p modName:%s addr:%x\n",
2376 ctxt, ctxt->func, ctxt->modName, ctxt->addr);
2378 printf(" cline:%d asmline:%d block:%d level:%d\n",
2379 ctxt->cline, ctxt->asmline, ctxt->block, ctxt->level);
2381 printf("[globals] currCtxt:%p, modules:%p, functions:%p symbols:%p\n",
2382 currCtxt, modules, functions, symbols);
2383 printf(" nStructs:%d, structs:%p, ssdirl:%s\n",
2384 nStructs, structs, ssdirl);
2386 /**************** modules *******************/
2391 printf("[modules]\n");
2392 m = setFirstItem(modules);
2397 printf(" %d) cfullname:%s, afullname:%s, name:%s\n", ++mi,
2398 m->cfullname, m->afullname, m->name);
2399 printf(" c_name:%s, asm_name:%s, ncLines:%d, nasmLines:%d\n",
2400 m->c_name, m->asm_name, m->ncLines, m->nasmLines);
2401 printf(" cLines:%p, asmLines:%p\n",
2402 m->cLines, m->asmLines);
2405 cs = m->cLines[i++];
2406 printf(" [cLines] ");
2409 printf(" (%d) addr:%x, block:%d, level:%d, src:%s\n",
2410 i, cs->addr, cs->block, cs->level, cs->src);
2411 cs = m->cLines[i++];
2414 printf("%d records", i);
2418 as = m->asmLines[i++];
2419 printf(" [asmLines] ");
2422 printf(" (%d) addr:%x, block:%d, level:%d, src:%s\n",
2423 i, as->addr, as->block, as->level, as->src);
2424 as = m->asmLines[i++];
2427 printf("%d records", i);
2431 m = setNextItem(modules);
2435 /**************** functions *******************/
2439 printf("[functions]\n");
2440 f = setFirstItem(functions);
2446 printf(" %d) sym:%p, modName:%s, mod:%p\n", i,
2447 f->sym, f->modName, f->mod);
2448 printf(" entryline:%d, aentryline:%d, exitline:%d, aexitline:%d\n",
2449 f->entryline, f->aentryline, f->exitline, f->aexitline);
2450 printf(" cfpoints:%p, afpoints:%p, laddr:%x, lline:%d\n",
2451 f->cfpoints, f->afpoints, f->laddr, f->lline);
2454 f = setNextItem(functions);
2457 printf(" %d functions\n", i);
2460 /**************** symbols *******************/
2464 printf("[symbols]\n");
2465 s = setFirstItem(symbols);
2471 printf(" %d) name:%s, size:%d, level:%d block:%d\n", i,
2472 s->name, s->size, s->level, s->block);
2473 printf(" isonstack:%d, isfunc:%d, offset:%d addr:%d\n",
2474 s->isonstack, s->isfunc, s->offset, s->addr);
2475 printf(" eaddr:%d, addr_type:%c, type:%p etype:%p\n",
2476 s->eaddr, s->addr_type, s->type, s->etype);
2477 printf(" scopetype:%c, sname:%s, rname:%s addrspace:%c\n",
2478 s->scopetype, s->sname, s->rname, s->addrspace);
2479 printf(" next:%p\n", s->next);
2482 s = setNextItem(symbols);
2485 printf(" %d symbols\n", i);
2490 /*-----------------------------------------------------------------*/
2491 /* infoRegisters - print register information */
2492 /*-----------------------------------------------------------------*/
2493 static void infoRegisters( int all, context *ctxt)
2495 static int regaddrs[] = {0x81,0x82,0x83,0xb8,0xd0,0xe0,0xf0,0};
2499 i = simGetValue (0xd0,'I',1);
2500 fprintf(stdout,"IP : 0x%04X RegisterBank %d:\nR0-7:",ctxt->addr,(i>>3)&3);
2501 for ( j = 0; j < 8 ; j++ )
2503 val = simGetValue (j,'R',1);
2504 fprintf(stdout," 0x%02lX",val);
2506 fprintf(stdout,"\n");
2507 val = simGetValue (0xe0,'I',1);
2508 fprintf(stdout,"ACC : 0x%02lX %lu %c\n",val,val,(isprint(val) ? (char)val : '.'));
2509 val = simGetValue (0xf0,'I',1);
2510 fprintf(stdout,"B : 0x%02lX %lu %c\n",val,val,(isprint(val) ? (char)val : '.'));
2511 val = simGetValue (0x82,'I',2);
2512 fprintf(stdout,"DPTR: 0x%04lX %lu\n",val,val);
2513 val = simGetValue (0x81,'I',1);
2514 fprintf(stdout,"SP : 0x%02lX (0x%04lX)\n",val,simGetValue (val-1,'B',2));
2515 fprintf(stdout,"PSW : 0x%02X | CY : %c | AC : %c | OV : %c | P : %c\n",
2516 i,(i&0x80)?'1':'0',(i&0x40)?'1':'0',(i&4)?'1':'0',(i&1)?'1':'0');
2519 fprintf(stdout,"Special Function Registers:\n");
2521 for ( i = 0x80 ; i < 0x100 ; i++ )
2524 if ( *r && *r == i )
2526 /* skip normal registers */
2530 if (applyToSetFTrue(sfrsymbols,symWithAddr,i,'I',&sym))
2532 val = simGetValue (sym->addr,sym->addrspace,sym->size);
2533 fprintf(stdout,"%s : 0x%02lx",sym->name,val);
2536 for ( j = 0 ; j < 8 ; j++ )
2539 if (applyToSetFTrue(sfrsymbols,symWithAddr,i+j,'J',&sym))
2541 //val = simGetValue (sym->addr,sym->addrspace,sym->size);
2542 fprintf(stdout," %s=%c",sym->name,(val&1)? '1':'0');
2547 fprintf(stdout,"\n");
2553 /*-----------------------------------------------------------------*/
2554 /* infoStack - print call stack information */
2555 /*-----------------------------------------------------------------*/
2556 static void infoStack(context *ctxt)
2560 context *ctx, my_context;
2561 unsigned int bp, pc, addr = ctxt->addr;
2564 for (status = frameStart(&bp,&pc); status; status = frameNext(&bp, &pc)) {
2565 ctx = discoverContext(pc, NULL, &my_context);
2568 Dprintf(D_break, ("break: infoStack: %s 0x%02x\n",func->sym->name, bp));
2570 fprintf(stdout,"#%d 0x%08x in %s () at %s:%d\n",i++,
2572 func->mod->c_name,func->lline+1);
2574 fprintf(stdout,"#%d 0x%08x\n", i++, pc);
2578 fprintf(stdout,"no stack.\n");
2581 /*-----------------------------------------------------------------*/
2582 /* cmdWhere - where command */
2583 /*-----------------------------------------------------------------*/
2584 int cmdWhere(char *s, context *cctxt)
2591 static int infomode = 0;
2592 /*-----------------------------------------------------------------*/
2593 /* cmdInfo - info command */
2594 /*-----------------------------------------------------------------*/
2595 int cmdInfo (char *s, context *cctxt)
2597 /* trim left and_right*/
2600 /* list all break points */
2601 if (strncmp(s,"break",5) == 0) {
2606 /* info frame same as frame */
2607 if (strncmp(s,"frame",5) == 0) {
2608 cmdFrame (s+5,cctxt);
2612 if (strncmp(s,"line",4) == 0) {
2614 cmdListSrc (s+4,cctxt);
2617 if (strncmp(s,"source",6) == 0)
2623 fprintf(stdout,"Source files for which symbols have been read in:\n\n");
2624 for (m = setFirstItem(modules); m ; m = setNextItem(modules))
2626 fprintf(stdout,"%s%s, %s",k ? ", ":"",m->cfullname, m->afullname);
2629 fprintf(stdout,"\n");
2633 if (!cctxt || !cctxt->func || !cctxt->func->mod)
2635 fprintf(stdout,"No source file loaded\n");
2638 m = cctxt->func->mod;
2639 fprintf(stdout,"Current source file is %s\n",m->c_name);
2640 fprintf(stdout,"Located in %s\n",m->cfullname);
2641 fprintf(stdout,"Contains %d lines.\nSource language is c.\n",
2646 if (strcmp(s,"functions") == 0)
2650 fprintf(stdout,"All defined functions:\n");
2651 for ( f = setFirstItem(functions); f ; f = setNextItem(functions))
2656 fprintf(stdout,"\nFile %s\n", m->c_name);
2658 fprintf(stdout,"%s();\n",f->sym->name);
2662 /* info stack display call stack */
2663 if (strcmp(s,"stack") == 0) {
2669 /* info stack display call stack */
2670 if (strcmp(s,"registers") == 0) {
2671 infoRegisters(0,cctxt);
2675 /* info stack display call stack */
2676 if (strcmp(s,"all-registers") == 0)
2678 infoRegisters(1,cctxt);
2682 /* info stack display call stack */
2683 if (strcmp(s,"symbols") == 0) {
2684 /* dump out symbols we have read in */
2685 fprintf(stdout,"Dumping symbols...\n");
2690 if (strcmp(s,"variables") == 0) {
2691 /* dump out symbols we have read in */
2692 fprintf(stdout,"Dumping symbols...\n");
2697 fprintf(stdout,"Undefined info command: \"%s\". Try \"help\n",s);
2702 /*-----------------------------------------------------------------*/
2703 /* cmdQuit - quit debugging */
2704 /*-----------------------------------------------------------------*/
2705 int cmdQuit (char *s, context *cctxt)
2712 /*-----------------------------------------------------------------*/
2713 /* cmdListSrc - list src */
2714 /*-----------------------------------------------------------------*/
2715 int cmdListSrc (char *s, context *cctxt)
2717 static int currline = 0;
2720 int llines = listlines;
2721 function *func = NULL;
2726 /* if the user has spcified line numer then the line number
2727 can be of the following formats
2728 LINE - just line number
2729 FILE:LINE - filename line number
2730 FILE:LINE,LASTLINE + last line
2731 FUNCTION - list a function
2732 FILE:FUNCTION - function in file */
2737 if (!cctxt || !cctxt->func || !cctxt->func->mod) {
2739 fprintf(stdout,"Sdcdb fails to have a proper context at %d.\n", __LINE__);
2744 list_mod = cctxt->func->mod;
2745 pline = strtol(s,&s,10) - 1;
2746 if (s && (s = strchr(s,',')))
2749 llines = strtol(s+1,0,10);
2759 /* if ':' present then FILE:LINE || FILE:FUNCTION */
2760 if ((bp = strchr(s,':'))) {
2765 list_mod=NULL; /* bug fix 2-09-02, moduleWithCName expects mod to be null */
2766 if (srcMode == SRC_CMODE) {
2767 if (!applyToSet(modules,moduleWithCName,s,&list_mod)) {
2768 fprintf (stderr,"No c source file named %s.\n",s);
2772 if (!applyToSet(modules,moduleWithAsmName,s,&list_mod)) {
2773 fprintf (stderr,"No source file named %s.\n",s);
2777 pline = strtol(bp,&bp,10) - 1;
2778 if (bp && (bp = strchr(bp,',')))
2780 /* FILE:LINE,LASTLINE */
2781 llines = strtol(bp+1,0,10);
2789 if (!applyToSet(functions,funcWithNameModule,bp,s,&func)) {
2790 fprintf(stdout,"Function \"%s\" not defined.\n",bp);
2793 list_mod = func->mod;
2794 if (srcMode == SRC_CMODE) {
2795 pline = func->entryline;
2796 llines = func->exitline - func->entryline + 1;
2798 pline = func->aentryline;
2799 llines = func->aexitline - func->aentryline + 1;
2809 if ((bp = strrchr(s,'\'')))
2815 if (!applyToSet(functions,funcWithName,s,&func)) {
2816 fprintf(stderr,"Function \"%s\" not defined.\n",s);
2820 list_mod = func->mod;
2821 if (srcMode == SRC_CMODE) {
2822 pline = func->entryline;
2823 llines = func->exitline - func->entryline + 1;
2825 pline = func->aentryline;
2826 llines = func->aexitline - func->aentryline + 1;
2832 /* if no line specified & we had listed
2833 before then continue from that listing */
2837 if (!cctxt || !cctxt->func || !cctxt->func->mod) {
2838 fprintf(stdout,"Missing context at %d. Try list filename:lineno\n", __LINE__);
2841 list_mod = cctxt->func->mod;
2842 if (srcMode == SRC_CMODE)
2843 pline = cctxt->cline;
2845 pline = cctxt->asmline;
2850 fprintf(stdout,"Sdcdb fails to have a valid module context at %d.\n", __LINE__);
2858 unsigned firstaddr , lastaddr ;
2859 if ( pline >= list_mod->ncLines )
2860 pline = cctxt->cline;
2861 firstaddr = lastaddr = list_mod->cLines[pline]->addr;
2862 if (!func && cctxt && cctxt->func )
2864 fprintf(stdout,"Line %d of \"%s\" starts at address 0x%08x <%s+%d>",
2866 list_mod->c_name, lastaddr,
2867 func ? func->sym->name : "?",
2868 func ? lastaddr -func->sym->addr : 0);
2870 for ( ; pline < list_mod->ncLines; pline++ )
2872 if ( list_mod->cLines[pline]->addr > lastaddr )
2874 lastaddr = list_mod->cLines[pline]->addr -1;
2878 fprintf(stdout," and ends at 0x%08x <%s+%d>.\n",
2880 func ? func->sym->name : "?",
2881 func ? lastaddr -func->sym->addr : 0);
2884 fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
2885 canonname(func->mod->cfullname),
2891 for ( i = 0 ; i < llines ; i++ ) {
2892 if (srcMode == SRC_CMODE) {
2893 if ( (pline + i) >= list_mod->ncLines )
2895 fprintf(stdout,"%d\t%s",pline + i,
2896 list_mod->cLines[pline +i]->src);
2898 if ( (pline + i) >= list_mod->nasmLines )
2900 fprintf(stdout,"%d\t%s",pline + i,
2901 list_mod->asmLines[pline +i]->src);
2904 currline = pline + i ;
2908 static unsigned long getValBasic(symbol *sym, link *type, char *val)
2924 v.f = strtod(val,NULL);
2927 v.val = strtol(val,NULL,0);
2930 if (IS_INTEGRAL(type))
2939 if (( s = strchr(val,'\'')))
2942 v.b[0] = strtol(s+2,NULL,8);
2948 v.b[0] = strtol(val,NULL,0);
2954 v.val = strtol(val,NULL,0);
2956 v.i.lo = strtol(val,NULL,0);
2958 v.val = strtol(val,NULL,0);
2961 v.val = strtol(val,NULL,0);
2966 /*-----------------------------------------------------------------*/
2967 /* printFmtInteger - print value in bin,oct,dez or hex */
2968 /*-----------------------------------------------------------------*/
2969 static void printFmtInteger(char *deffmt,int fmt, long val,
2972 static char digits[] =
2974 '0' , '1' , '2' , '3' , '4' , '5' ,
2975 '6' , '7' , '8' , '9' , 'a' , 'b' ,
2976 'c' , 'd' , 'e' , 'f' , 'g' , 'h'
2978 static int radixOfFormat[] = { 0 , 2, 8 ,10, 16 };
2979 static int olenOfSize[] = { 0 , 3, 6 , 8, 11 };
2985 if ( fmt == FMT_NON || fmt == FMT_DEZ )
2987 fprintf(stdout,deffmt,val);
2990 radix = radixOfFormat[fmt];
2993 if ( sign && val < 0 )
3001 while (val <= -radix)
3003 buf[charPos--] = digits[-(val % radix)];
3006 buf[charPos] = digits[-val];
3011 radix = olenOfSize[size];
3021 while (charPos > 39 - radix )
3023 buf[--charPos] = '0';
3028 if ( buf[charPos] != '0' )
3029 buf[--charPos] = '0';
3032 buf[--charPos] = 'x';
3033 buf[--charPos] = '0';
3037 buf[--charPos] = '-';
3039 fputs(&buf[charPos],stdout);
3042 /*-----------------------------------------------------------------*/
3043 /* printValBasic - print value of basic types */
3044 /*-----------------------------------------------------------------*/
3045 static void printValBasic(symbol *sym, link *type,
3046 char mem, unsigned addr,int size, int fmt)
3059 v.val = simGetValue(addr,mem,size);
3060 /* if this a floating point number then */
3062 fprintf(stdout,"%f",v.f);
3065 fprintf(stdout,"0x%0*lx",size<<1,v.val);
3067 if (IS_INTEGRAL(type))
3076 if ( isprint(v.val))
3077 printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'%c'"),
3078 fmt,(long)v.val,0,size);
3080 printFmtInteger((SPEC_USIGN(etype)?"0x%02x":"'\\%o'"),
3081 fmt,(long)v.val,0,size);
3087 if (SPEC_USIGN(etype))
3088 printFmtInteger("%u",fmt,(long)v.val,0,size);
3090 printFmtInteger("%d",fmt,(long)v.sval,1,size);
3092 if (SPEC_USIGN(etype))
3093 printFmtInteger("%u",fmt,(long)v.i.lo,0,size);
3095 printFmtInteger("%d",fmt,(long)v.i.lo,1,size);
3098 if (IS_BITVAR(etype))
3099 fprintf(stdout,"%c",(v.val?'1':'0'));
3101 fprintf(stdout,"0x%0*lx",size<<1,v.val);
3105 fprintf(stdout,"0x%0*lx",size<<1,v.val);
3108 /*-----------------------------------------------------------------*/
3109 /* printValFunc - prints function values */
3110 /*-----------------------------------------------------------------*/
3111 static void printValFunc (symbol *sym, int fmt)
3113 fprintf(stdout,"print function not yet implemented");
3117 do_indent(int indent) {
3119 fprintf(stdout, " ");
3123 /*-----------------------------------------------------------------*/
3124 /* printArrayValue - will print the values of array elements */
3125 /*-----------------------------------------------------------------*/
3126 static void printArrayValue (symbol *sym, link *type,
3127 char space, unsigned int addr, int fmt,
3130 link *elem_type = type->next;
3134 fprintf(stdout,"{");
3135 for (i = 0 ; i < DCL_ELEM(type) ; i++) {
3136 if (IS_AGGREGATE(elem_type)) {
3137 printValAggregates(sym,elem_type,space,addr,fmt,indent);
3140 printValBasic(sym,elem_type,space,addr,getSize(elem_type),fmt);
3143 addr += getSize(elem_type);
3144 if (i != DCL_ELEM(type) -1) {
3145 fprintf(stdout,",");
3147 fprintf(stdout,"\n");
3154 fprintf(stdout,"}");
3157 /*-----------------------------------------------------------------*/
3158 /* printStructValue - prints structures elements */
3159 /*-----------------------------------------------------------------*/
3160 static void printStructValue (symbol *sym, link *type,
3161 char space, unsigned int addr, int fmt,
3164 symbol *fields = SPEC_STRUCT(type)->fields;
3167 fprintf(stdout,"{\n");
3169 do_indent(indent + 1);
3170 fprintf(stdout,"%s = ", fields->name);
3172 if (IS_AGGREGATE(fields->type)) {
3173 printValAggregates(fields,fields->type,space, addr, fmt, indent + 1);
3175 printValBasic(fields,fields->type,space,addr,getSize(fields->type), fmt);
3177 fprintf(stdout,",\n");
3178 addr += getSize(fields->type);
3179 fields = fields->next;
3182 fprintf(stdout,"}");
3185 /*-----------------------------------------------------------------*/
3186 /* printValAggregates - print value of aggregates */
3187 /*-----------------------------------------------------------------*/
3188 static void printValAggregates (symbol *sym, link *type,
3189 char space,unsigned int addr, int fmt,
3193 if (IS_ARRAY(type)) {
3194 printArrayValue(sym, type, space, addr, fmt, indent);
3198 if (IS_STRUCT(type)) {
3199 printStructValue(sym, type, space, addr, fmt, indent);
3204 /*-----------------------------------------------------------------*/
3205 /* printOrSetSymValue - print or set value of a symbol */
3206 /*-----------------------------------------------------------------*/
3207 static int printOrSetSymValue (symbol *sym, context *cctxt,
3208 int flg, int dnum, int fmt, char *rs,
3209 char *val, char cmp )
3211 static char fmtChar[] = " todx ";
3212 static int stack = 1;
3218 char save_ch, save_ch2;
3221 /* if it is on stack then compute address & fall thru */
3224 symbol *bp = symLookup("bp",cctxt);
3227 fprintf(stdout,"cannot determine stack frame\n");
3231 sym->addr = simGetValue(bp->addr,bp->addrspace,bp->size)
3235 /* get the value from the simulator and
3243 fprintf(stdout,"$%d = ",stack++);
3246 fprintf(stdout,"%d: ", dnum);
3247 if ( fmt != FMT_NON )
3248 fprintf(stdout,"/%c ",fmtChar[fmt]);
3249 fprintf(stdout,"%s%s = ",sym->name,rs);
3259 if ( *rs == '[' && (IS_ARRAY(type) || IS_PTR(type)))
3262 while ( *rs && *rs != ']' ) rs++ ;
3265 if ( ! isdigit(*s ))
3267 /* index seems a variable */
3268 for ( s2 = s; *s2 && ( isalnum( *s2 ) || *s2 == '_'); s2++ );
3272 fields = symLookup(s,cctxt);
3276 fprintf(stdout,"Unknown variable \"%s\" for index.\n", s);
3279 /* arrays & structures first */
3280 if (! IS_INTEGRAL(fields->type))
3282 fprintf(stdout,"Wrong type of variable \"%s\" for index \n", s);
3285 n = simGetValue(fields->addr,fields->addrspace,getSize(fields->type));
3291 if ( IS_ARRAY(type) && (n < 0 || n >= DCL_ELEM(type)))
3293 fprintf(stdout,"Wrong index %d.\n", n);
3297 addr = simGetValue(addr, sym->addrspace, size);
3299 size = getSize(type);
3303 else if ( (*rs == '.' || get_member) && IS_STRUCT(type))
3306 /* search structure element */
3307 for ( rs = s; *rs && ( isalnum( *rs ) || *rs == '_'); rs++ );
3311 for (fields = SPEC_STRUCT(type)->fields; fields; fields = fields->next)
3313 if (!(strcmp(s,fields->name)))
3319 fprintf(stdout,"Unknown field \"%s\" of structure\n", s);
3322 type = fields->type;
3323 size = getSize(type);
3324 addr += fields->offset;
3326 else if ( *rs == '*' && IS_PTR(type))
3328 addr = simGetValue(addr, sym->addrspace, size);
3330 size = getSize(type);
3333 else if ( rs[0] == '-' && rs[1] == '>' &&
3334 IS_PTR(type) && IS_STRUCT(type->next))
3336 addr = simGetValue(addr, sym->addrspace, size);
3338 size = getSize(type);
3348 /* arrays & structures first */
3349 if (IS_AGGREGATE(type))
3353 fprintf(stdout,"Cannot set/compare aggregate variable\n");
3357 printValAggregates(sym,type,sym->addrspace,addr,fmt,0);
3364 printValFunc(sym,fmt);
3372 unsigned long newval;
3373 newval = getValBasic(sym,type,val);
3378 lval = simGetValue(addr,sym->addrspace,size);
3381 case '<' : return ( lval < newval ? 1:0 ); break;
3382 case '>' : return ( lval > newval ? 1:0 ); break;
3383 case 'l' : return ( lval <= newval ? 1:0 ); break;
3384 case 'g' : return ( lval >= newval ? 1:0 ); break;
3385 case '=' : return ( lval == newval ? 1:0 ); break;
3386 case '!' : return ( lval != newval ? 1:0 ); break;
3391 if ( sym->addrspace == 'I' && addr == 0xb8 )
3393 /* Symbol with address of IP */
3394 if ( cctxt ) cctxt->addr = newval;
3395 simSetPC(cctxt->addr);
3398 simSetValue(addr,sym->addrspace,size,newval);
3403 printValBasic(sym,type,sym->addrspace,addr,size,fmt);
3405 if ( flg > 0 ) fprintf(stdout,"\n");
3409 /*-----------------------------------------------------------------*/
3410 /* printStructInfo - print out structure information */
3411 /*-----------------------------------------------------------------*/
3412 static void printStructInfo (structdef *sdef)
3414 symbol *field = sdef->fields ;
3419 field = field->next;
3422 fprintf(stdout,"%s %s {\n",(i ? "struct" : "union" ), sdef->tag);
3423 field = sdef->fields;
3425 printTypeInfo (field->type);
3426 fprintf(stdout," %s ;\n",field->name);
3427 field = field->next ;
3430 fprintf(stdout,"}\n");
3434 /*-----------------------------------------------------------------*/
3435 /* printTypeInfo - print out the type information */
3436 /*-----------------------------------------------------------------*/
3437 static void printTypeInfo(link *p)
3443 switch (DCL_TYPE(p)) {
3445 printTypeInfo (p->next);
3446 fprintf(stdout,"()");
3449 printTypeInfo (p->next);
3450 fprintf(stdout,"[%d]",DCL_ELEM(p));
3456 printTypeInfo (p->next);
3457 fprintf(stdout,"(_near *)");
3461 printTypeInfo (p->next);
3462 fprintf(stdout,"(_xdata *)");
3466 printTypeInfo( p->next);
3467 fprintf(stdout,"(_code *)");
3471 printTypeInfo( p->next);
3472 fprintf(stdout,"(_generic *)");
3476 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
3478 (IS_LONG(p) ? fputs("long ",stdout) :
3479 ( IS_SHORT(p) ? fputs("short ",stdout) :
3480 fputs("int ",stdout))) ;
3483 fputs("float ",stdout);
3487 fputs ("char ",stdout);
3491 fputs("void ",stdout);
3495 printStructInfo (SPEC_STRUCT(p));
3499 fputs("sbit ",stdout);
3503 fprintf(stdout,": %d" ,SPEC_BLEN(p));
3509 /*-----------------------------------------------------------------*/
3510 /* conditionIsTrue - compare variable with constant value */
3511 /*-----------------------------------------------------------------*/
3512 int conditionIsTrue( char *s, context *cctxt)
3516 char *rs, *dup, cmp_char;
3517 dup = s = Safe_strdup(s);
3518 if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )) || !sym)
3520 else if (!( s = strpbrk(rs,"<>=!")))
3528 /* if <= or >= an other char is used
3529 * == or != not checked in switch
3533 case '>': cmp_char = 'g' ; break;
3534 case '<': cmp_char = 'l' ; break;
3539 fmt = printOrSetSymValue(sym,cctxt,0,0,0,rs,s,cmp_char);
3545 /*-----------------------------------------------------------------*/
3546 /* cmdPrint - print value of variable */
3547 /*-----------------------------------------------------------------*/
3548 int cmdPrint (char *s, context *cctxt)
3553 if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
3558 printOrSetSymValue(sym,cctxt,1,0,fmt,rs,NULL,'\0');
3563 /*-----------------------------------------------------------------*/
3564 /* cmdOutput - print value of variable without number and newline */
3565 /*-----------------------------------------------------------------*/
3566 int cmdOutput (char *s, context *cctxt)
3571 if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
3576 printOrSetSymValue(sym,cctxt,0,0,fmt,rs,NULL,'\0');
3581 /** find display entry with this number */
3583 DEFSETFUNC(dsymWithNumber)
3585 dsymbol *dsym = item;
3587 V_ARG(dsymbol **,dsymp);
3589 if ( dsym->dnum == dnum )
3597 /*-----------------------------------------------------------------*/
3598 /* displayAll - display all valid variables */
3599 /*-----------------------------------------------------------------*/
3600 void displayAll(context *cctxt)
3606 for (dsym = setFirstItem(dispsymbols);
3608 dsym = setNextItem(dispsymbols))
3610 if ( (sym = symLookup(dsym->name,cctxt)))
3611 printOrSetSymValue(sym,cctxt,2,dsym->dnum,dsym->fmt,
3612 dsym->rs,NULL,'\0');
3616 /*-----------------------------------------------------------------*/
3617 /* cmdDisplay - display value of variable */
3618 /*-----------------------------------------------------------------*/
3619 int cmdDisplay (char *s, context *cctxt)
3621 static int dnum = 1;
3625 if ( !( rs = preparePrint(s, cctxt, &fmt, &sym )))
3633 dsymbol *dsym = (dsymbol *)Safe_calloc(1,sizeof(dsymbol));
3634 dsym->dnum = dnum++ ;
3635 dsym->name = sym->name;
3637 dsym->rs = gc_strdup(rs);
3638 addSetHead(&dispsymbols,dsym);
3643 /*-----------------------------------------------------------------*/
3644 /* cmdUnDisplay - undisplay value of variable */
3645 /*-----------------------------------------------------------------*/
3646 int cmdUnDisplay (char *s, context *cctxt)
3654 for (dsym = setFirstItem(dispsymbols);
3656 dsym = setNextItem(dispsymbols))
3658 Safe_free(dsym->rs);
3661 deleteSet(&dispsymbols);
3666 dnum = strtol(s,&s,10);
3667 if (applyToSetFTrue(dispsymbols,dsymWithNumber,dnum,&dsym))
3669 deleteSetItem(&dispsymbols,dsym);
3670 Safe_free(dsym->rs);
3675 fprintf(stdout,"Arguments must be display numbers.\n");
3681 /*-----------------------------------------------------------------*/
3682 /* cmdPrintType - print type of a variable */
3683 /*-----------------------------------------------------------------*/
3684 int cmdPrintType (char *s, context *cctxt)
3688 /* trim left and right */
3692 if ((sym = symLookup(s,cctxt))) {
3693 printTypeInfo(sym->type);
3694 fprintf(stdout,"\n");
3697 "No symbol \"%s\" in current context.\n",
3703 /*-----------------------------------------------------------------*/
3704 /* cmdClrUserBp - clear user break point */
3705 /*-----------------------------------------------------------------*/
3706 int cmdClrUserBp (char *s, context *cctxt)
3709 function *func = NULL;
3711 /* clear break point location specification can be of the following
3713 a) <nothing> - break point at current location
3714 b) lineno - number of the current module
3715 c) filename:lineno - line number of the given file
3716 e) filename:function- function X in file Y (useful for static functions)
3717 f) function - function entry point
3721 fprintf(stdout,"No symbol table is loaded. Use the \"file\" command.\n");
3725 /* trim left and right */
3728 /* case a) nothing */
3729 /* if nothing given then current location : we know
3730 the current execution location from the currentContext */
3733 /* if current context is known */
3735 /* clear the break point @ current location */
3736 clearUSERbp (cctxt->addr);
3738 fprintf(stderr,"No default breakpoint address now.\n");
3743 /* case b) lineno */
3744 /* check if line number */
3746 /* get the lineno */
3749 /* if current context not present then we must get the module
3750 which has main & set the break point @ line number provided
3751 of that module : if current context known then set the bp
3752 at the line number given for the current module
3755 if (!cctxt->func->mod) {
3756 if (!applyToSet(functions,funcWithName,"main"))
3757 fprintf(stderr,"Function \"main\" not defined.\n");
3759 clearBPatModLine(func->mod,line);
3761 clearBPatModLine(cctxt->func->mod,line);
3767 if ((bp = strchr(s,':'))) {
3772 if (!applyToSet(modules,moduleWithCName,s,&mod)) {
3773 fprintf (stderr,"No source file named %s.\n",s);
3777 /* case c) filename:lineno */
3778 if (isdigit(*(bp +1))) {
3780 clearBPatModLine (mod,atoi(bp+1));
3784 /* case d) filename:function */
3785 if (!applyToSet(functions,funcWithNameModule,bp+1,s,&func))
3786 fprintf(stderr,"Function \"%s\" not defined.\n",bp+1);
3788 clearBPatModLine (mod,func->entryline);
3793 /* case e) function */
3794 if (!applyToSet(functions,funcWithName,s,&func))
3795 fprintf(stderr,"Function \"%s\" not defined.\n",s);
3797 clearBPatModLine(func->mod,func->entryline);
3803 /*-----------------------------------------------------------------*/
3804 /* cmdSimulator - send command to simulator */
3805 /*-----------------------------------------------------------------*/
3806 int cmdSimulator (char *s, context *cctxt)
3810 if (strlen(s) > 80) {
3811 printf("error 3A\n");
3815 strcat(tmpstr, "\n");
3817 waitForSim(200,NULL);
3818 fprintf(stdout,"%s",simResponse());
3822 void setMainContext()
3824 function *func = NULL;
3826 if (!applyToSet(functions,funcWithName,"_main",&func) &&
3827 !applyToSet(functions,funcWithName,"main",&func))
3830 discoverContext (func->sym->addr, func, currCtxt);
3833 function *needExtraMainFunction()
3835 function *func = NULL;
3836 if (!applyToSet(functions,funcWithName,"_main",&func))
3838 if (applyToSet(functions,funcWithName,"main",&func))
3846 static void printFrame()
3849 function *func = NULL;
3850 function *lastfunc = NULL;
3851 context *ctx, my_context;
3852 unsigned int bp, pc;
3855 if ( currentFrame < 0 )
3858 fprintf(stdout,"Bottom (i.e., innermost) frame selected; you cannot go down.\n");
3862 for (status = frameStart(&bp, &pc); status; status = frameNext(&bp, &pc))
3864 if (i >= currentFrame)
3868 if (i < currentFrame) {
3870 fprintf(stdout,"Initial frame selected; you cannot go up.\n");
3873 ctx = discoverContext(pc, NULL, &my_context);
3874 if (ctx && (func = ctx->func)) {
3875 fprintf(stdout,"#%d 0x%08x in %s () at %s:%d\n",
3876 currentFrame,pc,func->sym->name,func->mod->c_name,func->lline+1);
3877 fprintf(stdout,"\032\032%s:%d:1:beg:0x%08x\n",
3878 canonname(func->mod->cfullname),func->lline+1,func->laddr);
3880 fprintf(stdout,"#%d 0x%08x\n",
3886 /*-----------------------------------------------------------------*/
3887 /* cmdUp - Up command */
3888 /*-----------------------------------------------------------------*/
3889 int cmdUp(char *s, context *cctxt)
3893 currentFrame += strtol(s,0,10);
3901 /*-----------------------------------------------------------------*/
3902 /* cmdDown - down command */
3903 /*-----------------------------------------------------------------*/
3904 int cmdDown(char *s, context *cctxt)
3908 currentFrame -= strtol(s,0,10);
3915 /*-----------------------------------------------------------------*/
3916 /* cmdFrame - Frame command */
3917 /*-----------------------------------------------------------------*/
3918 int cmdFrame (char *s, context *cctxt)
3920 function *func = NULL;
3925 currentFrame = strtol(s,0,10);
3930 /*-----------------------------------------------------------------*/
3931 /* cmdFinish - exec till end of current function */
3932 /*-----------------------------------------------------------------*/
3933 int cmdFinish (char *s, context *ctxt)
3936 if (STACK_EMPTY(callStack)) {
3937 fprintf(stdout,"The program is not running.\n");
3942 if (srcMode == SRC_CMODE) {
3943 setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
3944 stepBpCB, ctxt->func->mod->c_name,
3945 ctxt->func->exitline);
3947 setBreakPoint (ctxt->func->sym->eaddr, CODE, STEP,
3948 stepBpCB, ctxt->func->mod->asm_name,
3949 ctxt->func->aexitline);
3959 /*-----------------------------------------------------------------*/
3960 /* cmdShow - show command */
3961 /*-----------------------------------------------------------------*/
3962 int cmdShow (char *s, context *cctxt)
3964 /* skip white space */
3967 if (strcmp(s,"copying") == 0) {
3968 fputs(copying,stdout);
3972 if (strcmp(s,"warranty") == 0) {
3973 fputs(warranty,stdout);