1 /*-------------------------------------------------------------------------
2 symtab.c - Header file for symbol table 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 -------------------------------------------------------------------------*/
27 extern char *currModName ;
28 structdef *structWithName (char *);
30 /*------------------------------------------------------------------*/
31 /* getSize - returns size of a type chain in bits */
32 /*------------------------------------------------------------------*/
33 unsigned int getSize ( link *p )
35 /* if nothing return 0 */
39 if ( IS_SPEC(p) ) { /* if this is the specifier then */
41 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
43 return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ;
51 return SPEC_STRUCT(p)->size ;
57 return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ;
63 /* this is a specifier */
64 switch (DCL_TYPE(p)) {
68 return DCL_ELEM(p) * getSize (p->next) ;
85 /*-----------------------------------------------------------------*/
86 /* parseFunc - creates a function record entry */
87 /*-----------------------------------------------------------------*/
88 void parseFunc (char *line)
93 Safe_calloc(1,func,sizeof(function));
94 func->sym = parseSymbol(line,&rs);
95 func->sym->isfunc = 1;
96 func->modName = currModName ;
97 while(*rs != ',') rs++;
99 sscanf(rs,"%d,%d,%d",&i,
100 &(SPEC_INTN(func->sym->etype)),
101 &(SPEC_BANK(func->sym->etype)));
102 SPEC_INTRTN(func->sym->etype) = i;
103 addSet(&functions,func);
106 /*-----------------------------------------------------------------*/
107 /* parseTypeInfo - parse the type info of a symbol expects the type*/
108 /* info to be of the form */
109 /* ({<size>}<type info chain) */
110 /*-----------------------------------------------------------------*/
111 static char *parseTypeInfo (symbol *sym, char *s)
115 s += 2; /* go past the ({ */
117 sym->size = strtol (s,&bp,10);
118 /* bp now points to '}' ... go past it */
120 while (*s != ')') { /* till we reach the end */
122 Safe_calloc(1,type,sizeof(link));
125 /* is a declarator */
130 DCL_TYPE(type) = FUNCTION;
134 DCL_TYPE(type) = GPOINTER;
138 DCL_TYPE(type) = CPOINTER;
142 DCL_TYPE(type) = FPOINTER;
146 DCL_TYPE(type) = POINTER;
150 DCL_TYPE(type) = IPOINTER;
154 DCL_TYPE(type) = PPOINTER;
159 DCL_TYPE(type) = ARRAY ;
160 DCL_ELEM(type) = strtol(s,&s,10);
165 type->class = SPECIFIER ;
169 SPEC_NOUN(type) = V_INT;
174 SPEC_NOUN(type) = V_INT;
179 SPEC_NOUN(type) = V_CHAR ;
183 SPEC_NOUN(type) = V_VOID;
187 SPEC_NOUN(type) = V_FLOAT;
192 SPEC_NOUN(type) = V_STRUCT;
194 char *ss = strtok(strdup(s),",):");
196 SPEC_STRUCT(type) = structWithName(ss);
202 SPEC_NOUN(type) = V_SBIT;
205 SPEC_NOUN(type) = V_BIT;
207 SPEC_BSTR(type) = strtol(s,&s,10);
209 SPEC_BLEN(type) = strtol(s,&s,10);
212 while (*s != ':') s++;
215 SPEC_USIGN(type) = 0;
217 SPEC_USIGN(type) = 1;
221 /* add the type to the symbol's type chain */
223 sym->etype = sym->etype->next = type;
225 sym->type = sym->etype = type;
232 /*-----------------------------------------------------------------*/
233 /* symFromRec - parse a symbol record and extract and create a sym */
234 /* expects the input string to be of the form */
235 /* {G|F<filename>|L<functionName>}'$'<name>'$'<level> */
236 /* '$'<block><type info> */
237 /*-----------------------------------------------------------------*/
238 symbol *parseSymbol (char *s, char **rs)
243 Safe_calloc(1,nsym,sizeof(symbol));
245 /* copy over the mangled name */
246 while (*bp != '(') bp++;
248 nsym->rname = alloccpy(s,bp - s);
250 /* if this is a Global Symbol */
251 nsym->scopetype = *s;
253 if (nsym->scopetype != 'G') {
254 /* get the function name it is local to */
256 while (*s != '$') s++;
257 nsym->sname = alloccpy(bp,s - bp);
260 /* next get the name */
262 while ( *s != '$' ) s++;
263 nsym->name = alloccpy(bp,s - bp);
266 /* get the level number */
267 nsym->level = strtol (s,&bp,10);
269 /* skip the '$' & get the block number */
270 nsym->block = strtol (s,&bp,10);
272 s = parseTypeInfo(nsym,bp);
274 /* get the address space after going past the comma */
279 nsym->isonstack = strtol(s,&s,10);
280 /* get the stack offset */
282 nsym->offset = strtol(s,&s,10);
285 addSet(&symbols,nsym);
291 /*-----------------------------------------------------------------*/
292 /* parseStruct - parses a structure record expected in format */
293 /* {F<filename>}$<tag>[()()()...] */
294 /*-----------------------------------------------------------------*/
295 structdef *parseStruct (char *s)
300 symbol *fields = NULL;
302 while (*s != '$') s++;
305 while (*s != '[') s++ ;
306 name = alloccpy(bp,s - bp);
307 nsdef = structWithName(name);
308 nsdef->fields = NULL;
310 while (*s && *s != ']') {
313 while (!isdigit(*s)) s++;
314 offset = strtol(s,&s,10);
315 while (*s != ':') s++;
317 sym = parseSymbol(s,&s);
318 sym->offset = offset ;
321 fields = nsdef->fields = sym;
323 fields = fields->next = sym;
330 /*-----------------------------------------------------------------*/
331 /* parseModule - creates a module with a given name */
332 /*-----------------------------------------------------------------*/
333 module *parseModule (char *s, bool createName )
338 Safe_calloc(1,nmod,sizeof(module));
340 addSet (&modules,nmod);
343 /* create copy file name */
347 sprintf(buffer,"%s.c",s);
349 Safe_calloc(1,nmod->c_name,strlen(buffer)+1);
350 strcpy(nmod->c_name,buffer);
352 sprintf(buffer,"%s.asm",s);
353 Safe_calloc(1,nmod->asm_name,strlen(buffer)+1);
354 strcpy(nmod->asm_name,buffer);
360 /*-----------------------------------------------------------------*/
361 /* moduleWithName - finds and returns a module with a given name */
362 /*-----------------------------------------------------------------*/
363 DEFSETFUNC(moduleWithName)
367 V_ARG(module **,rmod);
372 if (strcmp(mod->name,s) == 0) {
380 /*-----------------------------------------------------------------*/
381 /* moduleWithCName - finds and returns a module with a given c_name*/
382 /*-----------------------------------------------------------------*/
383 DEFSETFUNC(moduleWithCName)
387 V_ARG(module **,rmod);
391 if (strcmp(mod->c_name,s) == 0) {
399 /*-----------------------------------------------------------------*/
400 /* moduleWithAsmName - finds & returns a module with given asm_name*/
401 /*-----------------------------------------------------------------*/
402 DEFSETFUNC(moduleWithAsmName)
406 V_ARG(module **,rmod);
410 if (strcmp(mod->asm_name,s) == 0) {
419 /*-----------------------------------------------------------------*/
420 /* structWithName - returns a structure with a given name */
421 /*-----------------------------------------------------------------*/
422 structdef *structWithName (char *s)
427 /* go thru the struct table looking for a match */
428 for ( i = 0 ; i < nStructs ; i++ ) {
430 if (strcmp(currModName,structs[i]->sname) == 0 &&
431 strcmp(s,structs[i]->tag) == 0)
435 Safe_calloc(1,nsdef,sizeof(structdef));
436 nsdef->tag = alloccpy(s,strlen(s));
437 nsdef->sname = currModName ;
440 structs = (struct structdef **)resize((void **)structs,nStructs);
441 structs[nStructs-1] = nsdef;
445 /*-----------------------------------------------------------------*/
446 /* symWithRName - look for symbol with mangled name = parm */
447 /*-----------------------------------------------------------------*/
448 DEFSETFUNC(symWithRName)
452 V_ARG(symbol **,rsym);
457 if (strcmp(sym->rname,s) == 0) {
465 /*-----------------------------------------------------------------*/
466 /* funcWithRName - look for function with name */
467 /*-----------------------------------------------------------------*/
468 DEFSETFUNC(funcWithRName)
470 function *func = item;
472 V_ARG(function **,rfunc);
477 if (strcmp(func->sym->rname,s) == 0) {
485 /*-----------------------------------------------------------------*/
486 /* symLocal - local symbol respecting blocks & levels */
487 /*-----------------------------------------------------------------*/
495 V_ARG(symbol **,rsym);
497 if (strcmp(name,sym->name) == 0 && /* name matches */
498 sym->scopetype != 'G' && /* local scope */
499 (sym->sname && strcmp(sym->sname,sname) == 0) && /* scope == specified scope */
500 sym->block <= block && /* block & level kindo matches */
501 sym->level <= level) {
503 /* if a symbol was previously found then
504 sure that ones block & level are less
506 if (*rsym && (*rsym)->block >= block &&
507 (*rsym)->level >= level)
517 /*-----------------------------------------------------------------*/
518 /* symGlobal - return global symbol of name */
519 /*-----------------------------------------------------------------*/
520 DEFSETFUNC(symGlobal)
524 V_ARG(symbol **,rsym);
529 /* simple :: global & name matches */
530 if (sym->scopetype == 'G' &&
531 strcmp(sym->name,name) == 0) {
539 /*-----------------------------------------------------------------*/
540 /* symLookup - determine symbol from name & context */
541 /*-----------------------------------------------------------------*/
542 symbol *symLookup (char *name, context *ctxt)
546 /* first try & find a local variable for the
548 if ( applyToSet(symbols,symLocal,
550 ctxt->func->sym->name,
557 /* then try local to this module */
558 if (applyToSet(symbols,symLocal,
560 ctxt->func->mod->name,
564 /* no:: try global */
565 if ( applyToSet(symbols,symGlobal,name,&sym))
568 /* cannot find return null */
572 /*-----------------------------------------------------------------*/
573 /* lnkFuncEnd - link record for end of function */
574 /*-----------------------------------------------------------------*/
575 static void lnkFuncEnd (char *s)
577 char sname[128], *bp = sname;
580 /* copy till we get to a ':' */
587 if (!applyToSet(functions,funcWithRName,sname,&func))
591 sscanf(s,"%x",&func->sym->eaddr);
593 printf("%s(eaddr%x)\n",func->sym->name,func->sym->eaddr);
597 /*-----------------------------------------------------------------*/
598 /* lnkSymRec - record for a symbol */
599 /*-----------------------------------------------------------------*/
600 static void lnkSymRec (char *s)
602 char sname[128], *bp = sname;
605 /* copy till we get to a ':' */
613 if (!applyToSet(symbols,symWithRName,sname,&sym))
617 sscanf(s,"%x",&sym->addr);
619 printf("%s(%x)\n",sym->name,sym->addr);
623 /*-----------------------------------------------------------------*/
624 /* lnkAsmSrc - process linker record for asm sources */
625 /*-----------------------------------------------------------------*/
626 static void lnkAsmSrc (char *s)
628 char mname[128], *bp = mname;
633 /* input will be of format
634 filename$<line>:<address> */
635 while (*s != '$' && *s != '.')
638 /* skip to line stuff */
639 while (*s != '$') s++;
641 if (!applyToSet(modules,moduleWithName,mname,&mod))
644 if (sscanf(s,"$%d:%x",&line,&addr) != 2)
648 if (line < mod->nasmLines) {
649 mod->asmLines[line]->addr = addr;
651 printf("%s(%d:%x) %s",mod->asm_name,line,addr,mod->asmLines[line]->src);
656 /*-----------------------------------------------------------------*/
657 /* lnkCSrc - process linker output for c source */
658 /*-----------------------------------------------------------------*/
659 static void lnkCSrc (char *s)
661 char mname[128], *bp = mname;
662 int block,level,line;
666 /* input will be of format
667 filename.ext$<level>$<block>$<line>:<address> */
668 /* get the module name */
672 /* skip the extension */
673 while (*s != '$') s++;
675 if (sscanf(s,"$%d$%d$%d:%x",
676 &line,&level,&block,&addr) != 4)
680 if (!applyToSet(modules,moduleWithCName,mname,&mod)) {
681 mod = parseModule(mname,FALSE);
682 mod->c_name = alloccpy(mname,strlen(mname));
683 mod->cfullname=searchDirsFname(mod->c_name);
684 mod->cLines = loadFile(mod->c_name,&mod->ncLines);
688 if (line < mod->ncLines && line > 0) {
689 mod->cLines[line]->addr = addr;
690 mod->cLines[line]->block = block;
691 mod->cLines[line]->level = level;
693 printf("%s(%d:%x) %s",mod->c_name,
694 line+1,addr,mod->cLines[line]->src);
701 /*-----------------------------------------------------------------*/
702 /* parseLnkRec - parses a linker generated record */
703 /*-----------------------------------------------------------------*/
704 void parseLnkRec (char *s)
706 /* link records can be several types
707 dpeneding on the type do */
711 /* c source line address */
715 /* assembler source address */