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 extern char *currModName ;
29 structdef *structWithName (char *);
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)
94 func = Safe_calloc(1,sizeof(function));
95 func->sym = parseSymbol(line,&rs);
96 func->sym->isfunc = 1;
97 func->modName = currModName ;
98 while(*rs != ',') rs++;
100 sscanf(rs,"%d,%d,%d",&i,
101 &(SPEC_INTN(func->sym->etype)),
102 &(SPEC_BANK(func->sym->etype)));
103 SPEC_INTRTN(func->sym->etype) = i;
104 addSet(&functions,func);
107 /*-----------------------------------------------------------------*/
108 /* parseTypeInfo - parse the type info of a symbol expects the type*/
109 /* info to be of the form */
110 /* ({<size>}<type info chain) */
111 /*-----------------------------------------------------------------*/
112 static char *parseTypeInfo (symbol *sym, char *s)
116 s += 2; /* go past the ({ */
118 sym->size = strtol (s,&bp,10);
119 /* bp now points to '}' ... go past it */
121 while (*s != ')') { /* till we reach the end */
123 type = Safe_calloc(1,sizeof(link));
126 /* is a declarator */
131 DCL_TYPE(type) = FUNCTION;
135 DCL_TYPE(type) = GPOINTER;
139 DCL_TYPE(type) = CPOINTER;
143 DCL_TYPE(type) = FPOINTER;
147 DCL_TYPE(type) = POINTER;
151 DCL_TYPE(type) = IPOINTER;
155 DCL_TYPE(type) = PPOINTER;
160 DCL_TYPE(type) = ARRAY ;
161 DCL_ELEM(type) = strtol(s,&s,10);
166 type->class = SPECIFIER ;
170 SPEC_NOUN(type) = V_INT;
175 SPEC_NOUN(type) = V_INT;
180 SPEC_NOUN(type) = V_CHAR ;
184 SPEC_NOUN(type) = V_VOID;
188 SPEC_NOUN(type) = V_FLOAT;
193 SPEC_NOUN(type) = V_STRUCT;
195 char *ss = strtok(strdup(s),",):");
197 SPEC_STRUCT(type) = structWithName(ss);
203 SPEC_NOUN(type) = V_SBIT;
206 SPEC_NOUN(type) = V_BIT;
208 SPEC_BSTR(type) = strtol(s,&s,10);
210 SPEC_BLEN(type) = strtol(s,&s,10);
213 while (*s != ':') s++;
216 SPEC_USIGN(type) = 0;
218 SPEC_USIGN(type) = 1;
222 /* add the type to the symbol's type chain */
224 sym->etype = sym->etype->next = type;
226 sym->type = sym->etype = type;
233 /*-----------------------------------------------------------------*/
234 /* symFromRec - parse a symbol record and extract and create a sym */
235 /* expects the input string to be of the form */
236 /* {G|F<filename>|L<functionName>}'$'<name>'$'<level> */
237 /* '$'<block><type info> */
238 /*-----------------------------------------------------------------*/
239 symbol *parseSymbol (char *s, char **rs)
244 nsym = Safe_calloc(1,sizeof(symbol));
246 /* copy over the mangled name */
247 while (*bp != '(') bp++;
249 nsym->rname = alloccpy(s,bp - s);
251 /* if this is a Global Symbol */
252 nsym->scopetype = *s;
254 if (nsym->scopetype != 'G') {
255 /* get the function name it is local to */
257 while (*s != '$') s++;
258 nsym->sname = alloccpy(bp,s - bp);
261 /* next get the name */
263 while ( *s != '$' ) s++;
264 nsym->name = alloccpy(bp,s - bp);
267 /* get the level number */
268 nsym->level = strtol (s,&bp,10);
270 /* skip the '$' & get the block number */
271 nsym->block = strtol (s,&bp,10);
273 s = parseTypeInfo(nsym,bp);
275 /* get the address space after going past the comma */
280 nsym->isonstack = strtol(s,&s,10);
281 /* get the stack offset */
283 nsym->offset = strtol(s,&s,10);
286 addSet(&symbols,nsym);
292 /*-----------------------------------------------------------------*/
293 /* parseStruct - parses a structure record expected in format */
294 /* {F<filename>}$<tag>[()()()...] */
295 /*-----------------------------------------------------------------*/
296 structdef *parseStruct (char *s)
301 symbol *fields = NULL;
303 while (*s != '$') s++;
306 while (*s != '[') s++ ;
307 name = alloccpy(bp,s - bp);
308 nsdef = structWithName(name);
309 nsdef->fields = NULL;
311 while (*s && *s != ']') {
314 while (!isdigit(*s)) s++;
315 offset = strtol(s,&s,10);
316 while (*s != ':') s++;
318 sym = parseSymbol(s,&s);
319 sym->offset = offset ;
322 fields = nsdef->fields = sym;
324 fields = fields->next = sym;
331 /*-----------------------------------------------------------------*/
332 /* parseModule - creates a module with a given name */
333 /*-----------------------------------------------------------------*/
334 module *parseModule (char *s, bool createName )
339 nmod = Safe_calloc(1,sizeof(module));
341 addSet (&modules,nmod);
344 /* create copy file name */
348 sprintf(buffer,"%s.c",s);
350 nmod->c_name = Safe_malloc(strlen(buffer)+1);
351 strcpy(nmod->c_name,buffer);
353 sprintf(buffer,"%s.asm",s);
354 nmod->asm_name = Safe_malloc(strlen(buffer)+1);
355 strcpy(nmod->asm_name,buffer);
361 /*-----------------------------------------------------------------*/
362 /* moduleWithName - finds and returns a module with a given name */
363 /*-----------------------------------------------------------------*/
364 DEFSETFUNC(moduleWithName)
368 V_ARG(module **,rmod);
373 if (strcmp(mod->name,s) == 0) {
381 /*-----------------------------------------------------------------*/
382 /* moduleWithCName - finds and returns a module with a given c_name*/
383 /*-----------------------------------------------------------------*/
384 DEFSETFUNC(moduleWithCName)
388 V_ARG(module **,rmod);
392 if (strcmp(mod->c_name,s) == 0) {
400 /*-----------------------------------------------------------------*/
401 /* moduleWithAsmName - finds & returns a module with given asm_name*/
402 /*-----------------------------------------------------------------*/
403 DEFSETFUNC(moduleWithAsmName)
407 V_ARG(module **,rmod);
411 if (strcmp(mod->asm_name,s) == 0) {
420 /*-----------------------------------------------------------------*/
421 /* structWithName - returns a structure with a given name */
422 /*-----------------------------------------------------------------*/
423 structdef *structWithName (char *s)
428 /* go thru the struct table looking for a match */
429 for ( i = 0 ; i < nStructs ; i++ ) {
431 if (strcmp(currModName,structs[i]->sname) == 0 &&
432 strcmp(s,structs[i]->tag) == 0)
436 nsdef = Safe_calloc(1,sizeof(structdef));
437 nsdef->tag = alloccpy(s,strlen(s));
438 nsdef->sname = currModName ;
441 structs = (struct structdef **)resize((void **)structs,nStructs);
442 structs[nStructs-1] = nsdef;
446 /*-----------------------------------------------------------------*/
447 /* symWithRName - look for symbol with mangled name = parm */
448 /*-----------------------------------------------------------------*/
449 DEFSETFUNC(symWithRName)
453 V_ARG(symbol **,rsym);
458 if (strcmp(sym->rname,s) == 0) {
466 /*-----------------------------------------------------------------*/
467 /* funcWithRName - look for function with name */
468 /*-----------------------------------------------------------------*/
469 DEFSETFUNC(funcWithRName)
471 function *func = item;
473 V_ARG(function **,rfunc);
478 if (strcmp(func->sym->rname,s) == 0) {
486 /*-----------------------------------------------------------------*/
487 /* symLocal - local symbol respecting blocks & levels */
488 /*-----------------------------------------------------------------*/
496 V_ARG(symbol **,rsym);
498 if (strcmp(name,sym->name) == 0 && /* name matches */
499 sym->scopetype != 'G' && /* local scope */
500 (sym->sname && strcmp(sym->sname,sname) == 0) && /* scope == specified scope */
501 sym->block <= block && /* block & level kindo matches */
502 sym->level <= level) {
504 /* if a symbol was previously found then
505 sure that ones block & level are less
507 if (*rsym && (*rsym)->block >= block &&
508 (*rsym)->level >= level)
518 /*-----------------------------------------------------------------*/
519 /* symGlobal - return global symbol of name */
520 /*-----------------------------------------------------------------*/
521 DEFSETFUNC(symGlobal)
525 V_ARG(symbol **,rsym);
530 /* simple :: global & name matches */
531 if (sym->scopetype == 'G' &&
532 strcmp(sym->name,name) == 0) {
540 /*-----------------------------------------------------------------*/
541 /* symLookup - determine symbol from name & context */
542 /*-----------------------------------------------------------------*/
543 symbol *symLookup (char *name, context *ctxt)
547 /* first try & find a local variable for the
549 if ( applyToSet(symbols,symLocal,
551 ctxt->func->sym->name,
558 /* then try local to this module */
559 if (applyToSet(symbols,symLocal,
561 ctxt->func->mod->name,
565 /* no:: try global */
566 if ( applyToSet(symbols,symGlobal,name,&sym))
569 /* cannot find return null */
573 /*-----------------------------------------------------------------*/
574 /* lnkFuncEnd - link record for end of function */
575 /*-----------------------------------------------------------------*/
576 static void lnkFuncEnd (char *s)
578 char sname[128], *bp = sname;
581 /* copy till we get to a ':' */
588 if (!applyToSet(functions,funcWithRName,sname,&func))
592 sscanf(s,"%x",&func->sym->eaddr);
594 Dprintf(D_symtab, ("%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 Dprintf(D_symtab, ("%s(%x)\n",sym->name,sym->addr));
622 /*-----------------------------------------------------------------*/
623 /* lnkAsmSrc - process linker record for asm sources */
624 /*-----------------------------------------------------------------*/
625 static void lnkAsmSrc (char *s)
627 char mname[128], *bp = mname;
632 /* input will be of format
633 filename$<line>:<address> */
634 while (*s != '$' && *s != '.')
637 /* skip to line stuff */
638 while (*s != '$') s++;
640 if (!applyToSet(modules,moduleWithName,mname,&mod))
643 if (sscanf(s,"$%d:%x",&line,&addr) != 2)
647 if (line < mod->nasmLines) {
648 mod->asmLines[line]->addr = addr;
649 Dprintf(D_symtab, ("%s(%d:%x) %s",mod->asm_name,line,addr,mod->asmLines[line]->src));
653 /*-----------------------------------------------------------------*/
654 /* lnkCSrc - process linker output for c source */
655 /*-----------------------------------------------------------------*/
656 static void lnkCSrc (char *s)
658 char mname[128], *bp = mname;
659 int block,level,line;
663 /* input will be of format
664 filename.ext$<level>$<block>$<line>:<address> */
665 /* get the module name */
669 /* skip the extension */
670 while (*s != '$') s++;
672 if (sscanf(s,"$%d$%d$%d:%x",
673 &line,&level,&block,&addr) != 4)
677 if (!applyToSet(modules,moduleWithCName,mname,&mod)) {
678 mod = parseModule(mname,FALSE);
679 mod->c_name = alloccpy(mname,strlen(mname));
680 mod->cfullname=searchDirsFname(mod->c_name);
681 mod->cLines = loadFile(mod->c_name,&mod->ncLines);
685 if (line < mod->ncLines && line > 0) {
686 mod->cLines[line]->addr = addr;
687 mod->cLines[line]->block = block;
688 mod->cLines[line]->level = level;
689 Dprintf(D_symtab, ("%s(%d:%x) %s",mod->c_name,
690 line+1,addr,mod->cLines[line]->src));
696 /*-----------------------------------------------------------------*/
697 /* parseLnkRec - parses a linker generated record */
698 /*-----------------------------------------------------------------*/
699 void parseLnkRec (char *s)
701 /* link records can be several types
702 dpeneding on the type do */
706 /* c source line address */
710 /* assembler source address */