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 applyToSet(symbols,symWithRName,line,&func->sym);
103 func->sym = parseSymbol(line,&rs);
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)
252 nsym = Safe_calloc(1,sizeof(symbol));
254 /* copy over the mangled name */
255 while (*bp != '(') bp++;
257 nsym->rname = alloccpy(s,bp - s);
259 /* if this is a Global Symbol */
260 nsym->scopetype = *s;
262 if (nsym->scopetype != 'G') {
263 /* get the function name it is local to */
265 while (*s != '$') s++;
266 nsym->sname = alloccpy(bp,s - bp);
269 /* next get the name */
271 while ( *s != '$' ) s++;
272 nsym->name = alloccpy(bp,s - bp);
275 /* get the level number */
276 nsym->level = strtol (s,&bp,10);
278 /* skip the '$' & get the block number */
279 nsym->block = strtol (s,&bp,10);
281 s = parseTypeInfo(nsym,bp);
283 /* get the address space after going past the comma */
288 nsym->isonstack = strtol(s,&s,10);
289 /* get the stack offset */
291 nsym->offset = strtol(s,&s,10);
293 if ( nsym->addrspace == 'R' )
295 /* get registeroffset */
296 while (*s && *s != '[') s++ ;
300 nsym->addr = strtol(s+1,&s,10);
302 while (*s && *s != ']') s++ ;
306 addSet(&symbols,nsym);
312 /*-----------------------------------------------------------------*/
313 /* parseStruct - parses a structure record expected in format */
314 /* {F<filename>}$<tag>[()()()...] */
315 /*-----------------------------------------------------------------*/
316 structdef *parseStruct (char *s)
321 symbol *fields = NULL;
323 while (*s != '$') s++;
326 while (*s != '[') s++ ;
327 name = alloccpy(bp,s - bp);
328 nsdef = structWithName(name);
329 nsdef->fields = NULL;
331 while (*s && *s != ']') {
334 while (!isdigit(*s)) s++;
335 offset = strtol(s,&s,10);
336 while (*s != ':') s++;
338 sym = parseSymbol(s,&s);
339 sym->offset = offset ;
342 fields = nsdef->fields = sym;
344 fields = fields->next = sym;
351 /*-----------------------------------------------------------------*/
352 /* parseModule - creates a module with a given name */
353 /*-----------------------------------------------------------------*/
354 module *parseModule (char *s, bool createName )
359 nmod = Safe_calloc(1,sizeof(module));
361 addSet (&modules,nmod);
364 /* create copy file name */
368 sprintf(buffer,"%s.c",s);
370 nmod->c_name = Safe_malloc(strlen(buffer)+1);
371 strcpy(nmod->c_name,buffer);
373 sprintf(buffer,"%s.asm",s);
374 nmod->asm_name = Safe_malloc(strlen(buffer)+1);
375 strcpy(nmod->asm_name,buffer);
381 /*-----------------------------------------------------------------*/
382 /* moduleWithName - finds and returns a module with a given name */
383 /*-----------------------------------------------------------------*/
384 DEFSETFUNC(moduleWithName)
388 V_ARG(module **,rmod);
393 if (strcmp(mod->name,s) == 0) {
401 /*-----------------------------------------------------------------*/
402 /* moduleWithCName - finds and returns a module with a given c_name*/
403 /*-----------------------------------------------------------------*/
404 DEFSETFUNC(moduleWithCName)
408 V_ARG(module **,rmod);
412 if (strcmp(mod->c_name,s) == 0) {
420 /*-----------------------------------------------------------------*/
421 /* moduleWithAsmName - finds & returns a module with given asm_name*/
422 /*-----------------------------------------------------------------*/
423 DEFSETFUNC(moduleWithAsmName)
427 V_ARG(module **,rmod);
431 if (strcmp(mod->asm_name,s) == 0) {
440 /*-----------------------------------------------------------------*/
441 /* structWithName - returns a structure with a given name */
442 /*-----------------------------------------------------------------*/
443 structdef *structWithName (char *s)
448 /* go thru the struct table looking for a match */
449 for ( i = 0 ; i < nStructs ; i++ ) {
451 if (strcmp(currModName,structs[i]->sname) == 0 &&
452 strcmp(s,structs[i]->tag) == 0)
456 nsdef = Safe_calloc(1,sizeof(structdef));
457 nsdef->tag = alloccpy(s,strlen(s));
458 nsdef->sname = currModName ;
461 structs = (struct structdef **)resize((void **)structs,nStructs);
462 structs[nStructs-1] = nsdef;
466 /*-----------------------------------------------------------------*/
467 /* symWithRName - look for symbol with mangled name = parm */
468 /*-----------------------------------------------------------------*/
469 DEFSETFUNC(symWithRName)
473 V_ARG(symbol **,rsym);
478 if (strcmp(sym->rname,s) == 0) {
486 /*-----------------------------------------------------------------*/
487 /* funcWithRName - look for function with name */
488 /*-----------------------------------------------------------------*/
489 DEFSETFUNC(funcWithRName)
491 function *func = item;
493 V_ARG(function **,rfunc);
498 if (strcmp(func->sym->rname,s) == 0) {
506 /*-----------------------------------------------------------------*/
507 /* symLocal - local symbol respecting blocks & levels */
508 /*-----------------------------------------------------------------*/
516 V_ARG(symbol **,rsym);
518 if (strcmp(name,sym->name) == 0 && /* name matches */
519 sym->scopetype != 'G' && /* local scope */
520 (sym->sname && strcmp(sym->sname,sname) == 0) && /* scope == specified scope */
521 sym->block <= block && /* block & level kindo matches */
522 sym->level <= level) {
524 /* if a symbol was previously found then
525 sure that ones block & level are less
527 if (*rsym && (*rsym)->block >= block &&
528 (*rsym)->level >= level)
538 /*-----------------------------------------------------------------*/
539 /* symGlobal - return global symbol of name */
540 /*-----------------------------------------------------------------*/
541 DEFSETFUNC(symGlobal)
545 V_ARG(symbol **,rsym);
550 /* simple :: global & name matches */
551 if (sym->scopetype == 'G' &&
552 strcmp(sym->name,name) == 0) {
560 /*-----------------------------------------------------------------*/
561 /* symLookup - determine symbol from name & context */
562 /*-----------------------------------------------------------------*/
563 symbol *symLookup (char *name, context *ctxt)
567 if ((ctxt) && (ctxt->func) &&
568 (ctxt->func->sym) && (ctxt->func->sym->name)) {
569 /* first try & find a local variable for the given name */
570 if ( applyToSet(symbols,symLocal,
572 ctxt->func->sym->name,
580 if ((ctxt) && (ctxt->func) &&
581 (ctxt->func->mod) && (ctxt->func->mod->name)) {
582 /* then try local to this module */
583 if (applyToSet(symbols,symLocal,
585 ctxt->func->mod->name,
591 /* no:: try global */
592 if ( applyToSet(symbols,symGlobal,name,&sym))
595 /* cannot find return null */
599 /*-----------------------------------------------------------------*/
600 /* lnkFuncEnd - link record for end of function */
601 /*-----------------------------------------------------------------*/
602 static void lnkFuncEnd (char *s)
604 char sname[128], *bp = sname;
607 /* copy till we get to a ':' */
614 if (!applyToSet(functions,funcWithRName,sname,&func))
618 sscanf(s,"%x",&func->sym->eaddr);
620 Dprintf(D_symtab, ("symtab: %s(eaddr 0x%x)\n",func->sym->name,func->sym->eaddr));
623 /*-----------------------------------------------------------------*/
624 /* lnkSymRec - record for a symbol */
625 /*-----------------------------------------------------------------*/
626 static void lnkSymRec (char *s)
628 char sname[128], *bp = sname;
631 /* copy till we get to a ':' */
639 if (!applyToSet(symbols,symWithRName,sname,&sym))
643 sscanf(s,"%x",&sym->addr);
645 Dprintf(D_symtab, ("symtab: %s(0x%x)\n",sym->name,sym->addr));
648 /*-----------------------------------------------------------------*/
649 /* lnkAsmSrc - process linker record for asm sources */
650 /*-----------------------------------------------------------------*/
651 static void lnkAsmSrc (char *s)
653 char mname[128], *bp = mname;
658 /* input will be of format
659 filename$<line>:<address> */
660 while (*s != '$' && *s != '.')
663 /* skip to line stuff */
664 while (*s != '$') s++;
666 if (!applyToSet(modules,moduleWithName,mname,&mod))
669 if (sscanf(s,"$%d:%x",&line,&addr) != 2)
673 if (line < mod->nasmLines) {
674 mod->asmLines[line]->addr = addr;
675 Dprintf(D_symtab, ("symtab: %s(%d:0x%x) %s",mod->asm_name,line,addr,mod->asmLines[line]->src));
679 /*-----------------------------------------------------------------*/
680 /* lnkCSrc - process linker output for c source */
681 /*-----------------------------------------------------------------*/
682 static void lnkCSrc (char *s)
684 char mname[128], *bp = mname;
685 int block,level,line;
689 /* input will be of format
690 filename.ext$<level>$<block>$<line>:<address> */
691 /* get the module name */
695 /* skip the extension */
696 while (*s != '$') s++;
698 if (sscanf(s,"$%d$%d$%d:%x",
699 &line,&level,&block,&addr) != 4)
703 if (!applyToSet(modules,moduleWithCName,mname,&mod)) {
704 mod = parseModule(mname,FALSE);
705 mod->c_name = alloccpy(mname,strlen(mname));
706 mod->cfullname=searchDirsFname(mod->c_name);
707 mod->cLines = loadFile(mod->c_name,&mod->ncLines);
711 if (line < mod->ncLines && line > 0) {
712 mod->cLines[line]->addr = addr;
713 mod->cLines[line]->block = block;
714 mod->cLines[line]->level = level;
715 Dprintf(D_symtab, ("symtab: %s(%d:0x%x) %s",mod->c_name,
716 line+1,addr,mod->cLines[line]->src));
722 /*-----------------------------------------------------------------*/
723 /* parseLnkRec - parses a linker generated record */
724 /*-----------------------------------------------------------------*/
725 void parseLnkRec (char *s)
727 /* link records can be several types
728 dpeneding on the type do */
732 /* c source line address */
736 /* assembler source address */