1 /*-------------------------------------------------------------------------
2 sdcdb.c - main source file for sdcdb debugger
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 -------------------------------------------------------------------------*/
26 char *ssdirl
= DATADIR LIB_DIR_SUFFIX
":" DATADIR LIB_DIR_SUFFIX DIR_SEPARATOR_STRING
"small" ;
34 #if defined HAVE_LIBREADLINE && HAVE_LIBREADLINE != -1
35 #define HAVE_READLINE_COMPLETITION 1
37 #ifdef HAVE_LIBREADLINE
38 #include <readline/readline.h>
39 #include <readline/history.h>
40 #endif /* HAVE_LIBREADLINE */
46 #ifdef HAVE_SYS_WAIT_H
54 char *currModName
= NULL
;
55 cdbrecs
*recsRoot
= NULL
;
56 set
*modules
= NULL
; /* set of all modules */
57 set
*functions
= NULL
; /* set of functions */
58 set
*symbols
= NULL
; /* set of symbols */
59 set
*sfrsymbols
= NULL
; /* set of symbols of sfr or sbit */
61 structdef
**structs
= NULL
; /* all structures */
63 linkrec
**linkrecs
= NULL
; /* all linkage editor records */
64 context
*currCtxt
= NULL
;
67 char userinterrupt
= 0;
73 /* fake filename & lineno to make linker */
74 char *filename
= NULL
;
78 static void commandLoop(FILE *cmdfile
);
79 #ifdef HAVE_READLINE_COMPLETITION
80 char *completionCmdSource(const char *text
, int state
);
81 char *completionCmdFile(const char *text
, int state
);
82 char *completionCmdInfo(const char *text
, int state
);
83 char *completionCmdShow(const char *text
, int state
);
84 char *completionCmdListSymbols(const char *text
, int state
);
85 char *completionCmdPrintType(const char *text
, int state
);
86 char *completionCmdPrint(const char *text
, int state
);
87 char *completionCmdDelUserBp(const char *text
, int state
);
88 char *completionCmdUnDisplay(const char *text
, int state
);
89 char *completionCmdSetUserBp(const char *text
, int state
);
90 char *completionCmdSetOption(const char *text
, int state
);
92 #define completionCmdSource NULL
93 #define completionCmdFile NULL
94 #define completionCmdInfo NULL
95 #define completionCmdShow NULL
96 #define completionCmdListSymbols NULL
97 #define completionCmdPrintType NULL
98 #define completionCmdPrint NULL
99 #define completionCmdDelUserBp NULL
100 #define completionCmdUnDisplay NULL
101 #define completionCmdSetUserBp NULL
102 #define completionCmdSetOption NULL
103 #endif /* HAVE_READLINE_COMPLETITION */
108 const char *cmd
; /* command the user will enter */
109 int (*cmdfunc
)(char *,context
*); /* function to execute when command is entered */
110 #ifdef HAVE_READLINE_COMPLETITION
111 rl_compentry_func_t
*completion_func
;
114 #endif /* HAVE_READLINE_COMPLETITION */
115 const char *htxt
; /* short help text */
117 /* NOTE:- the search is done from the top, so "break" should
118 precede the synonym "b" */
120 { "break" , cmdSetUserBp
, completionCmdSetUserBp
,
121 "{b}reak\t[LINE | FILE:LINE | FILE:FUNCTION | FUNCTION | *<address>]"
123 { "tbreak" , cmdSetTmpUserBp
, completionCmdSetUserBp
/*same as "break"*/,
124 "tbreak\t[LINE | FILE:LINE | FILE:FUNCTION | FUNCTION | *<address>]"
126 { "b" , cmdSetUserBp
, completionCmdSetUserBp
, NULL
,},
128 { "jump" , cmdJump
, NULL
,
129 "jump\tContinue program being debugged at specified line or address\n"
130 "\t[LINE | FILE:LINE | *<address>]",
132 { "clear" , cmdClrUserBp
, completionCmdSetUserBp
/*same as "break"*/,
133 "{cl}ear\t[LINE | FILE:LINE | FILE:FUNCTION | FUNCTION]"
135 { "cl" , cmdClrUserBp
, completionCmdSetUserBp
/*same as "break"*/ ,
138 { "continue" , cmdContinue
, NULL
,
139 "{c}ontinue\tContinue program being debugged, after breakpoint."
141 { "condition" , cmdCondition
, completionCmdDelUserBp
/*same as "delete"*/,
142 "condition brkpoint_number expr\tSet condition for breakpoint."
144 { "ignore" , cmdIgnore
, completionCmdDelUserBp
/*same as "delete"*/,
145 "ignore brkpoint_number count\tSet ignore count for breakpoint."
147 { "commands" , cmdCommands
, completionCmdDelUserBp
/*same as "delete"*/,
148 "commands [brkpoint_number]\tSetting commands for breakpoint."
150 { "c" , cmdContinue
, NULL
,
153 { "disassemble",cmdDisasmF
, NULL
,
154 "disassemble [startaddr [endaddress]]\tdisassemble asm commands"
156 { "delete" , cmdDelUserBp
, completionCmdDelUserBp
,
157 "{d}elete n\tclears break point number n"
159 { "display" , cmdDisplay
, completionCmdPrint
/*same as "print"*/,
160 "display [/<fmt>] [<variable>]\tprint value of given variable each time the program stops"
162 { "undisplay" , cmdUnDisplay
, completionCmdUnDisplay
,
163 "undisplay [<variable>]\tdon't display this variable or all"
165 { "down" , cmdDown
, NULL
,
166 "down\tSelect and print stack frame called by this one.\n"
167 "\tAn argument says how many frames down to go."
171 "up\tSelect and print stack frame that called this one.\n"
172 "\tAn argument says how many frames up to go."
174 { "d" , cmdDelUserBp
, completionCmdDelUserBp
,
177 { "info" , cmdInfo
, completionCmdInfo
,
178 "info <break stack frame registers all-registers line source functions symbols variables>\t"
179 "list all break points, call-stack, frame or register information"
181 { "listasm" , cmdListAsm
, NULL
,
182 "listasm {la}\tlist assembler code for the current C line"
184 { "la" , cmdListAsm
, NULL
,
187 { "ls" , cmdListSymbols
, completionCmdListSymbols
,
188 "ls,lf,lm\tlist symbols,functions,modules"
190 { "lf" , cmdListFunctions
, completionCmdListSymbols
,
193 { "lm" , cmdListModules
, completionCmdListSymbols
,
196 { "list" , cmdListSrc
, completionCmdSetUserBp
/*same as "break"*/,
197 "{l}ist\t[LINE | FILE:LINE | FILE:FUNCTION | FUNCTION]"
199 { "l" , cmdListSrc
, completionCmdSetUserBp
/*same as "break"*/,
202 { "show" , cmdShow
, completionCmdShow
,
203 "show <copying warranty>\tcopying & distribution terms, warranty"
205 { "set" , cmdSetOption
, completionCmdSetOption
,
206 "set <srcmode>\ttoggle between c/asm.\nset variable <var> = >value\tset variable to new value"
208 { "stepi" , cmdStepi
, NULL
,
209 "stepi\tStep one instruction exactly."
211 { "step" , cmdStep
, NULL
,
212 "{s}tep\tStep program until it reaches a different source line."
214 { "source" , cmdSource
, completionCmdSource
,
215 "source <FILE>\tRead commands from a file named FILE."
217 { "s" , cmdStep
, NULL
,
220 { "nexti" , cmdNexti
, NULL
,
221 "nexti\tStep one instruction, but proceed through subroutine calls."
223 { "next" , cmdNext
, NULL
,
224 "{n}ext\tStep program, proceeding through subroutine calls."
226 { "n" , cmdNext
, NULL
,
229 { "run" , cmdRun
, NULL
,
230 "{r}un\tStart debugged program. "
232 { "r" , cmdRun
, NULL
,
235 { "ptype" , cmdPrintType
, completionCmdPrintType
,
236 "{pt}ype <variable>\tprint type information of a variable"
238 { "pt" , cmdPrintType
, NULL
,
241 { "print" , cmdPrint
, completionCmdPrintType
,
242 "{p}rint <variable>\tprint value of given variable"
244 { "output" , cmdOutput
, completionCmdPrint
/*same as "print"*/,
245 "output <variable>\tprint value of given variable without $ and newline"
247 { "p" , cmdPrint
, completionCmdPrintType
,
250 { "file" , cmdFile
, completionCmdFile
,
251 "file <filename>\tload symbolic information from <filename>"
253 { "frame" , cmdFrame
, NULL
,
254 "{fr}ame\tprint information about the current Stack"
256 { "finish" , cmdFinish
, NULL
,
257 "{fi}nish\texecute till return of current function"
259 { "fi" , cmdFinish
, NULL
,
262 { "where" , cmdWhere
, NULL
,
265 { "fr" , cmdFrame
, NULL
,
268 { "f" , cmdFrame
, NULL
,
271 { "x /i" , cmdDisasm1
, NULL
,
272 "x\tdisassemble one asm command"
274 { "!" , cmdSimulator
, NULL
,
275 "!<simulator command>\tsend a command directly to the simulator"
277 { "." , cmdSimulator
, NULL
,
278 ".{cmd}\tswitch from simulator or debugger command mode"
280 { "help" , cmdHelp
, NULL
,
281 "{h|?}elp\t[CMD_NAME | 0,1,2,3(help page)] (general help or specific help)"
283 { "?" , cmdHelp
, NULL
,
286 { "h" , cmdHelp
, NULL
,
289 { "quit" , cmdQuit
, NULL
,
290 "{q}uit\t\"Watch me now. I'm going Down. My name is Bobby Brown\""
292 { "q" , cmdQuit
, NULL
,
297 /*-----------------------------------------------------------------*/
298 /* trimming functions */
299 /*-----------------------------------------------------------------*/
300 char *trim_left(char *s
)
308 char *trim_right(char *s
)
310 char *p
= &s
[strlen(s
) - 1];
312 while (p
>= s
&& isspace(*p
))
321 return trim_right(trim_left(s
));
324 /*-----------------------------------------------------------------*/
325 /* gc_strdup - make a string duplicate garbage collector aware */
326 /*-----------------------------------------------------------------*/
327 char *gc_strdup(const char *s
)
330 ret
= Safe_malloc(strlen(s
)+1);
335 /*-----------------------------------------------------------------*/
336 /* alloccpy - allocate copy and return a new string */
337 /*-----------------------------------------------------------------*/
338 char *alloccpy ( char *s
, int size
)
345 d
= Safe_malloc(size
+1);
352 /*-----------------------------------------------------------------*/
353 /* resize - resizes array of type with new size */
354 /*-----------------------------------------------------------------*/
355 void **resize (void **array
, int newSize
)
360 vptr
= Safe_realloc(array
, newSize
*(sizeof(void **)));
362 vptr
= calloc(1, sizeof(void **));
366 fprintf(stderr
, "sdcdb: out of memory\n");
373 /*-----------------------------------------------------------------*/
374 /* readCdb - reads the cdb files & puts the records into cdbLine */
376 /*-----------------------------------------------------------------*/
377 static int readCdb (FILE *file
)
383 if (!(bp
= fgets(buffer
, sizeof(buffer
), file
)))
386 currl
= Safe_calloc(1, sizeof(cdbrecs
));
391 /* make sure this is a cdb record */
392 if (strchr("STLFM",*bp
) && *(bp
+1) == ':')
394 /* depending on the record type */
400 currl
->type
= SYM_REC
;
403 currl
->type
= STRUCT_REC
;
406 currl
->type
= LNK_REC
;
409 currl
->type
= FUNC_REC
;
412 currl
->type
= MOD_REC
;
417 currl
->line
= Safe_malloc(strlen(bp
)+1);
418 strcpy(currl
->line
, bp
);
421 if (!(bp
= fgets(buffer
, sizeof(buffer
), file
)))
427 currl
->next
= Safe_calloc(1, sizeof(cdbrecs
));
431 return (recsRoot
->line
? 1 : 0);
434 /*-----------------------------------------------------------------*/
435 /* searchDirsFname - search directory list & return the filename */
436 /*-----------------------------------------------------------------*/
437 char *searchDirsFname (char *fname
)
443 /* first try the current directory */
444 if ((rfile
= fopen(fname
, "r")))
447 return strdup(fname
) ;
451 return strdup(fname
);
453 /* make a copy of the source directories */
454 dirs
= sdirs
= strdup(ssdirl
);
456 /* assume that the separator is ':'
457 and try for each directory in the search list */
458 dirs
= strtok(dirs
, ":");
461 if (dirs
[strlen(dirs
)] == '/')
462 sprintf(buffer
, "%s%s", dirs
, fname
);
464 sprintf(buffer
, "%s/%s", dirs
, fname
);
465 if ((rfile
= fopen(buffer
, "r")))
467 dirs
= strtok(NULL
, ":");
474 return strdup(buffer
);
480 // sprintf(buffer, "%s", fname);
482 while (NULL
!= (p
= strchr(p
, '_')))
484 *p
= '.'; // try again with '_' replaced by '.'
485 if (NULL
!= (found
= searchDirsFname(fname
)))
487 *p
= '_'; // not found, restore '_' and try next '_'
493 /*-----------------------------------------------------------------*/
494 /* searchDirsFopen - go thru list of directories for filename given*/
495 /*-----------------------------------------------------------------*/
496 FILE *searchDirsFopen(char *fname
)
502 /* first try the current directory */
503 if ((rfile
= fopen(fname
, "r")))
509 /* make a copy of the source directories */
510 dirs
= sdirs
= strdup(ssdirl
);
512 /* assume that the separator is ':'
513 and try for each directory in the search list */
514 dirs
= strtok(dirs
, ":");
517 sprintf(buffer
, "%s/%s", dirs
, fname
);
518 if ((rfile
= fopen(buffer
, "r")))
520 dirs
= strtok(NULL
, ":");
527 /*-----------------------------------------------------------------*/
528 /* loadFile - loads a file into module buffer */
529 /*-----------------------------------------------------------------*/
530 srcLine
**loadFile (char *name
, int *nlines
)
535 srcLine
**slines
= NULL
;
537 if (!(mfile
= searchDirsFopen(name
)))
539 fprintf(stderr
, "sdcdb: cannot open module %s -- use '--directory=<source directory> option\n", name
);
543 while ((bp
= fgets(buffer
, sizeof(buffer
), mfile
)))
547 slines
= (srcLine
**)resize((void **)slines
, *nlines
);
549 slines
[(*nlines
)-1] = Safe_calloc(1, sizeof(srcLine
));
550 slines
[(*nlines
)-1]->src
= alloccpy(bp
, strlen(bp
));
551 slines
[(*nlines
)-1]->addr
= INT_MAX
;
559 /*-----------------------------------------------------------------*/
560 /* loadModules - reads the source files into module structure */
561 /*-----------------------------------------------------------------*/
562 static void loadModules (void)
568 /* go thru the records & find out the module
569 records & load the modules specified */
570 for ( loop
= recsRoot
; loop
; loop
= loop
->next
)
574 /* for module records do */
576 currMod
= parseModule(loop
->line
, TRUE
);
577 currModName
= currMod
->name
;
579 /* search the c source file and load it into buffer */
580 currMod
->cfullname
= searchDirsFname(currMod
->c_name
);
581 currMod
->cLines
= loadFile (currMod
->c_name
, &currMod
->ncLines
);
583 /* do the same for the assembler file */
584 currMod
->afullname
= searchDirsFname(currMod
->asm_name
);
585 currMod
->asmLines
= loadFile (currMod
->asm_name
, &currMod
->nasmLines
);
588 /* if this is a function record */
590 parseFunc(loop
->line
);
593 /* if this is a structure record */
595 parseStruct(loop
->line
);
598 /* if symbol then parse the symbol */
600 parseSymbol(loop
->line
, &rs
, 2);
604 parseLnkRec(loop
->line
);
610 /*-----------------------------------------------------------------*/
611 /* generate extra sets of sfr and sbit symbols */
612 /*-----------------------------------------------------------------*/
613 static void specialFunctionRegs (void)
616 for (sym
= setFirstItem(symbols
); sym
; sym
= setNextItem(symbols
))
618 if ( sym
->addrspace
== 'I' || sym
->addrspace
== 'J')
620 addSet(&sfrsymbols
, sym
);
624 /*-----------------------------------------------------------------*/
625 /* functionPoints - determine the execution points within a func */
626 /*-----------------------------------------------------------------*/
627 static void functionPoints (void)
633 // add _main dummy for runtime env
634 if ((func
= needExtraMainFunction()))
638 /* alloc new _main function */
639 func1
= Safe_calloc(1, sizeof(function
));
641 func1
->sym
= Safe_calloc(1, sizeof(symbol
));
642 *func1
->sym
= *func
->sym
;
643 func1
->sym
->name
= alloccpy("_main", 5);
644 func1
->sym
->rname
= alloccpy("G$_main$0$", 10);
645 /* TODO must be set by symbol information */
646 func1
->sym
->addr
= 0;
647 func1
->sym
->eaddr
= 0x2f;
648 addSet(&functions
, func1
);
651 /* for all functions do */
652 for ( func
= setFirstItem(functions
); func
; func
= setNextItem(functions
))
659 Dprintf(D_sdcdb
, ("sdcdb: func '%s' has entry '0x%x' exit '0x%x'\n",
664 if (!func
->sym
->addr
&& !func
->sym
->eaddr
)
667 /* for all source lines in the module find
668 the ones with address >= start and <= end
669 and put them in the point */
671 if (! applyToSet(modules
, moduleWithName
, func
->modName
, &mod
))
674 func
->entryline
= INT_MAX
-2;
676 func
->aentryline
= INT_MAX
-2;
679 /* do it for the C Lines first */
680 for ( j
= 0 ; j
< mod
->ncLines
; j
++ )
682 if (mod
->cLines
[j
]->addr
< INT_MAX
&&
683 mod
->cLines
[j
]->addr
>= sym
->addr
&&
684 mod
->cLines
[j
]->addr
<= sym
->eaddr
)
686 /* add it to the execution point */
687 if (func
->entryline
> j
)
690 if (func
->exitline
< j
)
693 ep
= Safe_calloc(1, sizeof(exePoint
));
694 ep
->addr
= mod
->cLines
[j
]->addr
;
696 ep
->block
= mod
->cLines
[j
]->block
;
697 ep
->level
= mod
->cLines
[j
]->level
;
698 addSet(&func
->cfpoints
, ep
);
701 /* check double line execution points of module */
702 for (ep
= setFirstItem(mod
->cfpoints
); ep
; ep
= setNextItem(mod
->cfpoints
))
704 if (ep
->addr
>= sym
->addr
&& ep
->addr
<= sym
->eaddr
)
706 addSet(&func
->cfpoints
, ep
);
709 /* do the same for asm execution points */
710 for ( j
= 0 ; j
< mod
->nasmLines
; j
++ )
712 if (mod
->asmLines
[j
]->addr
< INT_MAX
&&
713 mod
->asmLines
[j
]->addr
>= sym
->addr
&&
714 mod
->asmLines
[j
]->addr
<= sym
->eaddr
)
717 /* add it to the execution point */
718 if (func
->aentryline
> j
)
719 func
->aentryline
= j
;
721 if (func
->aexitline
< j
)
724 /* add it to the execution point */
725 ep
= Safe_calloc(1, sizeof(exePoint
));
726 ep
->addr
= mod
->asmLines
[j
]->addr
;
728 addSet(&func
->afpoints
, ep
);
731 if ( func
->entryline
== INT_MAX
-2 )
733 if ( func
->aentryline
== INT_MAX
-2 )
734 func
->aentryline
= 0;
737 if (!( D_sdcdb
& sdcdbDebug
))
740 Dprintf(D_sdcdb
, ("sdcdb: function '%s' has the following C exePoints\n",
745 for (ep
= setFirstItem(func
->cfpoints
); ep
; ep
= setNextItem(func
->cfpoints
))
747 Dprintf(D_sdcdb
, ("sdcdb: {0x%x,%d} %s",
748 ep
->addr
, ep
->line
+1, mod
->cLines
[ep
->line
]->src
));
751 Dprintf(D_sdcdb
, ("sdcdb: and the following ASM exePoints\n"));
752 for (ep
= setFirstItem(func
->afpoints
); ep
; ep
= setNextItem(func
->afpoints
))
754 Dprintf (D_sdcdb
, ("sdcdb: {0x%x,%d} %s",
755 ep
->addr
, ep
->line
+1, mod
->asmLines
[ep
->line
]->src
));
763 /*-----------------------------------------------------------------*/
764 /* setEntryExitBP - set the entry & exit Break Points for functions*/
765 /*-----------------------------------------------------------------*/
766 DEFSETFUNC(setEntryExitBP
)
768 function
*func
= item
;
770 if (func
->sym
&& func
->sym
->addr
&& func
->sym
->eaddr
)
772 /* set the entry break point */
773 setBreakPoint (func
->sym
->addr
, CODE
, FENTRY
,
774 fentryCB
, func
->mod
->c_name
, func
->entryline
);
776 /* set the exit break point */
777 setBreakPoint (func
->sym
->eaddr
, CODE
, FEXIT
,
778 fexitCB
, func
->mod
->c_name
, func
->exitline
);
784 /*-----------------------------------------------------------------*/
785 /* cmdFile - load file into the debugger */
786 /*-----------------------------------------------------------------*/
787 int cmdFile (char *s
,context
*cctxt
)
797 fprintf(stdout
, "No exec file now.\nNo symbol file now.\n");
801 sprintf(buffer
, "%s.cdb", s
);
802 /* try creating the cdbfile */
803 if (!(cdbFile
= searchDirsFopen(buffer
)))
805 fprintf(stdout
, "Cannot open file\"%s\", no symbolic information loaded\n", buffer
);
809 /* allocate for context */
810 currCtxt
= Safe_calloc(1, sizeof(context
));
814 /* read in the debug information */
815 if (!readCdb (cdbFile
))
817 fprintf(stdout
,"No symbolic information found in file %s.cdb\n",s
);
822 /* parse and load the modules required */
825 /* determine the execution points for this module */
828 /* extract known special function registers */
829 specialFunctionRegs();
831 /* start the simulator & setup connection to it */
833 if (INVALID_SOCKET
== sock
)
837 openSimulator((char **)simArgs
, nsimArgs
);
838 fprintf(stdout
, "%s", simResponse());
839 /* now send the filename to be loaded to the simulator */
840 sprintf(buffer
, "%s.ihx", s
);
841 bp
= searchDirsFname(buffer
);
845 /* set the break points
846 required by the debugger . i.e. the function entry
847 and function exit break points */
848 applyToSet(functions
, setEntryExitBP
);
854 /*-----------------------------------------------------------------*/
855 /* cmdSource - read commands from file */
856 /*-----------------------------------------------------------------*/
857 int cmdSource (char *s
, context
*cctxt
)
863 if (!( cmdfile
= searchDirsFopen(s
)))
865 fprintf(stderr
,"commandfile '%s' not found\n",s
);
868 commandLoop( cmdfile
);
873 /*-----------------------------------------------------------------*/
874 /* cmdHelp - help command */
875 /*-----------------------------------------------------------------*/
876 #define TEXT_OFFSET 24
878 static void printHelpLine(const char *htxt
, int offs
)
880 static char *spaces
= NULL
;
886 spaces
= Safe_malloc(TEXT_OFFSET
+ 1);
887 memset(spaces
, ' ', TEXT_OFFSET
);
888 spaces
[TEXT_OFFSET
] = '\0';
897 while (*p
&& *p
!= '\t' && *p
!= '\n')
903 printf("%.*s%.*s", offs
, spaces
, len
, ps
); /* command text */
905 if (len
>= TEXT_OFFSET
- offs
)
906 printf("\n%s", spaces
);
908 printf("%.*s", TEXT_OFFSET
- offs
- len
, spaces
);
912 printf("%.*s\n", len
, ps
); /* help text */
919 int cmdHelp (char *s
, context
*cctxt
)
929 endline
= ((*s
- '0') * 20) + 20;
931 startline
= endline
- 20;
935 for (i
= 0 ; i
< (sizeof(cmdTab
)/sizeof(struct cmdtab
)) ; i
++)
937 if ((cmdTab
[i
].htxt
) && !strcmp(cmdTab
[i
].cmd
,s
))
939 printHelpLine(cmdTab
[i
].htxt
, 0);
946 for (i
= 0 ; i
< (sizeof(cmdTab
)/sizeof(struct cmdtab
)) ; i
++)
948 /* command string matches */
950 if ((cmdTab
[i
].htxt
) && (i
>= startline
))
951 printHelpLine(cmdTab
[i
].htxt
, 0);
959 #define MAX_CMD_LEN 512
960 static char cmdbuff
[MAX_CMD_LEN
];
961 static int sim_cmd_mode
= 0;
963 /*-----------------------------------------------------------------
964 interpretCmd - interpret and do the command. Return 0 to continue,
965 return 1 to exit program.
966 |-----------------------------------------------------------------*/
967 int interpretCmd (char *s
)
969 static char *pcmd
= NULL
;
973 /* if nothing & previous command exists then
974 execute the previous command again */
975 if (*s
== '\n' && pcmd
)
978 /* if previous command exists & is different
979 from the current command then copy it */
993 /* trim trailing blanks */
998 if (strcmp(s
,".") == 0)
1003 else if (s
[0] == '.')
1005 /* kill the preceeding '.' and pass on as SDCDB command */
1014 cmdSimulator (s
, currCtxt
);
1020 if (strcmp(s
,".") ==0)
1027 for (i
= 0 ; i
< (sizeof(cmdTab
)/sizeof(struct cmdtab
)) ; i
++)
1029 /* command string matches */
1030 if (strncmp(s
,cmdTab
[i
].cmd
,strlen(cmdTab
[i
].cmd
)) == 0)
1032 if (!cmdTab
[i
].cmdfunc
)
1035 rv
= (*cmdTab
[i
].cmdfunc
)(s
+ strlen(cmdTab
[i
].cmd
),currCtxt
);
1037 /* if full name then give the file name & position */
1038 if (fullname
&& showfull
&& currCtxt
&& currCtxt
->func
)
1041 if (srcMode
== SRC_CMODE
)
1042 fprintf(stdout
,"\032\032%s:%d:1:beg:0x%08x\n",
1043 currCtxt
->func
->mod
->cfullname
,
1044 currCtxt
->cline
+1,currCtxt
->addr
);
1046 fprintf(stdout
,"\032\032%s:%d:1:beg:0x%08x\n",
1047 currCtxt
->func
->mod
->afullname
,
1048 currCtxt
->asmline
,currCtxt
->addr
);
1049 displayAll(currCtxt
);
1054 fprintf(stdout
,"Undefined command: \"%s\". Try \"help\".\n",s
);
1060 static FILE *actualcmdfile
=NULL
;
1061 static char *actualcmds
=NULL
;
1062 static int stopcmdlist
;
1063 /*-----------------------------------------------------------------*/
1064 /* getNextCmdLine get additional lines used by special commands */
1065 /*-----------------------------------------------------------------*/
1066 char *getNextCmdLine(void)
1068 //fprintf(stderr,"getNextCmdLine() actualcmdfile=%p\n",actualcmdfile);
1071 fprintf(stdout
,">");
1073 if (fgets(cmdbuff
,sizeof(cmdbuff
),actualcmdfile
) == NULL
)
1075 // fprintf(stderr,"getNextCmdLine() returns null\n");
1078 //fprintf(stderr,"getNextCmdLine() returns: %s",cmdbuff);
1082 void setCmdLine( char *cmds
)
1087 void stopCommandList()
1092 #ifdef HAVE_READLINE_COMPLETITION
1093 // helper function for doing readline completion.
1094 // input: toknum=index of token to find (0=first token)
1095 // output: *start=first character index of the token,
1096 // or the index of '\0'
1097 // *end=first blank character right after the token,
1098 // or the index of '\0'
1099 // return value: 0=token not found, 1=token found
1100 int completionHelper_GetTokenNumber(int toknum
, int *start
, int *end
)
1103 const char *p
= rl_line_buffer
;
1107 while (p
[*end
] != 0)
1109 // start = skip blanks from end
1111 while (p
[*start
] && isspace( p
[*start
] ))
1114 // end = skip non-blanks from start
1116 while (p
[*end
] && !isspace( p
[*end
] ))
1119 if (tok_index
== toknum
)
1125 return 0; // not found
1128 // helper function for doing readline completion.
1129 // returns the token number that we were asked to complete.
1130 // 0=first token (command name), 1=second token...
1131 int completionHelper_GetCurrTokenNumber()
1133 int toknum
, start
, end
;
1135 toknum
= start
= end
= 0;
1138 if (!completionHelper_GetTokenNumber(toknum
, &start
, &end
))
1141 if (rl_point
<= end
)
1148 // exapmle for vallist on entry:
1149 // "copying\0warranty\0";
1150 char *completionCompleteFromStrList(const char *text
, int state
, char *vallist
)
1158 ptr
+= strlen(ptr
)+1;
1163 if ( (len
< strlen(ptr
)) && !strncmp(text
, ptr
, len
) )
1166 ptr
+= strlen(ptr
)+1;
1172 // readline library completion function.
1173 // completes from the list of all sdcdb command.
1174 char *completionCommandsList(const char *text
, int state
)
1178 if (state
== 0) // new completion?
1179 { // yes, only complete if this is the first token on the line.
1180 int ok
= 0; // try to complete this request?
1181 char *p
= rl_line_buffer
;
1184 while (p
&& isspace(*p
))
1186 if (p
-rl_line_buffer
== rl_point
)
1191 while (p
&& !isspace(*p
))
1193 if (p
-rl_line_buffer
== rl_point
)
1198 if (p
-rl_line_buffer
== rl_point
)
1202 return NULL
; // no more completions
1204 i
= 0; // ok, gonna complete. initialize static variable.
1211 for (; i
< (sizeof(cmdTab
)/sizeof(struct cmdtab
)) ; i
++)
1213 int len
= strlen(text
);
1214 if (len
<= strlen(cmdTab
[i
].cmd
))
1216 if (strncmp(text
,cmdTab
[i
].cmd
,len
) == 0)
1217 return strdup(cmdTab
[i
].cmd
);
1221 return NULL
; // no more completions
1224 // readline library completion function.
1225 // completes from the list of symbols.
1226 char *completionSymbolName(const char *text
, int state
)
1230 if (state
== 0) // new completion?
1231 sy
= setFirstItem(symbols
); // yes
1233 sy
= setNextItem(symbols
);
1235 for (; sy
!= NULL
; )
1237 int len
= strlen(text
);
1238 if (len
<= strlen(sy
->name
))
1240 if (strncmp(text
,sy
->name
,len
) == 0)
1241 return strdup(sy
->name
);
1244 sy
= setNextItem(symbols
);
1249 // readline library completion function.
1250 // completes from the list known functions.
1251 // module_flag - if false, ignore function module name
1252 // if true, compare against module_name:fnction_name
1253 char *completionFunctionName(const char *text
, int state
, int module_flag
)
1257 if (state
== 0) // new completion?
1258 f
= setFirstItem(functions
); // yes
1260 f
= setNextItem(functions
);
1264 int text_len
= strlen(text
);
1268 if (text_len
<= strlen(f
->sym
->name
) &&
1269 !strncmp(text
,f
->sym
->name
,text_len
))
1271 return strdup(f
->sym
->name
);
1276 int modname_len
= strlen(f
->mod
->c_name
);
1277 int funcname_len
= strlen(f
->sym
->name
);
1278 char *functext
= malloc(modname_len
+funcname_len
+2);
1280 strcpy(functext
,f
->mod
->c_name
);
1281 strcat(functext
,":");
1282 strcat(functext
,f
->sym
->name
);
1283 if (text_len
<= strlen(functext
) &&
1284 !strncmp(text
,functext
,text_len
))
1293 f
= setNextItem(functions
);
1298 // readline library completion function.
1299 // completes from the list known modules.
1300 char *completionModuleName(const char *text
, int state
)
1304 if (state
== 0) // new completion?
1305 m
= setFirstItem(modules
); // yes
1307 m
= setNextItem(modules
);
1311 int len
= strlen(text
);
1312 if ( (len
<= strlen(m
->c_name
)) &&
1313 !strncmp(text
,m
->c_name
,len
) )
1315 return strdup(m
->c_name
);
1318 if ( (len
<= strlen(m
->asm_name
)) &&
1319 (strncmp(text
,m
->asm_name
,len
) == 0) )
1321 return strdup(m
->asm_name
);
1324 m
= setNextItem(modules
);
1329 // readline completion function for "file" command
1330 char *completionCmdFile(const char *text
, int state
)
1334 if (completionHelper_GetCurrTokenNumber() != 1)
1338 // we use filename_completion_function() from the readline library.
1339 return rl_filename_completion_function(text
, state
);
1342 // readline completion function for "source" command
1343 char *completionCmdSource(const char *text
, int state
)
1345 return completionCmdFile(text
, state
);
1348 // readline completion function for "info" command
1349 char *completionCmdInfo(const char *text
, int state
)
1353 if (completionHelper_GetCurrTokenNumber() != 1)
1357 return completionCompleteFromStrList(text
, state
,
1358 "break\0stack\0frame\0registers\0all-registers\0"
1359 "line\0source\0functions\0symbols\0variables\0");
1362 // readline completion function for "show" command
1363 char *completionCmdShow(const char *text
, int state
)
1367 if (completionHelper_GetCurrTokenNumber() != 1)
1370 return completionCompleteFromStrList(text
, state
, "copying\0warranty\0");
1373 // readline completion function for "la" command
1374 char *completionCmdListSymbols(const char *text
, int state
)
1378 if (completionHelper_GetCurrTokenNumber() != 1)
1381 return completionCompleteFromStrList(text
, state
, "v1\0v2\0");
1384 char *completionCmdPrintType(const char *text
, int state
)
1388 if (completionHelper_GetCurrTokenNumber() != 1)
1391 return completionSymbolName(text
, state
);
1394 char *completionCmdPrint(const char *text
, int state
)
1398 int i
= completionHelper_GetCurrTokenNumber();
1399 if (i
!= 1 && i
!= 2)
1402 return completionSymbolName(text
, state
);
1405 char *completionCmdDelUserBp(const char *text
, int state
)
1412 if (completionHelper_GetCurrTokenNumber() != 1)
1418 bp
= hTabFirstItem(bptable
,&k
);
1422 bp
= hTabNextItem(bptable
,&k
);
1425 for ( ; bp
; bp
= hTabNextItem(bptable
,&k
))
1427 if (bp
->bpType
== USER
|| bp
->bpType
== TMPUSER
)
1430 sprintf(buff
, "%d", bp
->bpnum
);
1431 return strdup(buff
);
1438 // readline completion function for "undisplay" command
1439 char *completionCmdUnDisplay(const char *text
, int state
)
1441 static dsymbol
*dsym
;
1445 if (completionHelper_GetCurrTokenNumber() != 1)
1447 dsym
= setFirstItem(dispsymbols
);
1453 sprintf(buff
, "%d", dsym
->dnum
);
1454 dsym
= setNextItem(dispsymbols
);
1455 return strdup(buff
);
1460 char *completionCmdSetUserBp(const char *text
, int state
)
1462 static int internal_state
; // 0=calling completionFunctionName(text, state, 0)
1463 // 1=calling completionFunctionName(text, 1, 1)
1466 if (completionHelper_GetCurrTokenNumber() != 1)
1471 if (internal_state
== 0)
1473 char *p
= completionFunctionName(text
, state
, 0);
1477 return completionFunctionName(text
, 0, 1);
1481 return completionFunctionName(text
, 1, 1);
1485 char *completionCmdSetOption(const char *text
, int state
)
1493 currtok
= completionHelper_GetCurrTokenNumber();
1495 if (currtok
== 2 || currtok
== 3)
1497 // make sure token 1 == "variable"
1498 completionHelper_GetTokenNumber(1, &start
, &end
);
1499 if (end
- start
!= 8 ||
1500 strncmp(rl_line_buffer
+start
,"variable",8))
1505 else if (currtok
!= 1)
1514 return completionCompleteFromStrList(text
, state
,
1518 "srcmode\0listsize\0variable\0");
1520 return completionSymbolName(text
, state
);
1523 return completionCompleteFromStrList(text
, state
, "=\0");
1528 // our main readline completion function
1529 // calls the other completion functions as needed.
1530 char *completionMain(const char *text
, int state
)
1532 static rl_compentry_func_t
*compl_func
;
1533 int i
, start
, end
, len
;
1535 if (state
== 0) // new completion?
1539 if (completionHelper_GetCurrTokenNumber() == 0)
1541 compl_func
= &completionCommandsList
;
1544 { // not completing first token, find the right completion
1545 // function according to the first token the user typed.
1546 completionHelper_GetTokenNumber(0, &start
, &end
);
1549 for (i
=0; i
< (sizeof(cmdTab
)/sizeof(struct cmdtab
)) ; i
++)
1551 if (!strncmp(rl_line_buffer
+start
,cmdTab
[i
].cmd
,len
) &&
1552 cmdTab
[i
].cmd
[len
] == '\0')
1554 compl_func
= cmdTab
[i
].completion_func
;
1563 return (*compl_func
)(text
,state
);
1565 #endif /* HAVE_READLINE_COMPLETITION */
1567 /*-----------------------------------------------------------------*/
1568 /* commandLoop - the main command loop or loop over command file */
1569 /*-----------------------------------------------------------------*/
1570 static void commandLoop(FILE *cmdfile
)
1572 char *line
, save_ch
, *s
;
1573 #ifdef HAVE_LIBREADLINE
1576 FILE *old_rl_instream
, *old_rl_outstream
;
1577 actualcmdfile
= cmdfile
;
1579 #ifdef HAVE_READLINE_COMPLETITION
1580 rl_completion_entry_function
= completionMain
;
1581 #endif /* HAVE_READLINE_COMPLETITION */
1582 rl_readline_name
= "sdcdb"; // Allow conditional parsing of the ~/.inputrc file.
1584 // save readline's input/output streams
1585 // this is done to support nested calls to commandLoop()
1586 // i wonder if it works...
1587 old_rl_instream
= rl_instream
;
1588 old_rl_outstream
= rl_outstream
;
1590 // set new streams for readline
1591 if ( cmdfile
== stdin
)
1592 rl_instream
= rl_outstream
= NULL
; // use stdin/stdout pair
1594 rl_instream
= rl_outstream
= cmdfile
;
1598 if ( cmdfile
== stdin
)
1601 line_read
= (char*)readline ("(sim) ");
1603 line_read
= (char*)readline ("(sdcdb) ");
1606 line_read
= (char*)readline ("");
1610 /* If the line has any text in it,
1611 save it on the history. */
1612 if (line_read
&& *line_read
)
1613 add_history (line_read
);
1615 // FIX: readline returns malloced string.
1616 // should check the source to verify it can be used
1617 // directly. for now - just copy it to cmdbuff.
1618 strcpy(cmdbuff
,line_read
);
1619 #if defined(_WIN32) || defined(HAVE_RL_FREE)
1630 #else /* HAVE_LIBREADLINE */
1631 actualcmdfile
= cmdfile
;
1635 if ( cmdfile
== stdin
)
1640 fprintf(stdout
,"(sdcdb) ");
1643 //fprintf(stderr,"commandLoop actualcmdfile=%p cmdfile=%p\n",
1644 // actualcmdfile,cmdfile);
1645 if (fgets(cmdbuff
,sizeof(cmdbuff
),cmdfile
) == NULL
)
1647 #endif /* HAVE_LIBREADLINE */
1649 if (interpretCmd(cmdbuff
))
1652 while ( actualcmds
)
1654 strcpy(cmdbuff
,actualcmds
);
1657 for ( line
= cmdbuff
; *line
; line
= s
)
1659 if ( (s
=strchr(line
,'\n')))
1666 s
+= strlen( line
);
1669 if (interpretCmd( line
))
1680 #ifdef HAVE_LIBREADLINE
1681 // restore readline's input/output streams
1682 rl_instream
= old_rl_instream
;
1683 rl_outstream
= old_rl_outstream
;
1684 #endif /* HAVE_LIBREADLINE */
1687 /*-----------------------------------------------------------------*/
1688 /* printVersionInfo - print the version information */
1689 /*-----------------------------------------------------------------*/
1690 static void printVersionInfo(void)
1693 "SDCDB is free software and you are welcome to distribute copies of it\n"
1694 "under certain conditions; type \"show copying\" to see the conditions.\n"
1695 "There is absolutely no warranty for SDCDB; type \"show warranty\" for details.\n"
1696 "SDCDB " SDCDB_VERSION
". Copyright (C) 1999 Sandeep Dutta (sandeep.dutta@usa.net)\n");
1699 /*-----------------------------------------------------------------*/
1700 /* printHelp - print help */
1701 /*-----------------------------------------------------------------*/
1702 static void printHelp(void)
1704 fprintf(stdout
, "Type ? for help\n");
1707 /*-----------------------------------------------------------------*/
1708 /* escapeQuotes - escape double quotes */
1709 /*-----------------------------------------------------------------*/
1712 static const char *escapeQuotes(const char *arg
)
1714 #define extend(n) do { if ((size_t)(ps - str + (n)) > strLen) str = Safe_realloc (str, strLen += CHUNK); } while (0)
1716 static char *str
= NULL
;
1717 static size_t strLen
= 0;
1724 str
= Safe_malloc (strLen
);
1727 for (ps
= str
, pa
= arg
; '\0' != *pa
; ++pa
)
1732 *ps
++ = '\\'; /* excape the quote */
1747 /*-----------------------------------------------------------------*/
1748 /* argsToCmdLine - concatenate arguments ti command line */
1749 /*-----------------------------------------------------------------*/
1750 char *argsToCmdLine(char **args
, int nargs
)
1752 static char *cmd
= NULL
;
1753 static size_t cmdLen
= 0;
1759 cmd
= Safe_malloc(CHUNK
);
1763 for (i
= 0; i
< nargs
; ++i
)
1766 size_t allocLen
= 0;
1771 ++allocLen
; /* space for space character */
1773 if (NULL
!= strchr(args
[i
], ' '))
1776 allocLen
+= 2; /* space for inital and final quote */
1777 arg
= escapeQuotes(args
[i
]);
1784 argLen
= strlen(arg
);
1785 allocLen
+= argLen
; /* space for argument */
1787 /* extend the buffer */
1788 if (cmdPos
+ allocLen
>= cmdLen
)
1794 while (cmdPos
+ allocLen
>= cmdLen
);
1795 cmd
= Safe_realloc(cmd
, cmdLen
);
1800 cmd
[cmdPos
++] = ' '; /* append space character */
1805 cmd
[cmdPos
++] = '"'; /* append initial quote */
1808 memcpy(&cmd
[cmdPos
], arg
, argLen
); /* append argument */
1812 cmd
[cmdPos
++] = '"'; /* append final quote */
1820 static void usage(void)
1823 "-{h|?}, --help\tDisplay this help\n"
1824 "-v\tVerbose: show the simulator invocation commald line\n"
1825 "--directory=<dir>\tSearch modules in <dir> directory\n"
1826 "-fullname\tGive the file name & position\n"
1827 "-cd=<dir>, -cd <dir>\tChange directory to <dir>\n"
1829 "-d=<msk>\tSet debugging to <mask>\n"
1831 "-contsim\tContinuous simulation\n"
1833 "-m<model>\tModel string: avr, xa, z80\n"
1834 "-z\tAll remaining options are for simulator";
1836 const char *simArgs
=
1837 "-t <cpu>, -cpu <cpu>\tCpu type\n"
1838 "-frequency <frequency>, -X <frequency>\tXTAL Frequency\n"
1839 "-{s|S} <serial_port>\tSerial port\n"
1840 "-k\tNetwork serial port";
1842 printf("usage: sdcdb [args] [simulator args] [filename]\n"
1844 printHelpLine(args
, 2);
1845 printf("simulator args:\n");
1846 printHelpLine(simArgs
, 2);
1851 /*-----------------------------------------------------------------*/
1852 /* parseCmdLine - parse the commandline arguments */
1853 /*-----------------------------------------------------------------*/
1854 static void parseCmdLine (int argc
, char **argv
)
1857 char *filename
= NULL
;
1858 int passon_args_flag
= 0; /* if true, pass on args to simulator */
1861 Dprintf(D_sdcdb
, ("sdcdb: parseCmdLine\n"));
1864 for (i
= 1; i
< argc
; i
++)
1866 if (passon_args_flag
) /* if true, pass on args to simulator */
1868 simArgs
[nsimArgs
++] = strdup(argv
[i
]);
1872 /* if this is an option */
1873 if (argv
[i
][0] == '-')
1876 if (strcmp(argv
[i
], "-h") == 0 ||
1877 strcmp(argv
[i
], "-?") == 0 ||
1878 strcmp(argv
[i
], "--help") == 0)
1885 if (strcmp(argv
[i
], "-v") == 0)
1891 /* if directory then mark directory */
1892 if (strncmp(argv
[i
], "--directory=", 12) == 0)
1896 ssdirl
= &argv
[i
][12];
1900 char *p
= Safe_malloc(strlen(ssdirl
)+strlen(&argv
[i
][12])+2);
1901 strcat(strcat(strcpy(p
,&argv
[i
][12]),":"),ssdirl
);
1907 if (strcmp(argv
[i
], "-fullname") == 0)
1913 if (strncmp(argv
[i
], "-cd=", 4) == 0)
1915 if (0 > chdir(&argv
[i
][4]))
1917 fprintf(stderr
, "can't change directory to %s\n", &argv
[i
][4]);
1923 if (strcmp(argv
[i
], "-cd") == 0)
1926 if (0 > chdir(argv
[i
]))
1928 fprintf(stderr
, "can't change directory to %s\n", argv
[i
]);
1935 if (strncmp(argv
[i
], "-d=", 3) == 0)
1937 sdcdbDebug
= strtol(&argv
[i
][3],0,0);
1941 if (strcmp(argv
[i
], "-contsim") == 0)
1946 if (strcmp(argv
[i
], "-q") == 0)
1952 if (strncmp(argv
[i
],"-m", 2) == 0)
1954 strncpy(model_str
, &argv
[i
][2], 15);
1955 if (strcmp(model_str
, "avr") == 0)
1956 simArgs
[0] = "savr";
1957 else if (strcmp(model_str
, "xa") == 0)
1959 else if (strcmp(model_str
, "z80") == 0)
1960 simArgs
[0] = "sz80";
1964 /* -z all remaining options are for simulator */
1965 if (strcmp(argv
[i
], "-z") == 0)
1967 passon_args_flag
= 1;
1971 /* the simulator arguments */
1974 if (strcmp(argv
[i
], "-t") == 0 ||
1975 strcmp(argv
[i
], "-cpu") == 0)
1977 simArgs
[nsimArgs
++] = "-t";
1978 simArgs
[nsimArgs
++] = strdup(argv
[++i
]);
1982 /* XTAL Frequency */
1983 if (strcmp(argv
[i
], "-X") == 0 ||
1984 strcmp(argv
[i
], "-frequency") == 0)
1986 simArgs
[nsimArgs
++] = "-X";
1987 simArgs
[nsimArgs
++] = strdup(argv
[++i
]);
1992 if ((strcmp(argv
[i
], "-S") == 0) ||
1993 (strcmp(argv
[i
], "-s") == 0))
1995 simArgs
[nsimArgs
++] = strdup(argv
[i
]);
1996 simArgs
[nsimArgs
++] = strdup(argv
[++i
]);
2000 /* network serial port */
2001 if ((strcmp(argv
[i
], "-k") == 0))
2003 simArgs
[nsimArgs
++] = strdup(argv
[i
]);
2004 simArgs
[nsimArgs
++] = strdup(argv
[++i
]);
2008 fprintf(stderr
,"unknown option %s --- ignored\n", argv
[i
]);
2014 /* must be file name */
2018 "too many filenames .. parameter '%s' ignored\n",
2023 file
= fopen(argv
[i
], "r");
2026 /* file exists: strip the cdb or ihx extension */
2027 char *p
= strrchr(argv
[i
], '.');
2031 (0 == strcmp(p
, ".cdb") || 0 == strcmp(p
, ".ihx")))
2041 cmdFile(filename
,NULL
);
2044 printf("+ %s\n", argsToCmdLine(simArgs
, nsimArgs
));
2047 /*-----------------------------------------------------------------*/
2048 /* setsignals - catch some signals */
2049 /*-----------------------------------------------------------------*/
2062 /* may be interrupt from user: stop debugger and also simulator */
2069 /* the only child can be the simulator */
2070 static void sigchld(int sig
)
2072 /* the only child can be the simulator */
2082 signal(SIGINT
, sigintr
);
2083 signal(SIGABRT
, bad_signal
);
2084 signal(SIGTERM
, bad_signal
);
2087 signal(SIGHUP
, SIG_IGN
);
2088 signal(SIGCONT
, SIG_IGN
);
2089 signal(SIGCHLD
, sigchld
);
2091 signal(SIGALRM
, bad_signal
);
2092 //signal(SIGFPE, bad_signal);
2093 //signal(SIGILL, bad_signal);
2094 signal(SIGPIPE
, bad_signal
);
2095 signal(SIGQUIT
, bad_signal
);
2096 //signal(SIGSEGV, bad_signal);
2100 /*-----------------------------------------------------------------*/
2102 /*-----------------------------------------------------------------*/
2104 int main ( int argc
, char **argv
)
2106 simArgs
[nsimArgs
++] = "s51";
2107 simArgs
[nsimArgs
++] = "-P";
2108 simArgs
[nsimArgs
++] = "-r";
2109 simArgs
[nsimArgs
++] = "9756";
2111 /* parse command line */
2112 parseCmdLine(argc
, argv
);
2116 printf("WARNING: SDCDB is EXPERIMENTAL.\n");