2 * Copyright (c) 1996 Barton P. Miller
4 * We provide the Paradyn Parallel Performance Tools (below
5 * described as Paradyn") on an AS IS basis, and do not warrant its
6 * validity or performance. We reserve the right to update, modify,
7 * or discontinue this software at any time. We shall have no
8 * obligation to supply such updates or modifications or any other
9 * form of support to you.
11 * This license is for research uses. For such uses, there is no
12 * charge. We define "research use" to mean you may freely use it
13 * inside your organization for whatever purposes you see fit. But you
14 * may not re-distribute Paradyn or parts of Paradyn, in any form
15 * source or binary (including derivatives), electronic or otherwise,
16 * to any other organization or entity without our permission.
18 * (for other uses, please contact us at paradyn@cs.wisc.edu)
20 * All warranties, including without limitation, any warranty of
21 * merchantability or fitness for a particular purpose, are hereby
24 * By your use of Paradyn, you understand and agree that we (or any
25 * other person or entity with proprietary rights in Paradyn) are
26 * under no obligation to provide either maintenance services,
27 * update services, notices of latent defects, or correction of
28 * defects for Paradyn.
30 * Even if advised of the possibility of such damages, under no
31 * circumstances shall we (or any other person or entity with
32 * proprietary rights in the software licensed hereunder) be liable
33 * to you or any third party for direct, indirect, or consequential
34 * damages of any character regardless of type of action, including,
35 * without limitation, loss of profits, loss of use, loss of good
36 * will, or computer failure or malfunction. You agree to indemnify
37 * us (and any other person or entity with proprietary rights in the
38 * software licensed hereunder) for any and all liability it may
39 * incur to third parties resulting from your use of Paradyn.
45 #include "BPatch_module.h"
46 #include "BPatch_collections.h"
47 #include "showerror.h"
49 extern char *current_func_name;
51 // Forward references for parsing routines
52 static int parseSymDesc(char *stabstr, int &cnt);
53 static BPatch_type *parseConstantUse(BPatch_module*, char *stabstr, int &cnt);
54 static char *parseTypeDef(BPatch_module*, char *stabstr, char *name, int ID);
55 static int parseTypeUse(BPatch_module*, char *&stabstr, int &cnt, char *name);
56 static inline bool isSymId(char ch);
57 static char *getIdentifier(char *stabstr, int &cnt);
60 // Start of code to parse Stab information.
61 // The structure of this code is a recursive decent parser that parses
62 // information in stab records and builds up the corresponding BPatch_types.
64 // Each non-terminal in the grammer has a function of the form parse<NT>.
66 // The grammar for a non-terminal appears in the comments just before
67 // the non-terminal parsing function
70 // This function takes the stab stabstring and parses it to create a new
71 // type or variable object. This function only defines the type/variable
74 // <stabString> = <ident>:<symDesc> |
75 // <ident>:c<constantUse> |
76 // <ident>:f<symDesc> |
77 // <ident>:f<syymDesc>,<ident>,<ident> |
78 // <ident>:F<typeUse><paramList> |
79 // <ident>:G<typeUse> |
81 // <ident>:S<typeUse> |
82 // <ident>:[pPr]<typeUse> |
83 // <ident>::T<typeUse> |
84 // <ident>:t<typeUse> |
85 // <ident>:T<typeUse> |
86 // <ident>:v<typeUse> |
89 // <paramList> = | <typeUse>;<paramList>
91 char *parseStabString(BPatch_module *mod, int linenum, char *stabstr,
92 int framePtr, BPatch_type *commonBlock = NULL)
100 BPatch_type * ptrType = NULL;
101 BPatch_type * newType = NULL; // For new types to add to the collection
102 BPatch_localVar *locVar = NULL;
103 #ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
104 fprintf(stderr, "%s[%d]: inside parseStabStr\n", __FILE__, __LINE__);
109 /* get type or variable name */
110 char *name = getIdentifier(stabstr, cnt);
114 // AIX puts out some symbols like this eg .bs
115 if (stabstr[cnt] != ':') {
119 if (stabstr[cnt] == ':') {
124 if (isSymId(stabstr[cnt])) {
125 /* instance of a predefined type */
127 ID = parseSymDesc(stabstr, cnt);
129 //printf("Variable: %s Type ID: %d, file ID %d \n",name, ID, file_ID);
130 if (stabstr[cnt] == '=') {
131 /* More Stuff to parse, call parseTypeDef */
132 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name, ID);
134 ptrType = mod->moduleTypes->findType( ID);
135 if (current_func_name) {
136 // XXX-may want to use N_LBRAC and N_RBRAC to set function scope
138 // Still need to add to local variable list if in a function
139 fp = mod->findFunction( current_func_name );
142 mod->getName(modName, 99);
143 printf(" Can't find function %s in module %s\n", current_func_name, modName);
144 printf("Unable to add %s to local variable list in %s\n",
145 name,current_func_name);
147 locVar = new BPatch_localVar(name, ptrType, linenum, framePtr);
149 printf("adding local var with missing type %s, type = %d\n",
152 fp->localVariables->addLocalVar( locVar);
155 } else if (current_func_name) {
156 // Try to find the BPatch_Function
157 ptrType = mod->moduleTypes->findType( ID);
158 fp = mod->findFunction(current_func_name);
161 mod->getName(modName, 99);
162 printf(" Can't find function in BPatch_function vector: %s in module %s\n",
163 current_func_name, modName);
165 locVar = new BPatch_localVar(name, ptrType, linenum, framePtr);
167 printf("adding local var with missing type %s, type = %d\n",
170 fp->localVariables->addLocalVar( locVar);
173 } else if (stabstr[cnt]) {
174 switch (stabstr[cnt]) {
175 case 'f': /*Local Function*/ {
176 char *scopeName=NULL;
177 char *lfuncName=NULL;
179 current_func_name = name;
180 // funcReturnID = parseSymDesc(stabstr, cnt);
181 funcReturnID = parseTypeUse(mod, stabstr, cnt, name);
183 if (stabstr[cnt]==',') {
184 cnt++; /*skip the comma*/
186 /* Local Function Name */
187 lfuncName = getIdentifier(stabstr, cnt);
189 assert(stabstr[cnt] == ',');
190 cnt++; /*skip the comma*/
192 /* Scope Name of Local Function */
193 scopeName = getIdentifier(stabstr, cnt);
196 fprintf(stderr, "Extra: %s\n", &stabstr[cnt]);
200 if (!scopeName) { // Not an embeded function
201 ptrType = mod->moduleTypes->findType(funcReturnID);
202 if( !ptrType) ptrType = BPatch::bpatch->type_Untyped;
204 fp = mod->findFunction( name );
206 showInfoCallback(string("missing local function ") +
210 fp->setReturnType(ptrType);
213 printf("%s is an embedded function in %s\n",name, scopeName);
218 case 'F':/* Global Function */
219 cnt++; /*skipping 'F' */
221 funcReturnID = parseTypeUse(mod, stabstr, cnt, name);
222 current_func_name = name;
225 // For SunPro compilers there may be a parameter list after
228 while (stabstr[cnt] == ';') {
230 (void) parseTypeUse(mod, stabstr, cnt, "");
233 ptrType = mod->moduleTypes->findType(funcReturnID);
234 if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
236 fp = mod->findFunction( name );
238 // for FORTRAN look with trailing _
239 char tempName[strlen(name)+2];
240 sprintf(tempName, "%s_", name);
242 // this leaks tempName XXXX
243 current_func_name = strdup(tempName);
245 fp = mod->findFunction(tempName);
247 showInfoCallback(string("missing local function ") +
254 fp->setReturnType(ptrType);
258 case 'G':/* Global Varaible */
259 cnt++; /* skip the 'G' */
261 /* Get variable type number */
262 symdescID = parseTypeUse(mod, stabstr, cnt, name);
264 fprintf(stderr, "\tMore to parse %s\n", &stabstr[cnt]);
266 // lookup symbol and set type
269 BPtype = mod->moduleTypes->findType(symdescID);
272 "ERROR: unable to find type #%d for variable %s\n",
275 /** XXXX - should add local too here **/
276 mod->moduleTypes->addGlobalVariable(name, BPtype);
280 case 'R': // function parameter passed in a register (AIX style)
281 case 'P': // function parameter passed in a register (GNU/Solaris)
282 case 'v': // Fortran Local Variable
283 case 'X': // Fortran function return Variable (e.g. function name)
284 case 'p': { // Function Parameter
285 cnt++; /* skip the 'p' */
287 /* Get variable type number */
288 symdescID = parseTypeUse(mod, stabstr, cnt, name);
290 if (stabstr[cnt] == ';') {
291 // parameter type information, not used for now
292 cnt = strlen(stabstr);
293 } else if (stabstr[cnt]) {
294 fprintf(stderr, "\tMore to parse %s\n", &stabstr[cnt]);
297 ptrType = mod->moduleTypes->findType(symdescID);
298 if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
300 BPatch_localVar *param;
301 param = new BPatch_localVar(name, ptrType, linenum, framePtr);
303 if (current_func_name) {
304 fp = mod->findFunction( current_func_name );
306 showInfoCallback(string("missing local function ") +
307 string(current_func_name));
308 } else { // found function, add parameter
309 fp->funcParameters->addLocalVar(param);
310 fp->addParam(name, ptrType, linenum, framePtr);
313 showInfoCallback(string("parameter without local function ")
319 case 'c': /* constant */
320 cnt++; /*move past the 'c' */
322 ptrType = parseConstantUse(mod, stabstr, cnt);
324 printf("Parsing Error More constant info to Parse!!: %s\n",
327 if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
329 BPatch_localVar *var;
330 var = new BPatch_localVar(name, ptrType, linenum, 0);
332 if (current_func_name) {
333 fp = mod->findFunction( current_func_name );
335 showInfoCallback(string("missing local function ") +
336 string(current_func_name));
337 } else { // found function, add parameter
338 fp->funcParameters->addLocalVar(var);
339 fp->addParam(name, ptrType, linenum, 0);
342 showInfoCallback(string("parameter without local function ")
347 case 'r':/* Register Variable */
348 cnt++; /*move past the 'r'*/
349 /* get type reference */
351 symdescID = parseSymDesc(stabstr, cnt);
354 /* often have rNN=*yy - what is this ? jkh 11/30/00 */
356 printf("Parsing Error More register info to Parse!!: %s\n",
361 case 'S':/* Global Static Variable */ {
362 cnt++; /*move past the 'S'*/
364 /* get type reference */
365 symdescID = parseTypeUse(mod, stabstr, cnt, name);
367 // lookup symbol and set type
370 BPtype = mod->moduleTypes->findType(symdescID);
373 "ERROR: unable to find type #%d for variable %s\n",
376 BPatch_image *img = (BPatch_image *) mod->getObjParent();
377 if (img->findVariable(name,false)) {
378 mod->moduleTypes->addGlobalVariable(name, BPtype);
383 printf("Parsing Error More Global Static info to Parse!!: %s\n",
388 case 't': // Type Name
389 cnt++; /*move past the 't'*/
391 /* get type reference */
392 symdescID = parseSymDesc(stabstr, cnt);
394 //Create BPatch_type.
395 if (stabstr[cnt] == '=') {
396 /* More Stuff to parse, call parseTypeDef */
397 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name, symdescID);
399 // AIX seems to append an semi at the end of these
400 if (stabstr[0] && strcmp(stabstr, ";")) {
401 fprintf(stderr, "\tMore to parse %s\n", stabstr);
404 //Create BPatch_type defined as a pre-exisitng type.
405 ptrType = mod->moduleTypes->findType(symdescID);
407 ptrType = BPatch::bpatch->type_Untyped;
408 newType = new BPatch_type(name, symdescID, ptrType);
410 mod->moduleTypes->addType(newType);
415 case ':': // :T... - skip ":" and parse 'T'
416 if ((stabstr[cnt+1] == 't') || (stabstr[cnt+1] == 'T')) {
417 // parse as a normal typedef
418 parseStabString(mod, linenum, &stabstr[cnt+1], framePtr);
420 fprintf(stderr, "Unknown type seen %s\n", stabstr);
424 case 'T':/* Aggregate type tag -struct, union, enum */
425 cnt++; /*move past the 'T'*/
427 if (stabstr[cnt] == 't') {
428 //C++ struct tag "T" and type def "t"
429 //printf("SKipping C++ Identifier t of Tt\n");
433 /* get type reference */
434 symdescID = parseSymDesc(stabstr, cnt);
436 //Create BPatch_type.
437 if (stabstr[cnt] == '=') {
438 /* More Stuff to parse, call parseTypeDef */
439 stabstr = parseTypeDef(mod,(&stabstr[cnt+1]),name,symdescID);
442 fprintf(stderr, "\tMore to parse %s\n", (&stabstr[cnt]));
445 //Create BPatch_type defined as a pre-exisitng type.
446 newType = new BPatch_type(name, symdescID);
447 if (newType) mod->moduleTypes->addType(newType);
452 case 'V':/* Local Static Variable (common block vars too) */
453 cnt++; /*move past the 'V'*/
455 // printf("parsing 'v' type of %s\n", stabstr);
456 /* Get variable type number */
457 symdescID = parseTypeUse(mod, stabstr, cnt, name);
459 fprintf(stderr, "\tMore to parse %s\n", &stabstr[cnt]);
461 // lookup symbol and set type
462 BPtype = mod->moduleTypes->findType(symdescID);
465 "ERROR: unable to find type #%d for variable %s\n",
470 /* This variable is in a common block */
471 /* add it only if not already there, common block
472 are re-defined for each subroutine but subroutines
473 define only the member they care about
476 BPatch_Vector<BPatch_field *> *fields;
478 fields = commonBlock->getComponents();
480 for (unsigned int i=0; i < fields->size(); i++) {
481 if (!strcmp((*fields)[i]->getName(), name)) {
485 int start1, start2, end1, end2;
486 start1 = (*fields)[i]->getOffset();
487 end1 = start1 + (*fields)[i]->getSize();
489 end2 = framePtr + BPtype->getSize();
490 if (((start2 >= start1) && (start2 < end1)) ||
491 ((start1 >= start2) && (start1 < end2))) {
492 /* common block aliasing detected */
493 printf("WARN: EQUIVALENCE used in %s: %s and %s\n",
494 current_func_name, name, (*fields)[i]->getName());
501 commonBlock->addField(name, BPatch_dataScalar, BPtype,
502 framePtr, BPtype->getSize());
505 // put it into the local variable scope
506 fp = mod->findFunction( current_func_name );
509 mod->getName(modName, 99);
510 printf(" Can't find function %s in module %s\n",
511 current_func_name, modName);
512 printf("Unable to add %s to local variable list in %s\n",
513 name,current_func_name);
515 printf("adding local variable %s at %x\n",
517 locVar = new BPatch_localVar(name, BPtype, linenum,
519 fp->localVariables->addLocalVar( locVar);
524 fprintf(stderr, "Unknown symbol descriptor: %c\n", stabstr[cnt]);
525 fprintf(stderr, " : %s\n", stabstr);
528 return(&stabstr[cnt]);
529 } /* end of parseStabString */
533 // Is the current character a valid prefix for a symDesc non-terminal?
535 inline bool isSymId(char ch)
537 return ((ch == '(') || isdigit(ch) || (ch == '-'));
541 // parse a Symbol Descriptor ID
542 // symDesc = <int> | (<int>,<int>)
544 int parseSymDesc(char *stabstr, int &cnt)
550 bool newForm = false;
552 hid = 0; //file-number
553 // parse both an int and (int,int) format (file-number, type ID)
554 if (stabstr[cnt] == '(') {
556 while (isdigit(stabstr[cnt])) {
557 hid = hid * 10 + stabstr[cnt] - '0';
562 if (stabstr[cnt] == ',') cnt++;
566 if (stabstr[cnt] == '-') {
572 while (isdigit(stabstr[cnt])) {
573 lid = lid * 10 + stabstr[cnt] - '0';
582 id = hid * 65536 + lid;
588 // parse an identifier up to a ":" or "," or ";"
590 char *getIdentifier(char *stabstr, int &cnt)
598 switch(stabstr[cnt+i]) {
626 ret = (char *) malloc(i+1);
629 strncpy(ret, &stabstr[cnt], i);
637 // Parse a use of a type.
639 // <typeUse> = <symDesc> | <symDesc>=<typeDef>
641 static int parseTypeUse(BPatch_module *mod,char *&stabstr, int &cnt, char *name)
643 int ret = parseSymDesc(stabstr, cnt);
645 if (stabstr[cnt] == '=') {
646 /* More Stuff to parse, call parseTypeDef */
647 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name, ret);
654 // parseCrossRef - internal struct/union pointer
656 // <crossRef> = [s|u|e]<ident>
658 static char *parseCrossRef(BPatch_typeCollection *moduleTypes, char *name,
659 int ID, char *stabstr, int &cnt)
662 BPatch_type *newType;
663 BPatch_dataClass typdescr = BPatch_dataPointer;
666 if ((stabstr[cnt] == 's') || // struct
667 (stabstr[cnt] == 'u') || // union
668 (stabstr[cnt] == 'e')) { // enum
671 temp = getIdentifier(stabstr, cnt);
674 // Find type that this one points to.
675 BPatch_type *ptrType = moduleTypes->findType(temp);
677 //Create a new B_type that points to a structure
678 newType = new BPatch_type(name, ID, typdescr, ptrType);
679 // Add to typeCollection
681 moduleTypes->addType(newType);
683 printf(" Can't Allocate new type ");
688 /* don't know what it is?? */
690 temp = getIdentifier(stabstr, cnt);
694 return( &(stabstr[cnt]));
698 // parse the definition of an array.
699 // arrayDef = ar<symDesc>;<symDesc>;<symDesc>;<symDesc> |
700 // ar<symDesc>;<symDesc>;<symDesc>;<arrayDef>
702 static BPatch_type *parseArrayDef(BPatch_module *mod, char *name,
703 int ID, char *stabstr, int &cnt)
708 BPatch_type *newType = NULL;
709 BPatch_type *ptrType = NULL;
710 int lowbound, hibound;
712 // format is ar<indexType>;<lowBound>;<highBound>;<elementType>
714 assert(stabstr[cnt] == 'a');
717 if (stabstr[cnt] != 'r') {
718 printf("unknown array definition seen %s\n", &stabstr[cnt]);
722 /* array with range */
723 symdesc = &(stabstr[cnt]);
725 cnt++; /* skip 'r' */
726 symdescID = parseSymDesc(stabstr, cnt);
728 cnt++; /* skip semicolon */
729 lowbound = parseSymDesc(stabstr, cnt);
731 cnt++; /* skip semicolon */
732 if (stabstr[cnt] == 'J') {
733 /* Fortran unbounded array */
736 } else if (stabstr[cnt] == 'T') {
737 /* Fortran runtime bound array - T0 is the form */
741 hibound = parseSymDesc(stabstr, cnt);
744 cnt++; /* skip semicolon */
745 elementType = parseSymDesc(stabstr, cnt);
747 if (stabstr[cnt] == 'a') {
748 /* multi dimensional array - Fortran style */
749 /* it has no valid id, so we give it a known duplicate */
750 ptrType = parseArrayDef(mod, name, 0, stabstr, cnt);
752 if (stabstr[cnt] == '=') {
753 /* multi dimensional array */
755 temp = parseTypeDef(mod, &(stabstr[cnt+1]), NULL, elementType);
756 /* parseTypeDef uses old style of returning updated stabstr,
757 but parseArrayDef function needs to return an updated cnt.
758 This simple hack updates cnt based on how far parseTypDef
759 advances it. jkh 12/4/00 */
761 if (stabstr[cnt] == ':') {
763 //printf("Skipping C++ rest of array def: %s\n",name );
764 while (stabstr[cnt] != ';') cnt++;
767 ptrType = mod->moduleTypes->findType(elementType);
770 // fprintf(stderr, "Symbol Desriptor: %s Descriptor ID: %d Type: %d, Low Bound: %d, Hi Bound: %d,\n", symdesc, symdescID, elementType, lowbound, hibound);
774 // Create new type - field in a struct or union
775 newType = new BPatch_type(name, ID, BPatch_dataArray, ptrType,
779 mod->moduleTypes->addType(newType);
781 fprintf(stderr, " Could not create newType Array\n");
786 // fprintf(stderr, "parsed array def to %d, remaining %s\n", cnt, &stabstr[cnt]);
790 #if defined(i386_unknown_linux2_0) || defined(ia64_unknown_linux2_4) /* temporary duplication - TLM */
792 // parse range type of the form:
794 // <rangeType> = r<typeNum>;<low>;<high>;
796 static char *parseRangeType(BPatch_module *mod,char *name,int ID, char *stabstr)
803 assert(stabstr[0] == 'r');
806 BPatch_dataClass typdescr = BPatchSymTypeRange;
808 // range index type - not used
809 (void) parseSymDesc(stabstr, cnt);
811 // printf("\tSymbol Descriptor: %c and Value: %d\n",tmpchar, symdescID);
813 cnt++; /* Discarding the ';' */
814 if (stabstr[cnt] == '-' ) cnt++;
816 /* Getting type range or size */
818 while (isdigit(stabstr[cnt+i])) i++;
820 char *low = (char *)malloc(sizeof(char)*(i+1));
821 if(!strncpy(low, &(stabstr[cnt]), i))
822 /* Error copying size/range*/
826 cnt = cnt + i + 1; /* Discard other Semicolon */
828 if((stabstr[cnt]) == '-') {
829 i++; /* discard '-' for (long) unsigned int */
832 while (isdigit(stabstr[cnt+i])) i++;
833 char *hi = (char *)malloc(sizeof(char)*(i+1));
834 if(!strncpy(hi, &(stabstr[cnt]), i))
835 /* Error copying upper range */
843 int size = atol(low);
846 BPatch_type *newType = new BPatch_type( name, ID, typdescr, size);
848 mod->moduleTypes->addType(newType);
853 BPatch_type *newType = new BPatch_type( name, ID, typdescr, low, hi);
855 mod->moduleTypes->addType(newType);
863 if( stabstr[cnt] == ';')
866 fprintf(stderr, "ERROR: More to parse in type-r- %s\n", &(stabstr[cnt]));
869 return(&(stabstr[cnt]));
874 // parse range type of the form:
876 // <rangeType> = r<typeNum>;<low>;<high>;
878 static char *parseRangeType(BPatch_module *mod,char *name,int ID, char *stabstr)
884 assert(stabstr[0] == 'r');
887 BPatch_dataClass typdescr = BPatchSymTypeRange;
889 // range index type - not used
890 (void) parseSymDesc(stabstr, cnt);
892 // printf("\tSymbol Descriptor: %c and Value: %d\n",tmpchar, symdescID);
894 cnt++; /* Discarding the ';' */
895 if (stabstr[cnt] == '-' ) cnt++;
897 /* Getting type range or size */
899 while (isdigit(stabstr[cnt+i])) i++;
901 char *temp = (char *)malloc(sizeof(char)*(i+1));
902 if(!strncpy(temp, &(stabstr[cnt]), i))
903 /* Error copying size/range*/
913 cnt = cnt + i + 1; /* Discard other Semicolon */
915 if((stabstr[cnt]) == '-')
916 i++; /* discard '-' for (long) unsigned int */
918 while(isdigit(stabstr[cnt+i])){
921 char *hi = (char *)malloc(sizeof(char)*(i+1));
922 if(!strncpy(hi, &(stabstr[cnt]), i))
923 /* Error copying upper range */
926 // printf("\tLower limit: %s and Upper limit: %s\n", low, hi);
928 BPatch_type *newType = new BPatch_type( name, ID, typdescr, low, hi);
930 mod->moduleTypes->addType(newType);
940 cnt = cnt + i + 1; /* Discard other Semicolon */
942 while(isdigit(stabstr[cnt+i])){
945 temp = (char *)malloc(sizeof(char)*(i+1));
946 if(!strncpy(temp, &(stabstr[cnt]), i))
947 /* Error copying Zero */
954 // printf("\tSize of Type : %d bytes\n",size);
956 BPatch_type *newType = new BPatch_type( name, ID, typdescr, size);
958 mod->moduleTypes->addType(newType);
960 // printf("Type RANGE: ERROR!!\n");
964 if( stabstr[cnt] == ';')
967 fprintf(stderr, "ERROR: More to parse in type-r- %s\n", &(stabstr[cnt]));
970 return(&(stabstr[cnt]));
976 // <attrType> = @s<int>;<int>
977 // <attrType> = @s<int>;(<int>,<int>)
978 // <attrType> = @s<int>;r(<int>,<int>);<int>;<int>;
980 static void parseAttrType(BPatch_module *mod, char *name,
981 int ID, char *stabstr, int &cnt)
983 bool includesRange = false;
985 // format @s(size in bits); negative type number;
986 BPatch_dataClass typdescr = BPatch_dataTypeAttrib;
988 assert(stabstr[cnt] == '@');
989 cnt++; /* skip the @ */
991 if (stabstr[cnt] == 's') {
994 int size = parseSymDesc(stabstr, cnt);
997 if (stabstr[cnt] == 'r') {
998 // include range at end
1003 int type = parseSymDesc(stabstr, cnt);
1004 // skip ';' end of stab record ??? (at least for bool)
1007 if (includesRange) {
1008 if (stabstr[cnt] == '-' ) cnt++;
1009 while (isdigit(stabstr[cnt])) cnt++;
1014 if (stabstr[cnt] == '-' ) cnt++;
1015 while (isdigit(stabstr[cnt])) cnt++;
1021 // Create a new B_type that points to a builtInTypes
1022 BPatch_type *ptrType =BPatch::bpatch->builtInTypes->findBuiltInType(type);
1024 if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
1026 BPatch_type *newType = new BPatch_type(name, ID, typdescr, size/8, ptrType);
1028 // Add type to collection
1029 if(newType) mod->moduleTypes->addType(newType);
1031 printf(" Can't Allocate new type ");
1036 printf("More Type Attribute to Parse: %s ID %d : %s\n", name,
1037 ID, &(stabstr[cnt]));
1038 printf("got type = %d\n", type);
1039 printf("full string = %s\n", stabstr);
1042 //printf(" Unable to parse Type Attribute: %s ID %d : %s\n",
1043 // name,ID, &(stabstr[cnt]));
1048 // <refType> = &<typeUse>
1050 static char *parseRefType(BPatch_module *mod, char *name,
1051 int ID, char *stabstr, int &cnt)
1053 /* reference to another type */
1054 assert(stabstr[cnt] == '&');
1057 int refID = parseTypeUse(mod, stabstr, cnt, name);
1059 // Create a new B_type that points to a structure
1060 BPatch_type *ptrType = mod->moduleTypes->findType(refID);
1061 if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
1063 BPatch_type *newType = new BPatch_type(name, ID, BPatch_dataPointer, ptrType);
1064 // Add to typeCollection
1066 mod->moduleTypes->addType(newType);
1068 printf(" Can't Allocate new type ");
1072 return(&(stabstr[cnt]));
1076 // parse a list of fields.
1077 // Format is <fieldName>:<type-desc>;offset;size;
1079 static char *parseFieldList(BPatch_module *mod, BPatch_type *newType,
1087 BPatch_visibility _vis = BPatch_visUnknown;
1088 BPatch_dataClass typedescr;
1091 #ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
1092 fprintf(stderr, "%s[%d]: inside parseFieldList\n", __FILE__, __LINE__);
1096 if (stabstr[cnt] == '!') {
1097 //Inheritance definition, Add base class field list to the current one
1098 //according to visibility rules.
1102 //Get # of base classes
1103 int baseClNum = atoi(getIdentifier(stabstr, cnt));
1106 //Skip information for each base class
1107 for(int i=0; i<baseClNum; ++i) {
1108 //Skip virtual inheritance flag, base visibility flag and base offset
1109 getIdentifier(stabstr, cnt);
1112 //Find base class type identifier
1113 int baseID = parseSymDesc(stabstr, cnt);
1118 BPatch_type *baseCl = mod->moduleTypes->findType(baseID);
1119 if (!baseCl || (baseCl->getDataClass() != BPatch_dataStructure) )
1122 //Get field descriptions of the base type
1123 BPatch_Vector<BPatch_field *> *baseClFields = baseCl->getComponents();
1124 for(unsigned int fieldNum=0; fieldNum < baseClFields->size(); fieldNum++) {
1125 BPatch_field *field = (*baseClFields)[fieldNum];
1127 if (field->getVisibility() == BPatch_private)
1128 continue; //Can not add this member
1130 newType->addField(field->getName(),
1131 field->getTypeDesc(),
1134 field->getVisibility());
1139 while (stabstr[cnt] && (stabstr[cnt] != ';')) {
1140 typedescr = BPatch_dataScalar;
1142 if (stabstr[cnt] == '~') {
1143 //End of virtual class
1144 while(stabstr[cnt] != ';') cnt++;
1145 break; //End of class is reached
1148 compname = getIdentifier(stabstr, cnt);
1150 if (strlen(compname) == 0) {
1151 //Something wrong! Most probably unhandled C++ type
1152 //Skip the rest of the structure
1153 while(stabstr[cnt]) cnt++;
1154 return(&stabstr[cnt]);
1159 if ((stabstr[cnt]) == ':') {
1161 typedescr = BPatch_dataMethod;
1165 if ((stabstr[cnt]) == '/') { // visibility C++
1166 cnt++; /* get '/' */
1167 switch (stabstr[cnt]) {
1169 _vis = BPatch_private;
1172 _vis = BPatch_protected;
1175 _vis = BPatch_public;
1178 _vis = BPatch_optimized;
1181 _vis = BPatch_visUnknown;
1183 cnt++; // get visibility value
1186 // should be a typeDescriptor
1187 comptype = parseTypeUse(mod, stabstr, cnt, "");
1189 if (stabstr[cnt] == ':') {
1190 cnt++; //Discard ':'
1194 if (typedescr == BPatch_dataMethod) {
1196 //Mangling of arguments
1197 while(stabstr[cnt] != ';') cnt++;
1200 cnt++; //Skip visibility
1201 cnt++; //Skip method modifier
1202 if (stabstr[cnt] == '*') {
1203 //Virtual fcn definition
1205 while(stabstr[cnt] != ';') cnt++; //Skip vtable index
1207 while(stabstr[cnt] != ';') cnt++; //Skip type number to
1209 while(stabstr[cnt] == ';') cnt++; //Skip all ';'
1211 else if ( (stabstr[cnt] == '.') ||
1212 (stabstr[cnt] == '?') )
1213 cnt++; //Skip '.' or '?'
1215 if (isSymId(stabstr[cnt])) {
1216 //Still more to process, but what is this?
1217 //It seems, it is another fcn definition
1218 parseTypeUse(mod, stabstr, cnt, "");
1219 if (stabstr[cnt] == ':')
1220 cnt++; //Discard ':'
1223 if (stabstr[cnt] == '~')
1224 cnt--; //Get back to ';'
1225 else if (stabstr[cnt] == ';') {
1226 //Skip all ';' except last one or two
1227 while(stabstr[cnt] == ';') cnt++;
1228 if (!stabstr[cnt] || (stabstr[cnt] == ',') )
1229 cnt--; //There must be two ';'
1233 //Something wrong! Skip entire stab record and exit
1234 while(stabstr[cnt]) cnt++;
1235 return (&stabstr[cnt]);
1244 char *varName = getIdentifier(stabstr, cnt);
1246 //Don't know what to do!
1249 else if (stabstr[cnt] == ',') {
1250 assert(stabstr[cnt] == ',');
1252 beg_offset = parseSymDesc(stabstr, cnt);
1254 if (stabstr[cnt] == ',') {
1256 size = parseSymDesc(stabstr, cnt);
1262 #ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
1263 fprintf(stderr, "%s[%d]: asserting last char of stabstr == ';': stabstr = %s\n",
1264 __FILE__, __LINE__, stabstr);
1268 #ifndef IBM_BPATCH_COMPAT
1269 assert(stabstr[cnt] == ';');
1270 cnt++; // skip ';' at end of field
1272 if (stabstr[cnt] == ';') // jaw 03/15/02-- major kludge here for DPCL compat
1273 cnt++; // needs further examination
1275 // printf("\tType: %d, Starting Offset: %d (bits), Size: %d (bits)\n", comptype, beg_offset, size);
1276 // Add struct field to type
1277 BPatch_type *fieldType = mod->moduleTypes->findType(comptype);
1278 if (fieldType == NULL) {
1279 //C++ compilers may add extra fields whose types might not available.
1280 //Assign void type to these kind of fields. --Mehmet
1281 fieldType = mod->moduleTypes->findType("void");
1283 if (_vis == BPatch_visUnknown) {
1284 newType->addField(compname, typedescr, fieldType,
1287 newType->addField(compname, typedescr, fieldType,
1288 beg_offset, size, _vis);
1289 //printf("Adding Component with VISIBILITY STRUCT\n");
1293 // should end with a ';'
1294 if (stabstr[cnt] == ';') {
1295 return &stabstr[cnt+1];
1296 } else if (stabstr[cnt] == '\0') {
1297 return &stabstr[cnt];
1299 printf("invalid stab record: %s\n", &stabstr[cnt]);
1305 // This function takes a <typeDef> and parses it
1307 // <typeDef> = <symDesc> |
1309 // *<typeUse> | Pointer to a type
1311 // f<typeUse> | function type
1312 // R<int>,<int> | Real type
1313 // b[u|s][c|]<int>;<int>;<int> | Builtin
1318 // k<typeDef> | SunPro constant
1319 // B<typeDef> | SunPro volatile
1320 // M<symDesc>;<int>| Fortran CHARACTER array
1321 // s<int><fields> | Structure <int> is size
1322 // u<int><fields> | Union <int> is size
1325 // <enumType> = <ident>:<int> | <ident>:<int>,<enumType>
1327 // It adds the typeDef to the type definition with the name name, and id ID.
1329 static char *parseTypeDef(BPatch_module *mod, char *stabstr, char *name, int ID)
1332 BPatch_type * newType = NULL;
1333 BPatch_type * ptrType = NULL;
1336 char * compsymdesc=NULL;
1338 BPatch_dataClass typdescr;
1345 cnt = i = j = k = 0;
1347 #ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
1348 fprintf(stderr, "%s[%d]: inside parseTypeDef, stabstr = %s\n", __FILE__, __LINE__,
1349 (stabstr == NULL) ? "NULL" : stabstr);
1353 assert (stabstr[0] != '=');
1355 // fprintf(stderr, "parsing %s\n", stabstr);
1356 if (isSymId(stabstr[0])) {
1357 typdescr = BPatch_dataScalar;
1358 type = parseSymDesc(stabstr, cnt);
1361 newType = new BPatch_type( name, ID, typdescr, type);
1362 if (newType) mod->moduleTypes->addType(newType);
1364 printf(" Can't Allocate newType ");
1367 } else if (stabstr[cnt] == '=') {
1368 // XXX - in the new type t(0,1)=(0,2)=s... is possible
1369 // skip the second id for now -- jkh 3/21/99
1370 stabstr = parseTypeDef(mod, &(stabstr[cnt+i+1]), name, type);
1372 BPatch_type *oldType;
1374 oldType = mod->moduleTypes->findType(type);
1375 if(!oldType) oldType = BPatch::bpatch->type_Untyped;
1376 newType = new BPatch_type( name, ID, typdescr, oldType);
1377 if (newType) mod->moduleTypes->addType(newType);
1379 BPatch_type *oldType;
1381 oldType = mod->moduleTypes->findType(type);
1382 newType = new BPatch_type( name, ID, typdescr, oldType);
1383 if(newType) mod->moduleTypes->addType(newType);
1385 printf(" Can't Allocate newType ");
1390 switch (stabstr[0]) {
1391 case 'x': //cross reference
1392 parseCrossRef(mod->moduleTypes, name, ID, stabstr, cnt);
1396 typdescr = BPatch_dataPointer;
1397 /* pointer to another type */
1399 ptrID = parseTypeUse(mod, stabstr, cnt, NULL);
1401 // Create a new B_type that points to a structure
1402 ptrType = mod->moduleTypes->findType(ptrID);
1403 if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
1405 newType = new BPatch_type(NULL, ID, BPatch_dataPointer, ptrType);
1406 // Add to typeCollection
1407 if(newType) mod->moduleTypes->addType(newType);
1409 printf(" Can't Allocate new type ");
1413 return(&(stabstr[cnt]));
1417 (void) parseArrayDef(mod, name, ID, stabstr, cnt);
1418 return (&stabstr[cnt]);
1423 typdescr = BPatch_dataFunction;
1425 cnt++; /* skip the f */
1426 type = parseTypeUse(mod, stabstr, cnt, name);
1434 int baseType = parseSymDesc(stabstr, cnt);
1435 if (baseType != -2 || (stabstr[cnt] != ';')) {
1436 printf("unexpected non character array %s\n", stabstr);
1439 int size = parseSymDesc(stabstr, cnt);
1441 ptrType = mod->moduleTypes->findType(baseType);
1442 newType = new BPatch_type(name, ID, BPatch_dataArray, ptrType,
1444 mod->moduleTypes->addType(newType);
1450 // Define a floating point type - R fp-type; bytes;
1452 (void) parseSymDesc(stabstr, cnt);
1455 int bytes = parseSymDesc(stabstr, cnt);
1457 newType = new BPatch_type(name, ID, BPatch_dataBuilt_inType, bytes);
1458 mod->moduleTypes->addType(newType);
1460 if (stabstr[cnt] == ';') cnt++; // skip the final ';'
1466 // builtin type b - signed char-flag width; offset; nbits
1467 typdescr = BPatch_dataBuilt_inType;
1468 int limit = strlen(&stabstr[cnt]);
1471 while (stabstr[cnt+i] != ';' && (i < limit)) i++;
1472 if (i >= limit) return(&(stabstr[cnt]));
1474 i++; // skip the ';'
1477 while (stabstr[cnt+i] != ';' && (i < limit)) i++;
1478 if (i >= limit) return(&(stabstr[cnt]));
1482 int nbits = parseSymDesc(stabstr, cnt);
1484 if (stabstr[cnt]) cnt++; // skip the final ';'
1486 newType = new BPatch_type(name, ID, BPatch_dataBuilt_inType,
1489 mod->moduleTypes->addType(newType);
1491 return &stabstr[cnt];
1495 case 'r': // range type
1496 return parseRangeType(mod, name, ID, stabstr);
1499 case 'e': // Enumerated type
1500 typdescr = BPatch_dataEnumerated;
1501 cnt++; /* skip the 'e' */
1503 // Create new Enum type
1504 newType = new BPatch_type(name, ID, typdescr);
1505 // Add type to collection
1506 mod->moduleTypes->addType(newType);
1508 while (stabstr[cnt]) {
1509 /* Get enum component value */
1510 compsymdesc = getIdentifier(stabstr, cnt);
1511 cnt++; /* skip colon */
1513 #ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
1514 fprintf(stderr, "%s[%d]: before parseSymDesc -- enumerated type \n",
1515 __FILE__, __LINE__);
1518 value = parseSymDesc(stabstr, cnt);
1520 // add enum field to type
1521 newType->addField(compsymdesc, BPatch_dataScalar, value);
1525 temp = compsymdesc = NULL;
1527 cnt++; /* skip trailing comma */
1528 if ((stabstr[cnt]) == ';') cnt++; /* End of enum stab record */
1532 case '@': // type attribute, defines size and type (negative num)
1533 parseAttrType(mod, name, ID, stabstr, cnt);
1536 case '&': //XXX- Need to complete, may be more to parse jdd 4/22/99
1537 return parseRefType(mod, name, ID, stabstr, cnt);
1540 case 'k': // Sun constant type s<typeDef> - parse as <typeDef>
1541 return parseTypeDef(mod, &stabstr[cnt+1], name, ID);
1544 case 'V': // AIX colatile ? type V<typeDef> - parse as <typeDef>
1545 case 'B': // Sun volatile type B<typeDef> - parse as <typeDef>
1546 return parseTypeDef(mod, &stabstr[cnt+1], name, ID);
1551 /* Type descriptor */
1552 if (stabstr[cnt] == 's') {
1553 typdescr = BPatch_dataStructure;
1555 typdescr = BPatch_dataUnion;
1558 cnt++; // skip to size
1559 structsize = parseSymDesc(stabstr, cnt);
1562 newType = new BPatch_type(name, ID, typdescr, structsize);
1563 //add to type collection
1564 mod->moduleTypes->addType(newType);
1565 #ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
1566 fprintf(stderr, "%s[%d]: before parseFieldList -- strlen(&stabstr[%d]) =%d \n",
1567 __FILE__, __LINE__, cnt, strlen(&stabstr[cnt]));
1570 return parseFieldList(mod, newType, &stabstr[cnt]);
1574 case 'Z': // What is this ??? - jkh 10/14/99 (xlc compiler uses it)
1575 return (&stabstr[1]);
1579 //Class method definition
1581 if (stabstr[cnt] == '#') {
1584 parseTypeUse(mod, stabstr, cnt, name);
1588 //Skip class type, return typ and arg types
1589 parseTypeUse(mod, stabstr, cnt, name);
1590 if (stabstr[cnt] == ',')
1592 else if (stabstr[cnt] == ';')
1598 return(&(stabstr[cnt]));
1602 fprintf(stderr, "ERROR: Unrecognized str = %s\n", &stabstr[cnt]);
1608 return(&(stabstr[cnt]));
1609 } /* end of parseTypeDef*/
1612 // parseConstantUse - parse a constant (used by Fortran PARAMETERS)
1614 // <constantUse> = =i<int> |
1618 static BPatch_type *parseConstantUse(BPatch_module *mod, char *stabstr, int &cnt)
1625 if (stabstr[cnt] == 'i') {
1626 ret = mod->moduleTypes->findType("integer*4");
1627 } else if (stabstr[cnt] == 'r') {
1628 ret = mod->moduleTypes->findType("double");
1630 printf("unknown constant type %s\n", &stabstr[cnt]);
1634 cnt = strlen(stabstr);