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 #define LEVEL_UNIT 65536
33 /*-----------------------------------------------------------------*/
34 /* gc_strcat - allocate and return concatenated strings */
35 /*-----------------------------------------------------------------*/
36 char *gc_strcat(const char *s1
, const char *s2
, const char *s3
)
38 char *p
= Safe_malloc(strlen(s1
) + strlen(s2
) + strlen(s3
) + 1);
39 strcat(strcat(strcpy(p
, s1
), s2
), s3
);
43 /*------------------------------------------------------------------*/
44 /* getSize - returns size of a type chain in bits */
45 /*------------------------------------------------------------------*/
46 unsigned int getSize ( st_link
*p
)
48 /* if nothing return 0 */
52 if ( IS_SPEC(p
) ) /* if this is the specifier then */
54 switch (SPEC_NOUN(p
)) /* depending on the specifier type */
57 return (IS_LONG(p
) ? LONGSIZE
: ( IS_SHORT(p
) ? SHORTSIZE
: INTSIZE
));
65 return SPEC_STRUCT(p
)->size
;
71 return ((SPEC_BLEN(p
) / 8) + (SPEC_BLEN(p
) % 8 ? 1 : 0));
77 /* this is a specifier */
83 return DCL_ELEM(p
) * getSize (p
->next
);
99 /*-----------------------------------------------------------------*/
100 /* parseFunc - creates a function record entry */
101 /*-----------------------------------------------------------------*/
102 void parseFunc (char *line
)
108 while (*rs
&& *rs
!= '(')
112 func
= Safe_calloc(1, sizeof(function
));
114 applyToSetFTrue(symbols
, symWithRName
, line
, &func
->sym
);
117 func
->sym
= parseSymbol(line
, &rs
, 1);
118 func
->sym
->isfunc
= 1;
119 func
->modName
= currModName
;
120 while(*rs
&& *rs
!= ',')
123 sscanf(rs
, "%d,%d,%hd", &i
,
124 &(SPEC_INTN(func
->sym
->etype
)),
125 &(SPEC_BANK(func
->sym
->etype
)));
126 SPEC_INTRTN(func
->sym
->etype
) = i
;
127 addSet(&functions
, func
);
130 /*-----------------------------------------------------------------*/
131 /* parseTypeInfo - parse the type info of a symbol expects the type*/
132 /* info to be of the form */
133 /* ({<size>}<type info chain) */
134 /*-----------------------------------------------------------------*/
135 static char *parseTypeInfo (symbol
*sym
, char *s
)
139 s
+= 2; /* go past the ({ */
141 sym
->size
= (short)strtol (s
, &bp
, 10);
142 /* bp now points to '}' ... go past it */
144 while (*s
!= ')') /* till we reach the end */
147 type
= Safe_calloc(1, sizeof(st_link
));
151 /* is a declarator */
158 DCL_TYPE(type
) = FUNCTION
;
162 DCL_TYPE(type
) = GPOINTER
;
166 DCL_TYPE(type
) = CPOINTER
;
170 DCL_TYPE(type
) = FPOINTER
;
174 DCL_TYPE(type
) = POINTER
;
178 DCL_TYPE(type
) = IPOINTER
;
182 DCL_TYPE(type
) = PPOINTER
;
187 DCL_TYPE(type
) = ARRAY
;
188 DCL_ELEM(type
) = (short)strtol(s
,&s
,10);
195 type
->class = SPECIFIER
;
200 SPEC_NOUN(type
) = V_INT
;
205 SPEC_NOUN(type
) = V_INT
;
210 SPEC_NOUN(type
) = V_CHAR
;
214 SPEC_NOUN(type
) = V_VOID
;
218 SPEC_NOUN(type
) = V_FLOAT
;
223 SPEC_NOUN(type
) = V_STRUCT
;
225 char *ss
= strtok(strdup(s
), ",):");
227 SPEC_STRUCT(type
) = structWithName(ss
);
233 SPEC_NOUN(type
) = V_SBIT
;
236 SPEC_NOUN(type
) = V_BIT
;
238 SPEC_BSTR(type
) = strtol(s
, &s
, 10);
240 SPEC_BLEN(type
) = strtol(s
, &s
, 10);
247 SPEC_USIGN(type
) = 0;
249 SPEC_USIGN(type
) = 1;
252 /* add the type to the symbol's type chain */
254 sym
->etype
= sym
->etype
->next
= type
;
256 sym
->type
= sym
->etype
= type
;
262 int calcLevel(int level1
, int level2
)
264 return (level1
* LEVEL_UNIT
) + level2
;
267 int parseLevel(char *s
, char **rs
, int base
)
271 long level
= strtol (s
, &bp
, 10);
275 level
= calcLevel(level
, strtol (s
, &bp
, 10));
283 char *allocRName(char *start
, int length
)
285 int idx
= length
> 2 ? length
- 2 : 0;
287 while(idx
&& start
[idx
] != '$')
289 if(start
[idx
] == '_')
298 return alloccpy(start
, length
);
301 /*-----------------------------------------------------------------*/
302 /* symFromRec - parse a symbol record and extract and create a sym */
303 /* expects the input string to be of the form */
304 /* {G|F<filename>|L<filename>'.'<functionName>}'$' */
305 /* <name>'$'<level>'$'<block><type info> */
306 /*-----------------------------------------------------------------*/
307 symbol
*parseSymbol (char *s
, char **rs
, int doadd
)
313 /* go the mangled name */
314 for ( bp
= s
; *bp
&& *bp
!= '('; bp
++ )
321 /* add only if not present and if linkrecord before symbol record */
322 if ( applyToSetFTrue(symbols
, symWithRName
, s
, &nsym
))
324 if ( nsym
->rname
!= nsym
->name
)
331 nsym
= Safe_calloc(1, sizeof(symbol
));
332 nsym
->rname
= allocRName(s
, bp
- s
);
335 /* if this is a Global Symbol */
336 nsym
->scopetype
= *s
;
338 if (nsym
->scopetype
!= 'G')
340 /* get the function name it is local to */
344 nsym
->sname
= alloccpy(bp
, s
- bp
);
347 /* next get the name */
351 nsym
->name
= alloccpy(bp
, s
- bp
);
354 /* get the level number */
355 nsym
->level
= parseLevel (s
, &bp
, 10);
357 /* skip the '$' & get the block number */
358 nsym
->block
= (short)strtol (s
, &bp
, 10);
360 s
= parseTypeInfo(nsym
, bp
);
362 /* get the address space after going past the comma */
364 nsym
->addrspace
= *s
;
367 nsym
->isonstack
= (short)strtol(s
, &s
, 10);
368 /* get the stack offset */
370 nsym
->offset
= strtol(s
, &s
, 10);
372 if ( nsym
->addrspace
== 'R' )
374 /* get registeroffset */
375 while (*s
&& *s
!= '[')
380 nsym
->addr
= strtol(s
+1, &s
, 10);
382 while (*s
&& *s
!= ']')
388 addSet(&symbols
, nsym
);
390 Dprintf(D_symtab
, ("symtab: par %s(0x%x) add=%d sym=%p\n",
391 nsym
->name
, nsym
->addr
, doadd
, nsym
));
393 Dprintf(D_symtab
, ("symbol\n name: %s\n size: %d\n level: %hd\n block: %hd\n isonstack: %hd\n",
394 nsym
->name
, nsym
->size
, nsym
->level
, nsym
->block
, nsym
->isonstack
));
396 Dprintf(D_symtab
, (" isfunc: %d\n offset: %d\n addr: %d\n eaddr: %d\n",
397 nsym
->isfunc
, nsym
->offset
, nsym
->addr
, nsym
->eaddr
));
399 Dprintf(D_symtab
, (" addr_type: %c\n type: %p\n etype: %p\n",
400 nsym
->addr_type
, nsym
->type
, nsym
->type
));
402 Dprintf(D_symtab
, (" scopetype: %c\n sname: %s\n rname: %s\n addrspace: %c\n",
403 nsym
->scopetype
, nsym
->sname
, nsym
->rname
, nsym
->addrspace
));
408 /*-----------------------------------------------------------------*/
409 /* parseStruct - parses a structure record expected in format */
410 /* {F<filename>}$<tag>[()()()...] */
411 /*-----------------------------------------------------------------*/
412 structdef
*parseStruct (char *s
)
417 symbol
*fields
= NULL
;
425 name
= alloccpy(bp
,s
- bp
);
426 nsdef
= structWithName(name
);
427 nsdef
->fields
= NULL
;
430 while (*s
&& *s
!= ']')
436 offset
= strtol(s
,&s
,10);
440 sym
= parseSymbol(s
,&s
,0);
441 sym
->offset
= offset
;
444 fields
= nsdef
->fields
= sym
;
446 fields
= fields
->next
= sym
;
447 nsdef
->size
+= sym
->size
;
453 /*-----------------------------------------------------------------*/
454 /* parseModule - creates a module with a given name */
455 /*-----------------------------------------------------------------*/
456 module
*parseModule (char *s
, bool createName
)
461 nmod
= Safe_calloc(1, sizeof(module
));
463 addSet (&modules
, nmod
);
465 /* create copy file name */
470 sprintf(buffer
, "%s.c", s
);
471 nmod
->c_name
= Safe_malloc(strlen(buffer
)+1);
472 strcpy(nmod
->c_name
, buffer
);
474 sprintf(buffer
, "%s.asm", s
);
475 nmod
->asm_name
= Safe_malloc(strlen(buffer
)+1);
476 strcpy(nmod
->asm_name
, buffer
);
482 /*-----------------------------------------------------------------*/
483 /* moduleWithName - finds and returns a module with a given name */
484 /*-----------------------------------------------------------------*/
485 DEFSETFUNC(moduleWithName
)
489 V_ARG(module
**, rmod
);
494 if (strcmp(mod
->name
, s
) == 0)
503 /*-----------------------------------------------------------------*/
504 /* moduleWithCName - finds and returns a module with a given c_name*/
505 /*-----------------------------------------------------------------*/
506 DEFSETFUNC(moduleWithCName
)
510 V_ARG(module
**, rmod
);
515 if (strcmp(mod
->c_name
, s
) == 0)
524 /*-----------------------------------------------------------------*/
525 /* moduleWithAsmName - finds & returns a module with given asm_name*/
526 /*-----------------------------------------------------------------*/
527 DEFSETFUNC(moduleWithAsmName
)
531 V_ARG(module
**, rmod
);
536 if (strcmp(mod
->asm_name
, s
) == 0)
545 /*-----------------------------------------------------------------*/
546 /* structWithName - returns a structure with a given name */
547 /*-----------------------------------------------------------------*/
548 structdef
*structWithName (char *s
)
553 /* go thru the struct table looking for a match */
554 for ( i
= 0 ; i
< nStructs
; i
++ )
556 if (strcmp(currModName
,structs
[i
]->sname
) == 0 &&
557 strcmp(s
,structs
[i
]->tag
) == 0)
563 nsdef
= Safe_calloc(1,sizeof(structdef
));
564 nsdef
->tag
= alloccpy(s
,strlen(s
));
565 nsdef
->sname
= currModName
;
568 structs
= (struct structdef
**)resize((void **)structs
,nStructs
);
569 structs
[nStructs
-1] = nsdef
;
573 /*-----------------------------------------------------------------*/
574 /* symWithRName - look for symbol with mangled name = parm */
575 /*-----------------------------------------------------------------*/
576 DEFSETFUNC(symWithRName
)
580 V_ARG(symbol
**, rsym
);
585 if (strcmp(sym
->rname
, s
) == 0)
594 /*-----------------------------------------------------------------*/
595 /* funcWithRName - look for function with name */
596 /*-----------------------------------------------------------------*/
597 DEFSETFUNC(funcWithRName
)
599 function
*func
= item
;
601 V_ARG(function
**,rfunc
);
606 if (strcmp(func
->sym
->rname
,s
) == 0)
615 /*-----------------------------------------------------------------*/
616 /* symLocal - local symbol respecting blocks & levels */
617 /*-----------------------------------------------------------------*/
622 V_ARG(char *, sname
);
625 V_ARG(symbol
**, rsym
);
627 if (strcmp(name
, sym
->name
) == 0 && /* name matches */
628 sym
->scopetype
!= 'G' && /* local scope */
630 strcmp(sym
->sname
, sname
) == 0 && /* scope == specified scope */
631 sym
->block
<= block
&& /* block & level kindo matches */
634 /* if a symbol was previously found then
635 sure that ones block & level are less
637 if (*rsym
&& (*rsym
)->block
>= block
&& (*rsym
)->level
>= level
)
647 /*-----------------------------------------------------------------*/
648 /* symGlobal - return global symbol of name */
649 /*-----------------------------------------------------------------*/
650 DEFSETFUNC(symGlobal
)
654 V_ARG(symbol
**, rsym
);
659 /* simple :: global & name matches */
660 if (sym
->scopetype
== 'G' &&
661 strcmp(sym
->name
, name
) == 0)
670 /*-----------------------------------------------------------------*/
671 /* symLookup - determine symbol from name & context */
672 /*-----------------------------------------------------------------*/
673 symbol
*symLookup (char *name
, context
*ctxt
)
677 if ((ctxt
) && (ctxt
->func
) &&
678 (ctxt
->func
->sym
) && (ctxt
->func
->sym
->name
))
680 char *sname
= gc_strcat(ctxt
->func
->mod
->name
, ".", ctxt
->func
->sym
->name
);
681 /* first try & find a local variable for the given name */
682 if ( applyToSet(symbols
, symLocal
,
696 if ((ctxt
) && (ctxt
->func
) &&
697 (ctxt
->func
->mod
) && (ctxt
->func
->mod
->name
))
699 /* then try local to this module */
700 if (applyToSet(symbols
, symLocal
,
702 ctxt
->func
->mod
->name
,
712 /* no:: try global */
713 if ( applyToSet(symbols
, symGlobal
, name
, &sym
))
716 /* cannot find return null */
720 /*-----------------------------------------------------------------*/
721 /* lnkFuncEnd - link record for end of function */
722 /*-----------------------------------------------------------------*/
723 static void lnkFuncEnd (char *s
)
725 char sname
[128], *bp
= sname
;
728 /* copy till we get to a ':' */
735 if (!applyToSet(functions
,funcWithRName
,sname
,&func
))
739 sscanf(s
,"%x",&func
->sym
->eaddr
);
741 Dprintf(D_symtab
, ("symtab: ead %s(0x%x)\n",func
->sym
->name
,func
->sym
->eaddr
));
744 /*-----------------------------------------------------------------*/
745 /* lnkSymRec - record for a symbol */
746 /*-----------------------------------------------------------------*/
747 static void lnkSymRec (char *s
)
752 /* search to a ':' */
753 for ( bp
= s
; *bp
&& *bp
!= ':'; bp
++ );
758 applyToSetFTrue(symbols
,symWithRName
,s
,&sym
);
761 sym
= Safe_calloc(1,sizeof(symbol
));
762 sym
->rname
= allocRName(s
,bp
- s
);
764 sym
->name
= sym
->rname
;
765 addSet(&symbols
,sym
);
770 sscanf(bp
+2,"%x",&sym
->addr
);
772 Dprintf(D_symtab
, ("symtab: lnk %s(0x%x)\n",sym
->name
,sym
->addr
));
775 /*-----------------------------------------------------------------*/
776 /* lnkAsmSrc - process linker record for asm sources */
777 /*-----------------------------------------------------------------*/
778 static void lnkAsmSrc (char *s
)
780 char mname
[128], *bp
= mname
;
785 /* input will be of format
786 filename$<line>:<address> */
787 while (*s
!= '$' && *s
!= '.')
790 /* skip to line stuff */
794 if (!applyToSet(modules
, moduleWithName
, mname
, &mod
))
797 if (sscanf(s
, "$%d:%x", &line
, &addr
) != 2)
801 if (line
< mod
->nasmLines
)
803 mod
->asmLines
[line
]->addr
= addr
;
804 Dprintf(D_symtab
, ("symtab: asm %s(%d:0x%x) %s", mod
->asm_name
, line
, addr
, mod
->asmLines
[line
]->src
));
808 /*-----------------------------------------------------------------*/
809 /* lnkCSrc - process linker output for c source */
810 /*-----------------------------------------------------------------*/
811 static void lnkCSrc (char *s
)
813 char mname
[128], *bp
= mname
;
814 int block
,level
,line
;
820 /* input will be of format
821 filename.ext$<line>$<level>$<block>:<address> */
822 /* get the module name */
826 /* skip the extension */
830 if (sscanf(s
,"$%d$%d$%d:%x", &line
,&level2
,&block
,&addr
) != 4)
831 if (sscanf(s
,"$%d$%d_%d$%d:%x", &line
,&level1
,&level2
,&block
,&addr
) != 5)
834 level
= calcLevel(level1
, level2
);
837 if (!applyToSet(modules
,moduleWithCName
,mname
,&mod
))
839 mod
= parseModule(mname
, FALSE
);
840 mod
->c_name
= alloccpy(mname
,strlen(mname
));
841 mod
->cfullname
=searchDirsFname(mod
->c_name
);
842 mod
->cLines
= loadFile(mod
->c_name
,&mod
->ncLines
);
846 /* one line can have more than one address : (for loops !)*/
847 if (line
< mod
->ncLines
&& line
> 0 /*&&
848 ( !mod->cLines[line]->addr ||
849 mod->cLines[line]->level > level )*/ )
851 if ( mod
->cLines
[line
]->addr
!= INT_MAX
)
853 /* save double line information for exepoints */
855 ep
= Safe_calloc(1,sizeof(exePoint
));
856 ep
->addr
= mod
->cLines
[line
]->addr
;
858 ep
->block
= mod
->cLines
[line
]->block
;
859 ep
->level
= mod
->cLines
[line
]->level
;
860 addSet(&mod
->cfpoints
,ep
);
861 Dprintf(D_symtab
, ("symtab: exe %s(%d:0x%x) %s", mod
->c_name
,
862 line
+1, addr
, mod
->cLines
[line
]->src
));
864 mod
->cLines
[line
]->addr
= addr
;
865 mod
->cLines
[line
]->block
= block
;
866 mod
->cLines
[line
]->level
= level
;
867 Dprintf(D_symtab
, ("symtab: ccc %s(%d:0x%x) %s", mod
->c_name
,
868 line
+1, addr
, mod
->cLines
[line
]->src
));
873 /*-----------------------------------------------------------------*/
874 /* parseLnkRec - parses a linker generated record */
875 /*-----------------------------------------------------------------*/
876 void parseLnkRec (char *s
)
878 /* link records can be several types
879 dpeneding on the type do */
883 /* c source line address */
887 /* assembler source address */