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;
332 while (*s && *s != ']') {
335 while (!isdigit(*s)) s++;
336 offset = strtol(s,&s,10);
337 while (*s != ':') s++;
339 sym = parseSymbol(s,&s);
340 sym->offset = offset ;
343 fields = nsdef->fields = sym;
345 fields = fields->next = sym;
346 nsdef->size += sym->size;
352 /*-----------------------------------------------------------------*/
353 /* parseModule - creates a module with a given name */
354 /*-----------------------------------------------------------------*/
355 module *parseModule (char *s, bool createName )
360 nmod = Safe_calloc(1,sizeof(module));
362 addSet (&modules,nmod);
365 /* create copy file name */
369 sprintf(buffer,"%s.c",s);
371 nmod->c_name = Safe_malloc(strlen(buffer)+1);
372 strcpy(nmod->c_name,buffer);
374 sprintf(buffer,"%s.asm",s);
375 nmod->asm_name = Safe_malloc(strlen(buffer)+1);
376 strcpy(nmod->asm_name,buffer);
382 /*-----------------------------------------------------------------*/
383 /* moduleWithName - finds and returns a module with a given name */
384 /*-----------------------------------------------------------------*/
385 DEFSETFUNC(moduleWithName)
389 V_ARG(module **,rmod);
394 if (strcmp(mod->name,s) == 0) {
402 /*-----------------------------------------------------------------*/
403 /* moduleWithCName - finds and returns a module with a given c_name*/
404 /*-----------------------------------------------------------------*/
405 DEFSETFUNC(moduleWithCName)
409 V_ARG(module **,rmod);
413 if (strcmp(mod->c_name,s) == 0) {
421 /*-----------------------------------------------------------------*/
422 /* moduleWithAsmName - finds & returns a module with given asm_name*/
423 /*-----------------------------------------------------------------*/
424 DEFSETFUNC(moduleWithAsmName)
428 V_ARG(module **,rmod);
432 if (strcmp(mod->asm_name,s) == 0) {
441 /*-----------------------------------------------------------------*/
442 /* structWithName - returns a structure with a given name */
443 /*-----------------------------------------------------------------*/
444 structdef *structWithName (char *s)
449 /* go thru the struct table looking for a match */
450 for ( i = 0 ; i < nStructs ; i++ ) {
452 if (strcmp(currModName,structs[i]->sname) == 0 &&
453 strcmp(s,structs[i]->tag) == 0)
457 nsdef = Safe_calloc(1,sizeof(structdef));
458 nsdef->tag = alloccpy(s,strlen(s));
459 nsdef->sname = currModName ;
462 structs = (struct structdef **)resize((void **)structs,nStructs);
463 structs[nStructs-1] = nsdef;
467 /*-----------------------------------------------------------------*/
468 /* symWithRName - look for symbol with mangled name = parm */
469 /*-----------------------------------------------------------------*/
470 DEFSETFUNC(symWithRName)
474 V_ARG(symbol **,rsym);
479 if (strcmp(sym->rname,s) == 0) {
487 /*-----------------------------------------------------------------*/
488 /* funcWithRName - look for function with name */
489 /*-----------------------------------------------------------------*/
490 DEFSETFUNC(funcWithRName)
492 function *func = item;
494 V_ARG(function **,rfunc);
499 if (strcmp(func->sym->rname,s) == 0) {
507 /*-----------------------------------------------------------------*/
508 /* symLocal - local symbol respecting blocks & levels */
509 /*-----------------------------------------------------------------*/
517 V_ARG(symbol **,rsym);
519 if (strcmp(name,sym->name) == 0 && /* name matches */
520 sym->scopetype != 'G' && /* local scope */
521 (sym->sname && strcmp(sym->sname,sname) == 0) && /* scope == specified scope */
522 sym->block <= block && /* block & level kindo matches */
523 sym->level <= level) {
525 /* if a symbol was previously found then
526 sure that ones block & level are less
528 if (*rsym && (*rsym)->block >= block &&
529 (*rsym)->level >= level)
539 /*-----------------------------------------------------------------*/
540 /* symGlobal - return global symbol of name */
541 /*-----------------------------------------------------------------*/
542 DEFSETFUNC(symGlobal)
546 V_ARG(symbol **,rsym);
551 /* simple :: global & name matches */
552 if (sym->scopetype == 'G' &&
553 strcmp(sym->name,name) == 0) {
561 /*-----------------------------------------------------------------*/
562 /* symLookup - determine symbol from name & context */
563 /*-----------------------------------------------------------------*/
564 symbol *symLookup (char *name, context *ctxt)
568 if ((ctxt) && (ctxt->func) &&
569 (ctxt->func->sym) && (ctxt->func->sym->name)) {
570 /* first try & find a local variable for the given name */
571 if ( applyToSet(symbols,symLocal,
573 ctxt->func->sym->name,
581 if ((ctxt) && (ctxt->func) &&
582 (ctxt->func->mod) && (ctxt->func->mod->name)) {
583 /* then try local to this module */
584 if (applyToSet(symbols,symLocal,
586 ctxt->func->mod->name,
592 /* no:: try global */
593 if ( applyToSet(symbols,symGlobal,name,&sym))
596 /* cannot find return null */
600 /*-----------------------------------------------------------------*/
601 /* lnkFuncEnd - link record for end of function */
602 /*-----------------------------------------------------------------*/
603 static void lnkFuncEnd (char *s)
605 char sname[128], *bp = sname;
608 /* copy till we get to a ':' */
615 if (!applyToSet(functions,funcWithRName,sname,&func))
619 sscanf(s,"%x",&func->sym->eaddr);
621 Dprintf(D_symtab, ("symtab: %s(eaddr 0x%x)\n",func->sym->name,func->sym->eaddr));
624 /*-----------------------------------------------------------------*/
625 /* lnkSymRec - record for a symbol */
626 /*-----------------------------------------------------------------*/
627 static void lnkSymRec (char *s)
629 char sname[128], *bp = sname;
632 /* copy till we get to a ':' */
640 if (!applyToSet(symbols,symWithRName,sname,&sym))
644 sscanf(s,"%x",&sym->addr);
646 Dprintf(D_symtab, ("symtab: %s(0x%x)\n",sym->name,sym->addr));
649 /*-----------------------------------------------------------------*/
650 /* lnkAsmSrc - process linker record for asm sources */
651 /*-----------------------------------------------------------------*/
652 static void lnkAsmSrc (char *s)
654 char mname[128], *bp = mname;
659 /* input will be of format
660 filename$<line>:<address> */
661 while (*s != '$' && *s != '.')
664 /* skip to line stuff */
665 while (*s != '$') s++;
667 if (!applyToSet(modules,moduleWithName,mname,&mod))
670 if (sscanf(s,"$%d:%x",&line,&addr) != 2)
674 if (line < mod->nasmLines) {
675 mod->asmLines[line]->addr = addr;
676 Dprintf(D_symtab, ("symtab: %s(%d:0x%x) %s",mod->asm_name,line,addr,mod->asmLines[line]->src));
680 /*-----------------------------------------------------------------*/
681 /* lnkCSrc - process linker output for c source */
682 /*-----------------------------------------------------------------*/
683 static void lnkCSrc (char *s)
685 char mname[128], *bp = mname;
686 int block,level,line;
690 /* input will be of format
691 filename.ext$<level>$<block>$<line>:<address> */
692 /* get the module name */
696 /* skip the extension */
697 while (*s != '$') s++;
699 if (sscanf(s,"$%d$%d$%d:%x",
700 &line,&level,&block,&addr) != 4)
704 if (!applyToSet(modules,moduleWithCName,mname,&mod)) {
705 mod = parseModule(mname,FALSE);
706 mod->c_name = alloccpy(mname,strlen(mname));
707 mod->cfullname=searchDirsFname(mod->c_name);
708 mod->cLines = loadFile(mod->c_name,&mod->ncLines);
712 if (line < mod->ncLines && line > 0) {
713 mod->cLines[line]->addr = addr;
714 mod->cLines[line]->block = block;
715 mod->cLines[line]->level = level;
716 Dprintf(D_symtab, ("symtab: %s(%d:0x%x) %s",mod->c_name,
717 line+1,addr,mod->cLines[line]->src));
723 /*-----------------------------------------------------------------*/
724 /* parseLnkRec - parses a linker generated record */
725 /*-----------------------------------------------------------------*/
726 void parseLnkRec (char *s)
728 /* link records can be several types
729 dpeneding on the type do */
733 /* c source line address */
737 /* assembler source address */