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 -------------------------------------------------------------------------*/
28 structdef *structWithName (char *);
29 DEFSETFUNC(symWithRName);
31 /*------------------------------------------------------------------*/
32 /* getSize - returns size of a type chain in bits */
33 /*------------------------------------------------------------------*/
34 unsigned int getSize ( link *p )
36 /* if nothing return 0 */
40 if ( IS_SPEC(p) ) { /* if this is the specifier then */
42 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
44 return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ;
52 return SPEC_STRUCT(p)->size ;
58 return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ;
64 /* this is a specifier */
65 switch (DCL_TYPE(p)) {
69 return DCL_ELEM(p) * getSize (p->next) ;
86 /*-----------------------------------------------------------------*/
87 /* parseFunc - creates a function record entry */
88 /*-----------------------------------------------------------------*/
89 void parseFunc (char *line)
95 while (*rs && *rs != '(') rs++ ;
98 func = Safe_calloc(1,sizeof(function));
100 applyToSetFTrue(symbols,symWithRName,line,&func->sym);
103 func->sym = parseSymbol(line,&rs,1);
104 func->sym->isfunc = 1;
105 func->modName = currModName ;
106 while(*rs && *rs != ',') rs++;
108 sscanf(rs,"%d,%d,%d",&i,
109 &(SPEC_INTN(func->sym->etype)),
110 &(SPEC_BANK(func->sym->etype)));
111 SPEC_INTRTN(func->sym->etype) = i;
112 addSet(&functions,func);
115 /*-----------------------------------------------------------------*/
116 /* parseTypeInfo - parse the type info of a symbol expects the type*/
117 /* info to be of the form */
118 /* ({<size>}<type info chain) */
119 /*-----------------------------------------------------------------*/
120 static char *parseTypeInfo (symbol *sym, char *s)
124 s += 2; /* go past the ({ */
126 sym->size = strtol (s,&bp,10);
127 /* bp now points to '}' ... go past it */
129 while (*s != ')') { /* till we reach the end */
131 type = Safe_calloc(1,sizeof(link));
134 /* is a declarator */
139 DCL_TYPE(type) = FUNCTION;
143 DCL_TYPE(type) = GPOINTER;
147 DCL_TYPE(type) = CPOINTER;
151 DCL_TYPE(type) = FPOINTER;
155 DCL_TYPE(type) = POINTER;
159 DCL_TYPE(type) = IPOINTER;
163 DCL_TYPE(type) = PPOINTER;
168 DCL_TYPE(type) = ARRAY ;
169 DCL_ELEM(type) = strtol(s,&s,10);
174 type->class = SPECIFIER ;
178 SPEC_NOUN(type) = V_INT;
183 SPEC_NOUN(type) = V_INT;
188 SPEC_NOUN(type) = V_CHAR ;
192 SPEC_NOUN(type) = V_VOID;
196 SPEC_NOUN(type) = V_FLOAT;
201 SPEC_NOUN(type) = V_STRUCT;
203 char *ss = strtok(strdup(s),",):");
205 SPEC_STRUCT(type) = structWithName(ss);
211 SPEC_NOUN(type) = V_SBIT;
214 SPEC_NOUN(type) = V_BIT;
216 SPEC_BSTR(type) = strtol(s,&s,10);
218 SPEC_BLEN(type) = strtol(s,&s,10);
221 while (*s != ':') s++;
224 SPEC_USIGN(type) = 0;
226 SPEC_USIGN(type) = 1;
230 /* add the type to the symbol's type chain */
232 sym->etype = sym->etype->next = type;
234 sym->type = sym->etype = type;
241 /*-----------------------------------------------------------------*/
242 /* symFromRec - parse a symbol record and extract and create a sym */
243 /* expects the input string to be of the form */
244 /* {G|F<filename>|L<functionName>}'$'<name>'$'<level> */
245 /* '$'<block><type info> */
246 /*-----------------------------------------------------------------*/
247 symbol *parseSymbol (char *s, char **rs, int doadd)
253 /* go the mangled name */
254 for ( bp = s; *bp && *bp != '('; bp++ );
260 /* add only if not present and if linkrecord before symbol record*/
261 if ( applyToSetFTrue(symbols,symWithRName,s,&nsym))
263 if ( nsym->rname != nsym->name )
270 nsym = Safe_calloc(1,sizeof(symbol));
271 nsym->rname = alloccpy(s,bp - s);
274 /* if this is a Global Symbol */
275 nsym->scopetype = *s;
277 if (nsym->scopetype != 'G') {
278 /* get the function name it is local to */
280 while (*s != '$') s++;
281 nsym->sname = alloccpy(bp,s - bp);
284 /* next get the name */
286 while ( *s != '$' ) s++;
287 nsym->name = alloccpy(bp,s - bp);
290 /* get the level number */
291 nsym->level = strtol (s,&bp,10);
293 /* skip the '$' & get the block number */
294 nsym->block = strtol (s,&bp,10);
296 s = parseTypeInfo(nsym,bp);
298 /* get the address space after going past the comma */
303 nsym->isonstack = strtol(s,&s,10);
304 /* get the stack offset */
306 nsym->offset = strtol(s,&s,10);
308 if ( nsym->addrspace == 'R' )
310 /* get registeroffset */
311 while (*s && *s != '[') s++ ;
315 nsym->addr = strtol(s+1,&s,10);
317 while (*s && *s != ']') s++ ;
321 if ( doadd ) addSet(&symbols,nsym);
323 Dprintf(D_symtab, ("symtab: par %s(0x%x) add=%d sym=%p\n",nsym->name,nsym->addr,doadd,nsym));
329 /*-----------------------------------------------------------------*/
330 /* parseStruct - parses a structure record expected in format */
331 /* {F<filename>}$<tag>[()()()...] */
332 /*-----------------------------------------------------------------*/
333 structdef *parseStruct (char *s)
338 symbol *fields = NULL;
340 while (*s != '$') s++;
343 while (*s != '[') s++ ;
344 name = alloccpy(bp,s - bp);
345 nsdef = structWithName(name);
346 nsdef->fields = NULL;
349 while (*s && *s != ']') {
352 while (!isdigit(*s)) s++;
353 offset = strtol(s,&s,10);
354 while (*s != ':') s++;
356 sym = parseSymbol(s,&s,0);
357 sym->offset = offset ;
360 fields = nsdef->fields = sym;
362 fields = fields->next = sym;
363 nsdef->size += sym->size;
369 /*-----------------------------------------------------------------*/
370 /* parseModule - creates a module with a given name */
371 /*-----------------------------------------------------------------*/
372 module *parseModule (char *s, bool createName )
377 nmod = Safe_calloc(1,sizeof(module));
379 addSet (&modules,nmod);
382 /* create copy file name */
386 sprintf(buffer,"%s.c",s);
388 nmod->c_name = Safe_malloc(strlen(buffer)+1);
389 strcpy(nmod->c_name,buffer);
391 sprintf(buffer,"%s.asm",s);
392 nmod->asm_name = Safe_malloc(strlen(buffer)+1);
393 strcpy(nmod->asm_name,buffer);
399 /*-----------------------------------------------------------------*/
400 /* moduleWithName - finds and returns a module with a given name */
401 /*-----------------------------------------------------------------*/
402 DEFSETFUNC(moduleWithName)
406 V_ARG(module **,rmod);
411 if (strcmp(mod->name,s) == 0) {
419 /*-----------------------------------------------------------------*/
420 /* moduleWithCName - finds and returns a module with a given c_name*/
421 /*-----------------------------------------------------------------*/
422 DEFSETFUNC(moduleWithCName)
426 V_ARG(module **,rmod);
430 if (strcmp(mod->c_name,s) == 0) {
438 /*-----------------------------------------------------------------*/
439 /* moduleWithAsmName - finds & returns a module with given asm_name*/
440 /*-----------------------------------------------------------------*/
441 DEFSETFUNC(moduleWithAsmName)
445 V_ARG(module **,rmod);
449 if (strcmp(mod->asm_name,s) == 0) {
458 /*-----------------------------------------------------------------*/
459 /* structWithName - returns a structure with a given name */
460 /*-----------------------------------------------------------------*/
461 structdef *structWithName (char *s)
466 /* go thru the struct table looking for a match */
467 for ( i = 0 ; i < nStructs ; i++ ) {
469 if (strcmp(currModName,structs[i]->sname) == 0 &&
470 strcmp(s,structs[i]->tag) == 0)
474 nsdef = Safe_calloc(1,sizeof(structdef));
475 nsdef->tag = alloccpy(s,strlen(s));
476 nsdef->sname = currModName ;
479 structs = (struct structdef **)resize((void **)structs,nStructs);
480 structs[nStructs-1] = nsdef;
484 /*-----------------------------------------------------------------*/
485 /* symWithRName - look for symbol with mangled name = parm */
486 /*-----------------------------------------------------------------*/
487 DEFSETFUNC(symWithRName)
491 V_ARG(symbol **,rsym);
496 if (strcmp(sym->rname,s) == 0) {
504 /*-----------------------------------------------------------------*/
505 /* funcWithRName - look for function with name */
506 /*-----------------------------------------------------------------*/
507 DEFSETFUNC(funcWithRName)
509 function *func = item;
511 V_ARG(function **,rfunc);
516 if (strcmp(func->sym->rname,s) == 0) {
524 /*-----------------------------------------------------------------*/
525 /* symLocal - local symbol respecting blocks & levels */
526 /*-----------------------------------------------------------------*/
534 V_ARG(symbol **,rsym);
536 if (strcmp(name,sym->name) == 0 && /* name matches */
537 sym->scopetype != 'G' && /* local scope */
538 (sym->sname && strcmp(sym->sname,sname) == 0) && /* scope == specified scope */
539 sym->block <= block && /* block & level kindo matches */
540 sym->level <= level) {
542 /* if a symbol was previously found then
543 sure that ones block & level are less
545 if (*rsym && (*rsym)->block >= block &&
546 (*rsym)->level >= level)
556 /*-----------------------------------------------------------------*/
557 /* symGlobal - return global symbol of name */
558 /*-----------------------------------------------------------------*/
559 DEFSETFUNC(symGlobal)
563 V_ARG(symbol **,rsym);
568 /* simple :: global & name matches */
569 if (sym->scopetype == 'G' &&
570 strcmp(sym->name,name) == 0) {
578 /*-----------------------------------------------------------------*/
579 /* symLookup - determine symbol from name & context */
580 /*-----------------------------------------------------------------*/
581 symbol *symLookup (char *name, context *ctxt)
585 if ((ctxt) && (ctxt->func) &&
586 (ctxt->func->sym) && (ctxt->func->sym->name)) {
587 /* first try & find a local variable for the given name */
588 if ( applyToSet(symbols,symLocal,
590 ctxt->func->sym->name,
598 if ((ctxt) && (ctxt->func) &&
599 (ctxt->func->mod) && (ctxt->func->mod->name)) {
600 /* then try local to this module */
601 if (applyToSet(symbols,symLocal,
603 ctxt->func->mod->name,
609 /* no:: try global */
610 if ( applyToSet(symbols,symGlobal,name,&sym))
613 /* cannot find return null */
617 /*-----------------------------------------------------------------*/
618 /* lnkFuncEnd - link record for end of function */
619 /*-----------------------------------------------------------------*/
620 static void lnkFuncEnd (char *s)
622 char sname[128], *bp = sname;
625 /* copy till we get to a ':' */
632 if (!applyToSet(functions,funcWithRName,sname,&func))
636 sscanf(s,"%x",&func->sym->eaddr);
638 Dprintf(D_symtab, ("symtab: ead %s(0x%x)\n",func->sym->name,func->sym->eaddr));
641 /*-----------------------------------------------------------------*/
642 /* lnkSymRec - record for a symbol */
643 /*-----------------------------------------------------------------*/
644 static void lnkSymRec (char *s)
649 /* search to a ':' */
650 for ( bp = s; *bp && *bp != ':'; bp++ );
656 applyToSetFTrue(symbols,symWithRName,s,&sym);
659 sym = Safe_calloc(1,sizeof(symbol));
660 sym->rname = alloccpy(s,bp - s);
662 sym->name = sym->rname;
663 addSet(&symbols,sym);
668 sscanf(bp+2,"%x",&sym->addr);
670 Dprintf(D_symtab, ("symtab: lnk %s(0x%x)\n",sym->name,sym->addr));
673 /*-----------------------------------------------------------------*/
674 /* lnkAsmSrc - process linker record for asm sources */
675 /*-----------------------------------------------------------------*/
676 static void lnkAsmSrc (char *s)
678 char mname[128], *bp = mname;
683 /* input will be of format
684 filename$<line>:<address> */
685 while (*s != '$' && *s != '.')
688 /* skip to line stuff */
689 while (*s != '$') s++;
691 if (!applyToSet(modules,moduleWithName,mname,&mod))
694 if (sscanf(s,"$%d:%x",&line,&addr) != 2)
698 if (line < mod->nasmLines) {
699 mod->asmLines[line]->addr = addr;
700 Dprintf(D_symtab, ("symtab: asm %s(%d:0x%x) %s",mod->asm_name,line,addr,mod->asmLines[line]->src));
704 /*-----------------------------------------------------------------*/
705 /* lnkCSrc - process linker output for c source */
706 /*-----------------------------------------------------------------*/
707 static void lnkCSrc (char *s)
709 char mname[128], *bp = mname;
710 int block,level,line;
714 /* input will be of format
715 filename.ext$<line>$<level>$<block>:<address> */
716 /* get the module name */
720 /* skip the extension */
721 while (*s != '$') s++;
723 if (sscanf(s,"$%d$%d$%d:%x",
724 &line,&level,&block,&addr) != 4)
728 if (!applyToSet(modules,moduleWithCName,mname,&mod)) {
729 mod = parseModule(mname,FALSE);
730 mod->c_name = alloccpy(mname,strlen(mname));
731 mod->cfullname=searchDirsFname(mod->c_name);
732 mod->cLines = loadFile(mod->c_name,&mod->ncLines);
736 /* one line can have more than one address : (for loops !)*/
737 if (line < mod->ncLines && line > 0 /*&&
738 ( !mod->cLines[line]->addr ||
739 mod->cLines[line]->level > level )*/ )
741 if ( mod->cLines[line]->addr != INT_MAX )
743 /* save double line information for exepoints */
745 ep = Safe_calloc(1,sizeof(exePoint));
746 ep->addr = mod->cLines[line]->addr ;
748 ep->block= mod->cLines[line]->block;
749 ep->level= mod->cLines[line]->level;
750 addSet(&mod->cfpoints,ep);
751 Dprintf(D_symtab, ("symtab: exe %s(%d:0x%x) %s",mod->c_name,
752 line+1,addr,mod->cLines[line]->src));
754 mod->cLines[line]->addr = addr;
755 mod->cLines[line]->block = block;
756 mod->cLines[line]->level = level;
757 Dprintf(D_symtab, ("symtab: ccc %s(%d:0x%x) %s",mod->c_name,
758 line+1,addr,mod->cLines[line]->src));
764 /*-----------------------------------------------------------------*/
765 /* parseLnkRec - parses a linker generated record */
766 /*-----------------------------------------------------------------*/
767 void parseLnkRec (char *s)
769 /* link records can be several types
770 dpeneding on the type do */
774 /* c source line address */
778 /* assembler source address */