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 *);
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 func = Safe_calloc(1,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 type = Safe_calloc(1,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 nsym = Safe_calloc(1,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);
284 if ( nsym->addrspace == 'R' )
286 /* get registeroffset */
287 while (*s && *s != '[') s++ ;
291 nsym->addr = strtol(s+1,&s,10);
293 while (*s && *s != ']') s++ ;
297 addSet(&symbols,nsym);
303 /*-----------------------------------------------------------------*/
304 /* parseStruct - parses a structure record expected in format */
305 /* {F<filename>}$<tag>[()()()...] */
306 /*-----------------------------------------------------------------*/
307 structdef *parseStruct (char *s)
312 symbol *fields = NULL;
314 while (*s != '$') s++;
317 while (*s != '[') s++ ;
318 name = alloccpy(bp,s - bp);
319 nsdef = structWithName(name);
320 nsdef->fields = NULL;
322 while (*s && *s != ']') {
325 while (!isdigit(*s)) s++;
326 offset = strtol(s,&s,10);
327 while (*s != ':') s++;
329 sym = parseSymbol(s,&s);
330 sym->offset = offset ;
333 fields = nsdef->fields = sym;
335 fields = fields->next = sym;
342 /*-----------------------------------------------------------------*/
343 /* parseModule - creates a module with a given name */
344 /*-----------------------------------------------------------------*/
345 module *parseModule (char *s, bool createName )
350 nmod = Safe_calloc(1,sizeof(module));
352 addSet (&modules,nmod);
355 /* create copy file name */
359 sprintf(buffer,"%s.c",s);
361 nmod->c_name = Safe_malloc(strlen(buffer)+1);
362 strcpy(nmod->c_name,buffer);
364 sprintf(buffer,"%s.asm",s);
365 nmod->asm_name = Safe_malloc(strlen(buffer)+1);
366 strcpy(nmod->asm_name,buffer);
372 /*-----------------------------------------------------------------*/
373 /* moduleWithName - finds and returns a module with a given name */
374 /*-----------------------------------------------------------------*/
375 DEFSETFUNC(moduleWithName)
379 V_ARG(module **,rmod);
384 if (strcmp(mod->name,s) == 0) {
392 /*-----------------------------------------------------------------*/
393 /* moduleWithCName - finds and returns a module with a given c_name*/
394 /*-----------------------------------------------------------------*/
395 DEFSETFUNC(moduleWithCName)
399 V_ARG(module **,rmod);
403 if (strcmp(mod->c_name,s) == 0) {
411 /*-----------------------------------------------------------------*/
412 /* moduleWithAsmName - finds & returns a module with given asm_name*/
413 /*-----------------------------------------------------------------*/
414 DEFSETFUNC(moduleWithAsmName)
418 V_ARG(module **,rmod);
422 if (strcmp(mod->asm_name,s) == 0) {
431 /*-----------------------------------------------------------------*/
432 /* structWithName - returns a structure with a given name */
433 /*-----------------------------------------------------------------*/
434 structdef *structWithName (char *s)
439 /* go thru the struct table looking for a match */
440 for ( i = 0 ; i < nStructs ; i++ ) {
442 if (strcmp(currModName,structs[i]->sname) == 0 &&
443 strcmp(s,structs[i]->tag) == 0)
447 nsdef = Safe_calloc(1,sizeof(structdef));
448 nsdef->tag = alloccpy(s,strlen(s));
449 nsdef->sname = currModName ;
452 structs = (struct structdef **)resize((void **)structs,nStructs);
453 structs[nStructs-1] = nsdef;
457 /*-----------------------------------------------------------------*/
458 /* symWithRName - look for symbol with mangled name = parm */
459 /*-----------------------------------------------------------------*/
460 DEFSETFUNC(symWithRName)
464 V_ARG(symbol **,rsym);
469 if (strcmp(sym->rname,s) == 0) {
477 /*-----------------------------------------------------------------*/
478 /* funcWithRName - look for function with name */
479 /*-----------------------------------------------------------------*/
480 DEFSETFUNC(funcWithRName)
482 function *func = item;
484 V_ARG(function **,rfunc);
489 if (strcmp(func->sym->rname,s) == 0) {
497 /*-----------------------------------------------------------------*/
498 /* symLocal - local symbol respecting blocks & levels */
499 /*-----------------------------------------------------------------*/
507 V_ARG(symbol **,rsym);
509 if (strcmp(name,sym->name) == 0 && /* name matches */
510 sym->scopetype != 'G' && /* local scope */
511 (sym->sname && strcmp(sym->sname,sname) == 0) && /* scope == specified scope */
512 sym->block <= block && /* block & level kindo matches */
513 sym->level <= level) {
515 /* if a symbol was previously found then
516 sure that ones block & level are less
518 if (*rsym && (*rsym)->block >= block &&
519 (*rsym)->level >= level)
529 /*-----------------------------------------------------------------*/
530 /* symGlobal - return global symbol of name */
531 /*-----------------------------------------------------------------*/
532 DEFSETFUNC(symGlobal)
536 V_ARG(symbol **,rsym);
541 /* simple :: global & name matches */
542 if (sym->scopetype == 'G' &&
543 strcmp(sym->name,name) == 0) {
551 /*-----------------------------------------------------------------*/
552 /* symLookup - determine symbol from name & context */
553 /*-----------------------------------------------------------------*/
554 symbol *symLookup (char *name, context *ctxt)
558 if ((ctxt) && (ctxt->func) &&
559 (ctxt->func->sym) && (ctxt->func->sym->name)) {
560 /* first try & find a local variable for the given name */
561 if ( applyToSet(symbols,symLocal,
563 ctxt->func->sym->name,
571 if ((ctxt) && (ctxt->func) &&
572 (ctxt->func->mod) && (ctxt->func->mod->name)) {
573 /* then try local to this module */
574 if (applyToSet(symbols,symLocal,
576 ctxt->func->mod->name,
582 /* no:: try global */
583 if ( applyToSet(symbols,symGlobal,name,&sym))
586 /* cannot find return null */
590 /*-----------------------------------------------------------------*/
591 /* lnkFuncEnd - link record for end of function */
592 /*-----------------------------------------------------------------*/
593 static void lnkFuncEnd (char *s)
595 char sname[128], *bp = sname;
598 /* copy till we get to a ':' */
605 if (!applyToSet(functions,funcWithRName,sname,&func))
609 sscanf(s,"%x",&func->sym->eaddr);
611 Dprintf(D_symtab, ("%s(eaddr%x)\n",func->sym->name,func->sym->eaddr));
614 /*-----------------------------------------------------------------*/
615 /* lnkSymRec - record for a symbol */
616 /*-----------------------------------------------------------------*/
617 static void lnkSymRec (char *s)
619 char sname[128], *bp = sname;
622 /* copy till we get to a ':' */
630 if (!applyToSet(symbols,symWithRName,sname,&sym))
634 sscanf(s,"%x",&sym->addr);
636 Dprintf(D_symtab, ("%s(%x)\n",sym->name,sym->addr));
639 /*-----------------------------------------------------------------*/
640 /* lnkAsmSrc - process linker record for asm sources */
641 /*-----------------------------------------------------------------*/
642 static void lnkAsmSrc (char *s)
644 char mname[128], *bp = mname;
649 /* input will be of format
650 filename$<line>:<address> */
651 while (*s != '$' && *s != '.')
654 /* skip to line stuff */
655 while (*s != '$') s++;
657 if (!applyToSet(modules,moduleWithName,mname,&mod))
660 if (sscanf(s,"$%d:%x",&line,&addr) != 2)
664 if (line < mod->nasmLines) {
665 mod->asmLines[line]->addr = addr;
666 Dprintf(D_symtab, ("%s(%d:%x) %s",mod->asm_name,line,addr,mod->asmLines[line]->src));
670 /*-----------------------------------------------------------------*/
671 /* lnkCSrc - process linker output for c source */
672 /*-----------------------------------------------------------------*/
673 static void lnkCSrc (char *s)
675 char mname[128], *bp = mname;
676 int block,level,line;
680 /* input will be of format
681 filename.ext$<level>$<block>$<line>:<address> */
682 /* get the module name */
686 /* skip the extension */
687 while (*s != '$') s++;
689 if (sscanf(s,"$%d$%d$%d:%x",
690 &line,&level,&block,&addr) != 4)
694 if (!applyToSet(modules,moduleWithCName,mname,&mod)) {
695 mod = parseModule(mname,FALSE);
696 mod->c_name = alloccpy(mname,strlen(mname));
697 mod->cfullname=searchDirsFname(mod->c_name);
698 mod->cLines = loadFile(mod->c_name,&mod->ncLines);
702 if (line < mod->ncLines && line > 0) {
703 mod->cLines[line]->addr = addr;
704 mod->cLines[line]->block = block;
705 mod->cLines[line]->level = level;
706 Dprintf(D_symtab, ("%s(%d:%x) %s",mod->c_name,
707 line+1,addr,mod->cLines[line]->src));
713 /*-----------------------------------------------------------------*/
714 /* parseLnkRec - parses a linker generated record */
715 /*-----------------------------------------------------------------*/
716 void parseLnkRec (char *s)
718 /* link records can be several types
719 dpeneding on the type do */
723 /* c source line address */
727 /* assembler source address */