2 * See the dyninst/COPYRIGHT file for copyright information.
4 * We provide the Paradyn Tools (below described as "Paradyn")
5 * on an AS IS basis, and do not warrant its validity or performance.
6 * We reserve the right to update, modify, or discontinue this
7 * software at any time. We shall have no obligation to supply such
8 * updates or modifications or any other form of support to you.
10 * By your use of Paradyn, you understand and agree that we (or any
11 * other person or entity with proprietary rights in Paradyn) are
12 * under no obligation to provide either maintenance services,
13 * update services, notices of latent defects, or correction of
14 * defects for Paradyn.
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 // from libiberty's demangle.h
34 #define DMGL_PARAMS (1 << 0)
35 #define DMGL_ANSI (1 << 1)
36 #define DMGL_VERBOSE (1 << 3)
39 #include "Symtab.h" // For looking up compiler type
44 #include "Collections.h"
45 #include "annotations.h"
46 #include "common/h/headers.h"
51 using namespace Dyninst;
52 using namespace Dyninst::SymtabAPI;
59 extern std::string symt_current_func_name;
60 extern std::string symt_current_mangled_func_name;
61 extern Function *symt_current_func;
64 std::string parseStabString(Module *mod, int linenum, char *stabstr,
65 int framePtr, typeCommon *commonBlock = NULL);
69 // Forward references for parsing routines
70 static int parseSymDesc(char *stabstr, int &cnt);
71 static Type *parseConstantUse(Module *, char *stabstr, int &cnt);
72 static char *parseTypeDef(Module *, char *stabstr,
73 const char *name, int ID, unsigned int sizeHint = 0);
74 static int parseTypeUse(Module*, char *&stabstr, int &cnt,
76 static inline bool isSymId(char ch);
77 static std::string getIdentifier(char *stabstr, int &cnt, bool stopOnSpace=false);
79 static std::string currentRawSymbolName;
81 std::string convertCharToString(const char *ptr){
89 // Start of code to parse Stab information.
90 // The structure of this code is a recursive decent parser that parses
91 // information in stab records and builds up the corresponding BPatch_types.
93 // Each non-terminal in the grammer has a function of the form parse<NT>.
95 // The grammar for a non-terminal appears in the comments just before
96 // the non-terminal parsing function
99 void vectorNameMatchKLUDGE(Module *mod, char *demangled_sym, std::vector<Function *> &bpfv, std::vector<int> &matches)
101 // iterate through all matches and demangle names with extra parameters, compare
102 for (unsigned int i = 0; i < bpfv.size(); ++i) {
103 std::string l_mangled;
104 std::vector<Symbol *> syms;
105 bpfv[i]->getSymbols(syms);
107 l_mangled = syms[0]->getMangledName();
109 char * l_demangled_raw = P_cplus_demangle(l_mangled.c_str(), mod->exec()->isNativeCompiler());
110 if( l_demangled_raw == NULL ) {
111 l_demangled_raw = strdup(l_mangled.c_str());
114 if (!strcmp(l_demangled_raw, demangled_sym)) {
115 matches.push_back(i);
117 free(l_demangled_raw);
119 } /* end iteration over function vector */
122 Function *mangledNameMatchKLUDGE(const char *pretty, const char *mangled,
126 std::vector<Function *> bpfv;
127 if (!mod->exec()->findFunctionsByName(bpfv, pretty)) {
128 //cerr << __FILE__ << __LINE__ << ": KLUDGE Cannot find " << pretty << endl;
129 return NULL; // no pretty name hits, expecting multiple
132 //cerr << __FILE__ << __LINE__ << ": mangledNameMatchKLUDGE: language = "
133 //<< mod->getLanguageStr() << endl;
135 if (lang_Fortran_with_pretty_debug == mod->language()) {
136 // debug function symbols are presented in "demangled" style.
137 if (bpfv.size() == 1)
140 cerr << __FILE__ << __LINE__ << ": FIXME!" << endl;
145 // demangle name with extra parameters
146 char * demangled_sym = P_cplus_demangle( mangled, mod->exec()->isNativeCompiler(), true );
147 if( demangled_sym == NULL ) {
148 demangled_sym = strdup( mangled );
149 assert( demangled_sym != NULL );
152 std::vector<int> matches;
154 vectorNameMatchKLUDGE(mod, demangled_sym, bpfv, matches);
156 Function *ret = NULL;
158 if (matches.size() == 1) {ret = bpfv[matches[0]]; goto clean_up;}
159 if (matches.size() > 1) goto clean_up;
161 // check in the uninstrumentable pile
165 vectorNameMatchKLUDGE(mod, demangled_sym, bpfv, matches);
166 if (matches.size() == 1) {ret = bpfv[matches[0]]; goto clean_up;}
167 if (matches.size() > 1) goto clean_up;
170 free( demangled_sym );
174 // This function takes the stab stabstring and parses it to create a new
175 // type or variable object. This function only defines the type/variable
178 // <stabString> = <ident>:<symDesc> |
179 // <ident>:c<constantUse> |
180 // <ident>:f<symDesc> |
181 // <ident>:f<syymDesc>,<ident>,<ident> |
182 // <ident>:F<typeUse><paramList> |
183 // <ident>:G<typeUse> |
185 // <ident>:S<typeUse> |
186 // <ident>:[pPr]<typeUse> |
187 // <ident>::T<typeUse> |
188 // <ident>:t<typeUse> |
189 // <ident>:T<typeUse> |
190 // <ident>:v<typeUse> |
191 // <ident>:V<symDesc> |
194 // <paramList> = | <typeUse>;<paramList>
197 std::string Dyninst::SymtabAPI::parseStabString(Module *mod, int linenum, char *stabstr,
198 int framePtr, typeCommon *commonBlock)
200 typeCollection *tc = typeCollection::getModTypeCollection(mod);
204 int funcReturnID = 0;
206 Type * ptrType = NULL;
207 Type * newType = NULL; // For new types to add to the collection
208 localVar *locVar = NULL;
211 types_printf("parseStabString, mod %p/%s, linenum %d, stabstr %s\n",
213 (mod != NULL) ? mod->fileName().c_str() : "NULL",
217 std::string fName = mod->fileName();
219 /* get type or variable name */
220 std::string mangledname = getIdentifier( stabstr, cnt );
222 currentRawSymbolName = mangledname;
223 char * demangled = P_cplus_demangle( mangledname.c_str(), mod->exec()->isNativeCompiler() );
226 if ( demangled == NULL )
235 if ( name[0] != '\0' && stabstr[cnt] != ':' )
237 types_printf("\t returning name %s\n", name.c_str());
241 if (stabstr[cnt] == ':')
247 if (isSymId(stabstr[cnt]))
249 /* instance of a predefined type */
251 ID = parseSymDesc(stabstr, cnt);
253 if (stabstr[cnt] == '=')
255 /* More Stuff to parse, call parseTypeDef */
257 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name.c_str(), ID);
259 ptrType = tc->findOrCreateType(ID);
260 if (!symt_current_func)
262 // XXX-may want to use N_LBRAC and N_RBRAC to set function scope
264 // Still need to add to local variable list if in a function
266 std::string modName = mod->fileName();
267 //bperr("%s[%d] Can't find function %s in module %s\n", __FILE__, __LINE__,
268 // symt_current_mangled_func_name.c_str(), modName);
269 //bperr("Unable to add %s to local variable list in %s\n",
270 // name.c_str(), symt_current_func_name.c_str());
274 locVar = new localVar(name, ptrType, fName, linenum, symt_current_func);
275 VariableLocation loc;
276 loc.stClass = storageRegOffset;
277 loc.refClass = storageNoRef;
278 loc.frameOffset = framePtr;
279 locVar->addLocation(loc);
281 //bperr("adding local var with missing type %s, type = %d\n",
285 localVarCollection *lvs = NULL;
287 if (!symt_current_func->getAnnotation(lvs, FunctionLocalVariablesAnno))
289 lvs = new localVarCollection();
290 if (!symt_current_func->addAnnotation(lvs, FunctionLocalVariablesAnno))
292 fprintf(stderr, "%s[%d]: failed to add annotation here\n", FILE__, __LINE__);
298 fprintf(stderr, "%s[%d]: failed to get annotation here\n", FILE__, __LINE__);
301 lvs->addLocalVar(locVar);
304 else if (symt_current_func)
306 // Try to find the BPatch_Function
307 ptrType = tc->findOrCreateType( ID);
309 locVar = new localVar(name, ptrType, fName, linenum, symt_current_func);
310 VariableLocation loc;
311 loc.stClass = storageRegOffset;
312 loc.refClass = storageNoRef;
313 loc.frameOffset = framePtr;
314 locVar->addLocation(loc);
318 ////bperr("adding local var with missing type %s, type = %d\n",
322 if (!symt_current_func->addLocalVar(locVar))
324 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
329 else if (stabstr[cnt])
331 std::vector<Function *> bpfv;
333 switch (stabstr[cnt]) {
334 case 'f': /*Local Function*/
336 std::string scopeName;
337 std::string lfuncName;
340 symt_current_func_name = name;
341 symt_current_mangled_func_name = mangledname;
343 funcReturnID = parseTypeUse(mod, stabstr, cnt, name.c_str());
345 if (stabstr[cnt]==',')
347 cnt++; /*skip the comma*/
349 /* Local Function Name */
350 lfuncName = getIdentifier(stabstr, cnt);
352 assert(stabstr[cnt] == ',');
353 cnt++; /*skip the comma*/
355 /* Scope Name of Local Function */
356 scopeName = getIdentifier(stabstr, cnt);
360 //bperr("Extra: %s\n", &stabstr[cnt]);
364 if (!scopeName.length())
366 // Not an embeded function
368 ptrType = tc->findOrCreateType(funcReturnID);
370 The shared_ptr type_Untyped is static, so this
371 otherwise unsafe operation is safe.
373 if ( !ptrType) ptrType = Symtab::type_Untyped().get();
375 if (!(mod->exec()->findFunctionsByName(bpfv, name)))
377 //showInfoCallback(string("missing local function ") +
379 // It's very possible that we might not find a function
380 // that's a weak reference, and defined in multiple places
381 // as we only store an object from the last definition
383 // 12/08 - not sure this is necessary anymore
384 // due to the Function abstraction
391 // warn if we find more than one function with current_func_name
393 sprintf(msg, "%s[%d]: found %d functions with name %s, using the first",
394 __FILE__, __LINE__, (int)bpfv.size(), name.c_str());
395 // BPatch::bpatch->reportError(BPatchWarning, 0, msg);
398 else if (!bpfv.size())
400 //bperr("%s[%d]: SERIOUS: found 0 functions with name %s",
401 // __FILE__, __LINE__, name.c_str());
407 fp->setReturnType(ptrType);
412 //bperr("%s is an embedded function in %s\n",name.c_str(), scopeName.c_str());
415 symt_current_func = fp;
416 // skip to end - SunPro Compilers output extra info here - jkh 6/9/3
417 cnt = strlen(stabstr);
422 case 'F':/* Global Function */
424 cnt++; /*skipping 'F' */
426 funcReturnID = parseTypeUse(mod, stabstr, cnt, name.c_str());
428 symt_current_func_name = name;
429 symt_current_mangled_func_name = mangledname;
432 // For SunPro compilers there may be a parameter list after
436 while (stabstr[cnt] == ';')
439 (void) parseTypeUse(mod, stabstr, cnt, "");
442 // skip to end - SunPro Compilers output extra info here - jkh 6/9/3
443 cnt = strlen(stabstr);
445 ptrType = tc->findOrCreateType(funcReturnID);
446 if (!ptrType) ptrType = Symtab::type_Untyped().get();
448 std::vector<Function *>fpv;
449 if (!mod->exec()->findFunctionsByName(fpv, symt_current_mangled_func_name))
450 //if (!mod->findSymbol(fpv, symt_current_mangled_func_name, Symbol::ST_FUNCTION, true))
452 std::string modName = mod->fileName();
454 if (NULL == (fp = mangledNameMatchKLUDGE(symt_current_func_name.c_str(),
455 symt_current_mangled_func_name.c_str(), mod)))
457 //bpwarn("%s L%d - Cannot find global function with mangled name '%s' or pretty name '%s' with return type '%s' in module '%s', possibly extern\n",
458 // __FILE__, __LINE__,
459 // symt_current_mangled_func_name.c_str(), current_func_name.c_str(),
460 // ((ptrType->getMangledName() == NULL) ? "" : ptrType->getMangledName()),
463 //strncpy(prefix, current_mangled_func_name, 4);
465 // mod->dumpMangled(prefix);
471 fp->setReturnType(ptrType);
472 symt_current_func = fp;
477 case 'U':/* Class Declaration - for Sun Compilers - jkh 6/6/03 */
478 case 'E':/* Extern'd Global ??? - undocumented type for Sun Compilers - jkh 6/6/03 */
479 case 'G':/* Global Varaible */
480 cnt++; /* skip the 'G' */
482 /* Get variable type number */
483 symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
486 BPtype = tc->findOrCreateType(symdescID);
490 std::vector<Variable *> ret;
491 bool result = mod->findVariablesByName(ret, name);
493 // Might be in a different module...
494 if (mod->exec()->getDefaultModule()->findVariablesByName(ret, name))
495 toUse = mod->exec()->getDefaultModule();
497 for (unsigned i=0; i<ret.size(); i++) {
498 ret[i]->setType(BPtype);
501 typeCollection *tc_to_use = typeCollection::getModTypeCollection(toUse);
502 tc_to_use->addGlobalVariable(name, BPtype);
507 case 'P': // function parameter passed in a register (GNU/Solaris)
508 case 'R': // function parameter passed in a register (AIX style)
509 case 'v': // Fortran Local Variable
510 case 'X': // Fortran function return Variable (e.g. function name)
513 // Function Parameter
514 cnt++; /* skip the 'p' */
516 /* Get variable type number */
517 symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
519 if (stabstr[cnt] == ';')
521 // parameter type information, not used for now
522 cnt = strlen(stabstr);
524 // else if (stabstr[cnt])
526 //bperr( "\tMore to parse func param %s\n", &stabstr[cnt]);
527 //bperr( "\tFull String: %s\n", stabstr);
530 ptrType = tc->findOrCreateType(symdescID);
531 if (!ptrType) ptrType = Symtab::type_Untyped().get();
535 param = new localVar(name, ptrType, fName, linenum, symt_current_func);
536 VariableLocation loc;
537 loc.stClass = storageRegOffset;
538 loc.refClass = storageNoRef;
539 loc.frameOffset = framePtr;
540 param->addLocation(loc);
542 if (symt_current_func)
544 if (!symt_current_func->addParam(param))
546 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
553 case 'c': /* constant */
555 cnt++; /*move past the 'c' */
556 if (symt_current_mangled_func_name.length())
558 std::vector<Function *>fpv;
559 if (mod->exec()->findFunctionsByName(fpv, symt_current_mangled_func_name))
561 // found function, add parameter
563 symt_current_func = fp;
568 ptrType = parseConstantUse(mod, stabstr, cnt);
570 if (!ptrType) ptrType = Symtab::type_Untyped().get();
573 var = new localVar(name, ptrType, fName, linenum, symt_current_func);
574 VariableLocation loc;
575 loc.stClass = storageRegOffset;
576 loc.refClass = storageNoRef;
578 var->addLocation(loc);
579 if (symt_current_func) {
580 if (!symt_current_func->addParam(var))
582 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
588 case 'r':/* Register Variable */
589 cnt++; /*move past the 'r'*/
590 /* get type reference */
592 symdescID = parseSymDesc(stabstr, cnt);
595 case 'S':/* Global Static Variable */
597 cnt++; /*move past the 'S'*/
599 /* get type reference */
600 symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
602 // lookup symbol and set type
605 std::string nameTrailer;
606 if (name.find(".") < name.length())
608 std::string defaultNameSpace;
609 defaultNameSpace = name.substr(0,name.find("."));
610 nameTrailer = name.substr(name.find(".")+1,name.length()-name.find(".")-1);
611 mod->setDefaultNamespacePrefix(defaultNameSpace);
618 BPtype = tc->findOrCreateType(symdescID);
622 Symtab *img = mod->exec();
623 std::vector<Symbol *>syms;
624 if (img->findSymbol(syms,
628 img->findSymbol(syms,
635 tc->addGlobalVariable(nameTrailer, BPtype);
641 //bperr("ERROR: unable to find type #%d for variable %s\n",
642 // symdescID, nameTrailer.c_str());
648 case 't': // Type Name
649 cnt++; /*move past the 't'*/
651 /* get type reference */
652 symdescID = parseSymDesc(stabstr, cnt);
655 if (stabstr[cnt] == '=')
657 /* More Stuff to parse, call parseTypeDef */
658 //char *oldstabstr = stabstr;
659 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name.c_str(), symdescID);
663 // AIX seems to append an semi at the end of these
664 if (stabstr[0] && strcmp(stabstr, ";"))
666 //bperr("\tMore to parse creating type %s\n", stabstr);
667 //bperr( "\tFull String: %s\n", oldStr);
672 //Create Type defined as a pre-exisitng type.
674 ptrType = tc->findOrCreateType(symdescID);
677 ptrType = Symtab::type_Untyped().get();
680 // We assume that IDs are unique per type. Instead of reusing the
681 // underlying base ID, use a SymtabAPI-generated ID.
683 typeTypedef *newType = new typeTypedef(ptrType, name);
687 tc->addOrUpdateType(newType);
692 case ':': // :T... - skip ":" and parse 'T'
693 if ((stabstr[cnt+1] == 't') || (stabstr[cnt+1] == 'T'))
695 // parse as a normal typedef
696 parseStabString(mod, linenum, &stabstr[cnt+1], framePtr);
701 //bperr("Unknown type seen %s\n", stabstr);
706 case 'T':/* Aggregate type tag -struct, union, enum */
707 cnt++; /*move past the 'T'*/
709 if (stabstr[cnt] == 't')
711 //C++ struct tag "T" and type def "t"
712 ////bperr("SKipping C++ Identifier t of Tt\n");
716 /* get type reference */
717 symdescID = parseSymDesc(stabstr, cnt);
720 if (stabstr[cnt] == '=')
722 /* More Stuff to parse, call parseTypeDef */
723 stabstr = parseTypeDef(mod,(&stabstr[cnt+1]),name.c_str(),symdescID);
728 //bperr( "\tMore to parse aggregate type %s\n", (&stabstr[cnt]));
729 //bperr("\tFull String: %s\n", stabstr);
735 //Create Type defined as a pre-exisitng type.
737 newType = Type::createPlaceholder(symdescID, name);
742 case 'V':/* Local Static Variable (common block vars too) */
743 cnt++; /*move past the 'V'*/
745 // //bperr("parsing 'v' type of %s\n", stabstr);
746 /* Get variable type number */
748 symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
750 // lookup symbol and set type
751 BPtype = tc->findOrCreateType(symdescID);
755 //bperr("ERROR: unable to find type #%d for variable %s\n",
756 // symdescID, name.c_str());
762 /* This variable is in a common block */
763 /* add it only if not already there, common block
764 are re-defined for each subroutine but subroutines
765 define only the member they care about
769 const std::vector<Field *> *fields;
770 fields = commonBlock->getFields();
773 for (unsigned int i=0; i < fields->size(); i++)
775 if (name == (*fields)[i]->getName())
781 int start1, start2, end1, end2;
782 start1 = (*fields)[i]->getOffset();
783 end1 = start1 + (*fields)[i]->getSize();
785 end2 = framePtr + BPtype->getSize();
786 if ( ((start2 >= start1) && (start2 < end1))
787 || ((start1 >= start2) && (start1 < end2)) )
789 /* common block aliasing detected */
790 //bpwarn("WARN: EQUIVALENCE used in %s: %s and %s\n",
791 // current_func_name.c_str(), name.c_str(), (*fields)[i]->getName());
801 commonBlock->addField(name, BPtype, framePtr);
806 // put it into the local variable scope
807 if (symt_current_func)
809 locVar = new localVar(name, BPtype, fName, linenum, symt_current_func);
810 VariableLocation loc;
811 loc.stClass = storageAddr;
812 loc.refClass = storageNoRef;
813 loc.frameOffset = framePtr;
814 locVar->addLocation(loc);
816 if (!symt_current_func->addLocalVar(locVar))
818 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
824 //bperr("Unable to add %s to local variable list in %s\n",
825 // name.c_str(),current_func_name.c_str());
830 // These are string literals, of the form
831 // name:l(type);value
832 // where type must be predefined, and value of of type type.
833 // It should be safe to ignore these.
835 cnt = strlen(stabstr);
838 case 'Y': // C++ specific stuff
839 cnt++; // Skip past the 'Y'
840 if (stabstr[cnt] == 'I')
842 /* Template instantiation */
843 cnt++; // skip past the I;
844 if (stabstr[cnt] == 'f') /* Template function */
846 while (stabstr[cnt] != '@') cnt++;
847 cnt++; // Skip past '@'
848 cnt++; // Skip past ';'
849 cnt++; // Skip past ';'
850 while (stabstr[cnt] != ':') cnt++;
851 // Create fake stab string that cuts out template garbage
852 char *dupstring = strdup(stabstr);
853 strcpy(dupstring, mangledname.c_str());
854 strcat(dupstring, stabstr+cnt);
855 parseStabString(mod, linenum, dupstring, framePtr, commonBlock);
859 cnt = strlen(stabstr);
863 //bperr( "Unknown symbol descriptor: %c\n", stabstr[cnt]);
864 //bperr( " : %s\n", stabstr);
869 return(&stabstr[cnt]);
870 } /* end of parseStabString */
874 // Is the current character a valid prefix for a symDesc non-terminal?
876 inline bool isSymId(char ch)
878 return ((ch == '(') || isdigit(ch) || (ch == '-'));
882 // parse a Symbol Descriptor ID
883 // symDesc = <int> | (<int>,<int>)
885 int parseSymDesc(char *stabstr, int &cnt)
891 bool newForm = false;
893 hid = 0; //file-number
894 // parse both an int and (int,int) format (file-number, type ID)
895 if (stabstr[cnt] == '(') {
897 while (isdigit(stabstr[cnt])) {
898 hid = hid * 10 + stabstr[cnt] - '0';
903 if (stabstr[cnt] == ',') cnt++;
907 if (stabstr[cnt] == '-') {
913 while (isdigit(stabstr[cnt])) {
914 lid = lid * 10 + stabstr[cnt] - '0';
923 id = hid * 65536 + lid;
930 // parse an identifier up to a ":" or "," or ";"
932 std::string getIdentifier( char *stabstr, int &cnt, bool stopOnSpace ) {
938 switch( stabstr[ cnt + i ] ) {
952 if ( !stopOnSpace ) {
955 } // else fall through
960 /* Handle case of '::' */
961 if ( stabstr[ cnt + i ] == ':' && stabstr[ cnt + i + 1 ] == ':' &&
962 (stabstr[ cnt + i + 2 ] == '_' || isalpha(stabstr[ cnt + i + 2 ])) ) {
966 /* If we're inside a bracket and we haven't reached
967 the end of the string, continue. */
968 if( brCnt != 0 && stabstr[ cnt + i ] != '\0' ) {
972 //bperr( "Failed to find identifier in stabstring '%s;\n", stabstr );
986 char * identifier = (char *)malloc( i + 1 );
987 assert( identifier );
989 strncpy( identifier, & stabstr[cnt], i );
990 identifier[i] = '\0';
993 std::string pd_identifier = identifier;
995 return pd_identifier;
996 } /* end getIdentifier() */
1001 // A simplified version of getIdentifier, it only cares about finding a ':'
1004 char * getFieldName( char *stabstr, int &cnt) {
1009 switch( stabstr[ cnt + i ] ) {
1018 char * identifier = (char *) malloc(i + 1);
1021 strncpy(identifier, &stabstr[cnt], i);
1022 identifier[i] = '\0';
1029 // Parse a use of a type.
1031 // <typeUse> = <symDesc> | <symDesc>=<typeDef>
1033 static int parseTypeUse(Module *mod,char *&stabstr, int &cnt,
1036 int ret = parseSymDesc(stabstr, cnt);
1038 if (stabstr[cnt] == '=') {
1039 /* More Stuff to parse, call parseTypeDef */
1040 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name, ret);
1047 // parseCrossRef - internal struct/union pointer
1049 // <crossRef> = [s|u|e]<ident>
1051 static char *parseCrossRef(typeCollection *moduleTypes,const char * /*name*/,
1052 int ID, char *stabstr, int &cnt)
1055 Type *newType = NULL;
1057 cnt++; /* skip 'x'*/
1059 if ((stabstr[cnt] == 's') || // struct
1060 (stabstr[cnt] == 'u') || // union
1061 (stabstr[cnt] == 'e')) { // enum
1062 xreftype = stabstr[cnt++];
1064 temp = getIdentifier(stabstr, cnt);
1065 cnt++; /*skip ':' */
1067 // Find type that this one points to.
1068 Type *ptrType = moduleTypes->findType(temp.c_str());
1070 // This type name hasn't been seen before. Create the
1071 // skeleton for it, and we'll update it later when we actually see
1073 if (xreftype == 'e') {
1074 newType = new typeEnum(ID, temp);
1075 newType = moduleTypes->addOrUpdateType((typeEnum *) newType);
1076 } else if (xreftype == 'u') {
1077 newType = new typeUnion(ID, temp);
1078 newType = moduleTypes->addOrUpdateType((typeEnum *) newType);
1080 newType = new typeStruct(ID, temp);
1081 newType = moduleTypes->addOrUpdateType((typeEnum *) newType);
1086 /* don't know what it is?? */
1088 temp = getIdentifier(stabstr, cnt);
1089 cnt++; /*skip ':' */
1092 return( &(stabstr[cnt]));
1096 // parse the definition of an array.
1097 // arrayDef = ar<symDesc>;<symDesc>;<symDesc>;<symDesc> |
1098 // ar<symDesc>;<symDesc>;<symDesc>;<arrayDef> |
1101 static Type *parseArrayDef(Module *mod, const char *name,
1102 int ID, char *&stabstr, int &cnt, unsigned int sizeHint)
1104 typeCollection *tc = typeCollection::getModTypeCollection(mod);
1108 Type *newType = NULL;
1109 Type *ptrType = NULL;
1110 int lowbound, hibound;
1112 // format is ar<indexType>;<lowBound>;<highBound>;<elementType>
1114 assert(stabstr[cnt] == 'a' || stabstr[cnt] == 'A');
1116 if (stabstr[cnt ++] == 'A') {
1120 elementType = parseSymDesc(stabstr, cnt);
1121 ptrType = tc->findOrCreateType(elementType);
1123 // Regular (maybe) array
1125 if (stabstr[cnt] != 'r') {
1126 //bperr("unknown array definition seen %s\n", &stabstr[cnt]);
1130 /* array with range */
1131 symdesc = &(stabstr[cnt]);
1133 cnt++; /* skip 'r' */
1135 symdescID = parseTypeUse(mod, stabstr, cnt, name);
1137 cnt++; /* skip semicolon */
1138 lowbound = parseSymDesc(stabstr, cnt);
1140 cnt++; /* skip semicolon */
1141 if (stabstr[cnt] == 'J') {
1142 /* Fortran unbounded array */
1145 } else if (stabstr[cnt] == 'T') {
1146 /* Fortran runtime bound array - Txx is the form (xx=digits)*/
1149 while (isdigit(stabstr[cnt])) cnt++;
1151 hibound = parseSymDesc(stabstr, cnt);
1154 cnt++; /* skip semicolon */
1155 elementType = parseSymDesc(stabstr, cnt);
1157 if (stabstr[cnt] == 'a')
1159 /* multi dimensional array - Fortran style */
1160 /* it has no valid id, so we give it a known duplicate */
1161 //fprintf(stderr, "%s[%d]: parseArrayDef(...'%s'...)\n", FILE__, __LINE__, stabstr);
1162 ptrType = parseArrayDef(mod, name, 0, stabstr, cnt, sizeHint);
1166 if (stabstr[cnt] == '=')
1168 /* multi dimensional array */
1170 temp = parseTypeDef(mod, &(stabstr[cnt+1]), NULL, elementType);
1171 /* parseTypeDef uses old style of returning updated stabstr,
1172 but parseArrayDef function needs to return an updated cnt.
1173 This simple hack updates cnt based on how far parseTypDef
1174 advances it. jkh 12/4/00 */
1176 if (stabstr[cnt] == ':') {
1178 ////bperr("Skipping C++ rest of array def: %s\n",name );
1179 while (stabstr[cnt] != ';') cnt++;
1182 ptrType = tc->findOrCreateType(elementType);
1186 // //bperr("Symbol Desriptor: %s Descriptor ID: %d Type: %d, Low Bound: %d, Hi Bound: %d,\n", symdesc, symdescID, elementType, lowbound, hibound);
1190 // Create new type - field in a struct or union
1191 std::string tName = convertCharToString(name);
1193 typeArray *newAType = new typeArray(ID, ptrType, lowbound, hibound, tName, sizeHint);
1194 // Add to Collection
1195 newType = tc->addOrUpdateType((typeArray *) newAType);
1200 // //bperr( "parsed array def to %d, remaining %s\n", cnt, &stabstr[cnt]);
1204 int guessSize(const char *low, const char *hi)
1209 sscanf(low, "%llo", &l);
1211 sscanf(low, "%lld", &l);
1213 sscanf(hi, "%llo", &h);
1215 sscanf(hi, "%lld", &h);
1218 if (( low[0]=='-' && l < -2147483648LL )
1219 || ( l > || ( h > 2147483647LL))
1221 else if (( l < -32768 ) || ( h > 32767 ))
1223 else if (( l < -128 ) || ( h > 127 ))
1228 if (l < 0) { // Must be signed
1229 if (l < -2147483648LL || h > 0x7fffffffLL)
1231 else if (l < 0xffff8000 || h > 0x7fff)
1233 else if (l < 0xffffff80 || h > 0x7f)
1238 if (h > 0xffffffffLL)
1240 else if (h > 0xffff)
1249 #if defined(i386_unknown_linux2_0) \
1250 || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1252 // parse range type of the form:
1254 // <rangeType> = r<typeNum>;<low>;<high>;
1256 static char *parseRangeType(Module *mod, const char *name, int ID,
1257 char *stabstr, unsigned int sizeHint = 0)
1259 int cnt, i, symdescID;
1265 assert(stabstr[0] == 'r');
1268 // range index type - not used
1269 symdescID = parseSymDesc(stabstr, cnt);
1271 typeCollection *tc = typeCollection::getModTypeCollection(mod);
1274 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
1279 baseType = tc->findType(symdescID);
1282 // //bperr("\tSymbol Descriptor: %c and Value: %d\n",tmpchar, symdescID);
1284 cnt++; /* Discarding the ';' */
1286 if (stabstr[cnt] == '-' ) {
1290 /* Getting type range or size */
1292 while (isdigit(stabstr[cnt+i])) i++;
1294 char *low = (char *)malloc(sizeof(char)*(i+1));
1295 if(!strncpy(low, &(stabstr[cnt]), i))
1296 /* Error copying size/range*/
1300 cnt = cnt + i + 1; /* Discard other Semicolon */
1302 if((stabstr[cnt]) == '-') {
1303 i++; /* discard '-' for (long) unsigned int */
1306 while (isdigit(stabstr[cnt+i])) i++;
1307 char *hi = (char *)malloc(sizeof(char)*(i+1));
1308 if(!strncpy(hi, &(stabstr[cnt]), i))
1309 /* Error copying upper range */
1317 int size = atol(low);
1320 Type *newType = new typeScalar(ID, size, name);
1322 newType = tc->addOrUpdateType((typeScalar *) newType);
1328 std::string tName = convertCharToString(name);
1331 long low_conv = strtol(low, NULL, 10);
1334 low_conv = LONG_MIN;
1338 long hi_conv = strtol(hi, NULL, 10);
1344 if (baseType == NULL)
1345 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : guessSize(low,hi),
1346 low_conv, hi_conv, tName);
1348 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : baseType->getSize(),
1349 low_conv, hi_conv, tName);
1351 tc->addOrUpdateType((typeSubrange *) newType);
1358 if( stabstr[cnt] == ';')
1361 return(&(stabstr[cnt]));
1366 // parse range type of the form:
1368 // <rangeType> = r<typeNum>;<low>;<high>;
1370 static char *parseRangeType(Module *mod, const char *name, int ID,
1371 char *stabstr, unsigned int sizeHint = 0)
1373 int cnt, i, symdescID;
1379 assert(stabstr[0] == 'r');
1383 symdescID = parseSymDesc(stabstr, cnt);
1385 typeCollection *tc = typeCollection::getModTypeCollection(mod);
1386 baseType = tc->findType(symdescID);
1388 // //bperr("\tSymbol Descriptor: %c and Value: %d\n",tmpchar, symdescID);
1390 cnt++; /* Discarding the ';' */
1392 if (stabstr[cnt] == '-' ) {
1396 /* Getting type range or size */
1397 while (isdigit(stabstr[cnt+i])) i++;
1399 char *temp = (char *)malloc(sizeof(char)*(i+1));
1400 if(!strncpy(temp, &(stabstr[cnt]), i))
1401 /* Error copying size/range*/
1407 cnt = cnt + i + 1; /* Discard other Semicolon */
1409 if((stabstr[cnt]) == '-') {
1410 i++; /* discard '-' for (long) unsigned int */
1413 while(isdigit(stabstr[cnt+i]))
1416 char *hi = (char *)malloc(sizeof(char)*(i+1));
1417 if(!strncpy(hi, &(stabstr[cnt]), i))
1418 /* Error copying upper range */
1422 std::string tname = convertCharToString(name);
1427 // //bperr("\tLower limit: %s and Upper limit: %s\n", low, hi);
1430 long low_conv = strtol(low, NULL, 10);
1433 // fprintf(stderr, "%s[%d]: error converting range limit '%s' to long: %s\n",
1434 // FILE__, __LINE__, low, strerror(errno));
1435 low_conv = LONG_MIN;
1438 if (low_conv < LONG_MIN)
1440 fprintf(stderr, "%s[%d]: signed variable saturation...\n", FILE__, __LINE__);
1441 low_conv = LONG_MIN;
1445 long hi_conv = strtol(hi, NULL, 10);
1448 //fprintf(stderr, "%s[%d]: error converting range limit '%s' to long: %s\n",
1449 // FILE__, __LINE__, hi, strerror(errno));
1453 if (hi_conv > LONG_MAX)
1455 fprintf(stderr, "%s[%d]: signed variable saturation...\n", FILE__, __LINE__);
1459 if (baseType == NULL)
1461 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : guessSize(low,hi),
1462 low_conv, hi_conv, tname);
1466 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : baseType->getSize(),
1467 low_conv, hi_conv, tname);
1469 newType = tc->addOrUpdateType((typeSubrange *) newType);
1479 // //bperr("\tSize of Type : %d bytes\n",size);
1482 newType = new typeScalar(ID, size, convertCharToString(name));
1484 newType = tc->addOrUpdateType((typeScalar *) newType);
1489 // //bperr("Type RANGE: ERROR!!\n");
1491 long low_conv = strtol(low, NULL, 10);
1494 fprintf(stderr, "%s[%d]: error converting range limit '%s' to long: %s\n",
1495 FILE__, __LINE__, low, strerror(errno));
1496 low_conv = LONG_MIN;
1500 long hi_conv = strtol(hi, NULL, 10);
1503 fprintf(stderr, "%s[%d]: error converting range limit '%s' to long: %s\n",
1504 FILE__, __LINE__, hi, strerror(errno));
1508 if (baseType == NULL)
1509 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : sizeof(long),
1510 low_conv, hi_conv, tname);
1512 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : baseType->getSize(),
1513 low_conv, hi_conv, tname);
1514 newType = tc->addOrUpdateType((typeSubrange *) newType);
1521 if( stabstr[cnt] == ';')
1524 return(&(stabstr[cnt]));
1530 // <attrType> = @s<int>;<int>
1531 // <attrType> = @s<int>;(<int>,<int>)
1532 // <attrType> = @s<int>;r(<int>,<int>);<int>;<int>;
1536 // This may in fact be much simpler than first anticipated
1537 // AIX stabs use attributes only as hints, and dbx only
1538 // understands @s (size) and @P (packed) types. We only
1539 // parse the size attribute, and should be able to get away
1540 // with simply passing the remainder to the rest of our parser
1542 static char *parseAttrType(Module *mod, const char *name,
1543 int ID, char *stabstr, int &cnt)
1545 assert(stabstr[cnt] == '@');
1546 cnt++; // skip the @
1548 if (stabstr[cnt] == 's') {
1551 int size = parseSymDesc(stabstr, cnt);
1554 char *newstr = parseTypeDef(mod, stabstr+cnt, name, ID, size);
1555 if (newstr[0] == ';')
1560 ////bperr(" Unable to parse Type Attribute: %s ID %d : %s\n",
1561 // name,ID, &(stabstr[cnt]));
1562 while (stabstr[cnt] != ';') cnt++;
1564 return parseTypeDef(mod, stabstr+cnt, name, ID);
1568 static void parseAttrType(Module *mod, const char *name,
1569 int ID, char *stabstr, int &cnt)
1571 bool includesRange = false;
1572 char *low = NULL, *high = NULL;
1574 // format @s(size in bits); negative type number;
1575 dataClass typdescr = dataTypeAttrib;
1577 assert(stabstr[cnt] == '@');
1578 cnt++; // skip the @
1580 if (stabstr[cnt] == 's') {
1583 int size = parseSymDesc(stabstr, cnt);
1586 if (stabstr[cnt] == 'r') {
1587 // include range at end
1589 includesRange = true;
1592 int type = parseSymDesc(stabstr, cnt);
1593 // skip ';' end of stab record ??? (at least for bool)
1596 if (includesRange) {
1599 // Parse out low range string.
1601 if (stabstr[cnt] == '-' ) cnt++, len++;
1602 while (isdigit(stabstr[cnt])) cnt++, len++;
1605 // Store the low range string.
1606 low = (char *)malloc(sizeof(char) * (len + 1));
1608 strncpy(low, &stabstr[cnt - (len + 1)], len);
1611 // Parse out high range string.
1613 if (stabstr[cnt] == '-' ) cnt++, len++;
1614 while (isdigit(stabstr[cnt])) cnt++, len++;
1617 // Store the high range string.
1618 high = (char *)malloc(sizeof(char) * (len + 1));
1620 strncpy(high, &stabstr[cnt - (len + 1)], len);
1624 // Create a new B_type that points to a builtInTypes
1625 Type *ptrType =BPatch::bpatch->builtInTypes->findBuiltInType(type);
1627 if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
1629 Type *newType = new Type(name, ID, typdescr, size/8, ptrType);
1631 //bperr(" Can't Allocate new type ");
1635 if (includesRange) {
1636 newType->setLow(low);
1637 newType->setHigh(high);
1642 // Add type to collection
1643 newType2 = tc->addOrUpdateType(newType);
1646 //bperr("More Type Attribute to Parse: %s ID %d : %s\n", name,
1647 ID, &(stabstr[cnt]));
1648 //bperr("got type = %d\n", type);
1649 //bperr("full string = %s\n", stabstr);
1652 ////bperr(" Unable to parse Type Attribute: %s ID %d : %s\n",
1653 // name,ID, &(stabstr[cnt]));
1658 // <refType> = &<typeUse>
1660 static char *parseRefType(Module *mod, const char *name,
1661 int ID, char *stabstr, int &cnt)
1663 /* reference to another type */
1664 assert(stabstr[cnt] == '&');
1667 int refID = parseTypeUse(mod, stabstr, cnt, name);
1669 // Create a new B_type that points to a structure
1670 typeCollection *tc = typeCollection::getModTypeCollection(mod);
1671 Type *ptrType = tc->findOrCreateType(refID);
1672 if (!ptrType) ptrType = Symtab::type_Untyped().get();
1673 std::string tName = convertCharToString(name);
1674 typeRef *newType = new typeRef(ID, ptrType, tName);
1676 // Add to typeCollection
1677 newType = tc->addOrUpdateType(newType);
1679 return(&(stabstr[cnt]));
1683 // Given a base class and a new type, add all visible fields to the new class
1685 void addBaseClassToClass(Module *mod, int baseID,
1686 fieldListType *newType, int /*offset*/)
1689 typeCollection *tc = typeCollection::getModTypeCollection(mod);
1692 fieldListType *baseCl = dynamic_cast<fieldListType *>(tc->findType(baseID));
1694 std::string modName = mod->fileName();
1695 //bpwarn( "can't find base class id %d in module %s\n", baseID, modName);
1696 baseCl = new typeStruct(baseID);
1697 fieldListType *baseCl2 = dynamic_cast<typeStruct *>(tc->addOrUpdateType( (typeStruct *)baseCl ));
1698 std::string fName = "{superclass}";
1699 newType->addField( fName, baseCl2, -1, visUnknown );
1700 baseCl->decrRefCount();
1703 std::string fName = "{superclass}";
1704 newType->addField( fName, baseCl, -1, visUnknown );
1706 //Get field descriptions of the base type
1708 const std::vector<Field *> *baseClFields = baseCl->getComponents();
1709 for (unsigned int fieldNum=0; fieldNum < baseClFields->size(); fieldNum++) {
1710 Field *field = (*baseClFields)[fieldNum];
1712 if (field->getVisibility() == visPrivate)
1713 continue; //Can not add this member
1715 newType->addField(field->getName(), field->getTypeDesc(), field->getType(), field->getOffset()+offset, field->getVisibility());
1721 // parse a list of fields.
1722 // Format is [A|B|C-M|N|O][c][G]<fieldName>:<type-desc>;offset;size;
1724 static char *parseFieldList(Module *mod, fieldListType *newType,
1725 char *stabstr, bool sunCPlusPlus)
1732 visibility_t _vis = visUnknown;
1733 dataClass typedescr;
1734 bool hasVirtuals = false;
1735 typeCollection *tc = typeCollection::getModTypeCollection(mod);
1738 if (stabstr[cnt] == '!')
1740 //Inheritance definition, Add base class field list to the current one
1741 //according to visibility rules.
1745 //Get # of base classes
1746 int baseClNum = atoi(getIdentifier(stabstr, cnt).c_str());
1749 typeStruct *newStructType = dynamic_cast<typeStruct *>(newType);
1750 //Skip information for each base class
1751 for (int i=0; i<baseClNum; ++i)
1753 //Skip virtual inheritance flag, base visibility flag and base offset
1754 getIdentifier(stabstr, cnt);
1757 //Find base class type identifier
1758 int baseID = parseSymDesc(stabstr, cnt);
1762 addBaseClassToClass(mod, baseID, newStructType, 0);
1766 while (stabstr[cnt] && (stabstr[cnt] != ';'))
1768 typedescr = dataScalar;
1770 if (stabstr[cnt] == '~')
1772 //End of virtual class
1773 while (stabstr[cnt] != ';') cnt++;
1774 break; //End of class is reached
1778 if (sunCPlusPlus) cnt += 3;
1780 if ((stabstr[cnt] == 'u') && (stabstr[cnt+1] == ':') && (!isdigit(stabstr[cnt+2])))
1785 compname = getFieldName(stabstr, cnt);
1788 if (strlen(compname) == 0) {
1789 //Something wrong! Most probably unhandled C++ type
1790 //Skip the rest of the structure
1791 while(stabstr[cnt]) cnt++;
1792 return(&stabstr[cnt]);
1797 if ((stabstr[cnt]) == ':')
1800 typedescr = dataFunction;
1804 if ((stabstr[cnt]) == '/')
1806 cnt++; /* get '/' */
1807 switch (stabstr[cnt]) {
1812 _vis = visProtected;
1820 cnt++; // get visibility value
1823 // should be a typeDescriptor
1824 comptype = parseTypeUse(mod, stabstr, cnt, "");
1826 if (stabstr[cnt] == ':')
1828 while (stabstr[cnt] == ':')
1830 cnt++; //Discard ':'
1833 std::string varName = getIdentifier(stabstr, cnt);
1835 if (typedescr == dataFunction)
1837 // Additional qualifiers for methods
1839 cnt++; //Skip visibility
1840 cnt++; //Skip method modifier
1841 if (stabstr[cnt] == '*')
1843 //Virtual fcn definition
1846 while(stabstr[cnt] != ';') cnt++; //Skip vtable index
1848 if (stabstr[cnt] != ';')
1850 parseTypeUse(mod, stabstr, cnt, ""); //Skip type number to the base class
1853 if (isSymId(stabstr[cnt]))
1855 parseTypeUse(mod, stabstr, cnt, "");
1857 } else if ( (stabstr[cnt] == '.')
1858 || (stabstr[cnt] == '?') )
1860 cnt++; //Skip '.' or '?'
1861 if (isSymId(stabstr[cnt]))
1863 parseTypeUse(mod, stabstr, cnt, "");
1868 if (stabstr[cnt] == ';')
1872 else if (stabstr[cnt] == ',')
1875 beg_offset = parseSymDesc(stabstr, cnt);
1877 if (stabstr[cnt] == ',')
1880 size = parseSymDesc(stabstr, cnt);
1886 if (stabstr[cnt] == ';') // jaw 03/15/02-- major kludge here for DPCL compat
1887 cnt++; // needs further examination
1889 // //bperr("\tType: %d, Starting Offset: %d (bits), Size: %d (bits)\n", comptype, beg_offset, size);
1890 // Add struct field to type
1892 Type *fieldType = tc->findOrCreateType( comptype );
1893 if (fieldType == NULL)
1895 //C++ compilers may add extra fields whose types might not available.
1896 //Assign void type to these kind of fields. --Mehmet
1897 fieldType = tc->findType("void");
1899 std::string fName = convertCharToString(compname);
1900 if (_vis == visUnknown)
1902 newType->addField(fName, fieldType, beg_offset);
1906 // //bperr( "Adding field '%s' to type '%s' @ 0x%x\n", compname, newType->getName(), newType );
1907 newType->addField(fName, fieldType, beg_offset, _vis);
1908 ////bperr("Adding Component with VISIBILITY STRUCT\n");
1914 stabstr[cnt] == ';' &&
1915 stabstr[cnt+1] == '~' &&
1916 stabstr[cnt+2] == '%')
1919 while (stabstr[cnt] != ';') cnt++;
1922 // should end with a ';'
1923 if (stabstr[cnt] == ';')
1925 return &stabstr[cnt+1];
1927 else if (stabstr[cnt] == '\0')
1929 return &stabstr[cnt];
1933 //bperr("invalid stab record: %s\n", &stabstr[cnt]);
1935 return NULL; // should not get here
1941 // Y<type><size><className>;<Bases>;<DataMembers>;<MemberFunctions>;<StaticDataMembers>;
1942 // <Friends>;<VirtualFunctionInfo>;<NestedClassList>;<AccessAdjustments>;
1943 // <VirtualBaseClassOffsets>;<TemplatmentMembers>;<PassMethod>;
1945 static char *parseCPlusPlusInfo(Module *mod,
1946 char *stabstr, const char *mangledName, int ID)
1948 typeCollection *tc = typeCollection::getModTypeCollection(mod);
1952 bool sunStyle = true;
1953 bool nestedType = false;
1955 fieldListType * newType = NULL, *newType2 = NULL;
1957 assert(stabstr[0] == 'Y');
1961 if (isdigit(stabstr[cnt])) {
1962 structsize = parseSymDesc(stabstr, cnt);
1966 switch(stabstr[cnt]) {
1969 typdescr = dataTypeClass;
1975 typdescr = dataStructure;
1981 typdescr = dataUnion;
1984 case 'n': // namespace - ignored
1985 cnt = strlen(stabstr);
1986 return(&(stabstr[cnt]));
1990 //bperr( "ERROR: Unrecognized C++ str = %s\n", stabstr);
1991 cnt = strlen(stabstr);
1992 return(&(stabstr[cnt]));
1996 cnt++; // skip to size
1997 if (isdigit(stabstr[cnt])) {
1998 structsize = parseSymDesc(stabstr, cnt);
2001 if (stabstr[cnt] == 'V') cnt++;
2002 if (stabstr[cnt] == '(') cnt++;
2004 if (sunStyle && (stabstr[cnt] != ';')) {
2008 // Class or Type Name
2010 while (stabstr[cnt] != ';') cnt++;
2011 len = &stabstr[cnt] - n;
2012 name = (char *) calloc(len + 1, sizeof(char));
2013 strncpy(name, n, len);
2015 name = const_cast< char * >( mangledName );
2018 std::string tName = convertCharToString(name);
2023 newType = new typeStruct(ID, tName);
2024 newType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeStruct *) newType));
2027 newType = new typeUnion(ID, tName);
2028 newType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeUnion *) newType));
2033 //add to type collection
2035 if(newType2 != newType)
2036 newType->decrRefCount();
2041 while (stabstr[cnt] != ';') {
2042 // skip visibility flag
2045 int offset = parseSymDesc(stabstr, cnt);
2047 // Find base class type identifier
2048 int baseID = parseSymDesc(stabstr, cnt);
2049 addBaseClassToClass(mod, baseID, newType2, offset);
2055 // parse dataMembers
2056 stabstr = parseFieldList(mod, newType2, &stabstr[cnt], sunStyle);
2060 // parse member functions
2062 while (stabstr[cnt] && (stabstr[cnt] != ';')) {
2063 std::string pd_funcName = getIdentifier(stabstr, cnt, true);
2064 const char *funcName = pd_funcName.c_str();
2066 funcName++; // skip ppp-code
2068 if (*funcName == '-') funcName++; // it's a pure vitual
2070 while (isdigit(*funcName)) funcName++; // skip virtual function index
2073 char *className = strdup(currentRawSymbolName.c_str());
2075 className[strlen(className)-1] = '\0'; // remove tailing "_"
2076 std::string methodName = std::string(className) + std::string(funcName) + std::string("_");
2077 char * name = P_cplus_demangle( methodName.c_str(), mod->exec()->isNativeCompiler() );
2078 if( name != NULL ) {
2079 funcName = strrchr( name, ':' );
2080 if( funcName ) { funcName++; }
2081 else { funcName = name; }
2084 // should include position for virtual methods
2085 Type *fieldType = tc->findType("void");
2087 std::string fName = convertCharToString(funcName);
2089 typeFunction *funcType = new typeFunction( ID, fieldType, fName);
2090 newType2->addField( fName, funcType);
2094 if (stabstr[cnt] == ' ') cnt++;
2098 cnt = strlen(stabstr);
2099 return(&(stabstr[cnt]));
2103 // This function takes a <typeDef> and parses it
2105 // <typeDef> = <symDesc> |
2107 // *<typeUse> | Pointer to a type
2109 // f<typeUse> | function type
2110 // R<int>,<int> | Real type
2111 // b[u|s][c|]<int>;<int>;<int> | Builtin
2116 // k<typeDef> | SunPro constant
2117 // B<typeDef> | SunPro volatile
2118 // M<symDesc>;<int>| Fortran CHARACTER array
2119 // s<int><fields> | Structure <int> is size
2120 // u<int><fields> | Union <int> is size
2123 // <enumType> = <ident>:<int> | <ident>:<int>,<enumType>
2125 // It adds the typeDef to the type definition with the name name, and id ID.
2127 static char *parseTypeDef(Module *mod, char *stabstr,
2128 const char *name, int ID, unsigned int sizeHint)
2130 typeCollection *tc = typeCollection::getModTypeCollection(mod);
2131 Type * newType = NULL;
2132 fieldListType * newFieldType = NULL, *newFieldType2 = NULL;
2133 Type * ptrType = NULL;
2135 std::string compsymdesc;
2144 cnt = i = j = k = 0;
2146 assert (stabstr[0] != '=');
2148 // //bperr( "parsing %s\n", stabstr);
2149 if (isSymId(stabstr[0]))
2151 typdescr = dataScalar;
2152 type = parseSymDesc(stabstr, cnt);
2157 // as far as I can tell, this only happens when defining an empty
2160 std::string tName = convertCharToString(name);
2161 newType = new typeScalar(ID, 0, tName);
2162 newType = tc->addOrUpdateType((typeScalar *) newType);
2164 else if (stabstr[cnt] == '=')
2166 // XXX - in the new type t(0,1)=(0,2)=s... is possible
2167 // skip the second id for now -- jkh 3/21/99
2168 stabstr = parseTypeDef(mod, &(stabstr[cnt+i+1]), name, type);
2172 oldType = tc->findOrCreateType(type);
2173 if (!oldType) oldType = Symtab::type_Untyped().get();
2174 std::string tName = convertCharToString(name);
2175 newType = new typeTypedef(ID, oldType, tName, sizeHint);
2176 tc->addOrUpdateType((typeTypedef *) newType);
2182 std::string tName = convertCharToString(name);
2183 oldType = tc->findOrCreateType(type);
2184 newType = new typeTypedef(ID, oldType, tName, sizeHint);
2185 newType = tc->addOrUpdateType((typeTypedef *) newType);
2188 switch (stabstr[0]) {
2189 case 'x': //cross reference
2191 parseCrossRef(tc, name, ID, stabstr, cnt);
2196 /* pointer to another type */
2198 ptrID = parseTypeUse(mod, stabstr, cnt, NULL);
2200 // Create a new B_type that points to a structure
2201 ptrType = tc->findOrCreateType(ptrID);
2202 if (!ptrType) ptrType = Symtab::type_Untyped().get();
2204 newType = new typePointer(ID, ptrType);
2205 // Add to typeCollection
2206 newType = tc->addOrUpdateType((typePointer *) newType);
2207 return(&(stabstr[cnt]));
2213 (void) parseArrayDef(mod, name, ID, stabstr, cnt, sizeHint);
2214 return (&stabstr[cnt]);
2219 /* function with return type and prototype */
2221 // g<typeUse>[<typeUse>]*#
2222 typdescr = dataFunction;
2224 cnt++; /* skip the g */
2225 type = parseTypeUse(mod, stabstr, cnt, name);
2226 ptrType = tc->findOrCreateType(type);
2229 std::string tName = convertCharToString(name);
2230 typeFunction *newFunction =
2231 new typeFunction(ID, ptrType, tName);
2232 typeFunction *newFunction2 = NULL;
2235 newFunction2 = dynamic_cast<typeFunction*>(tc->addOrUpdateType(newFunction));
2236 if(newFunction2 != newFunction)
2237 newFunction->decrRefCount();
2239 if (!newFunction2) {
2240 //bpfatal(" Can't Allocate new type ");
2241 types_printf("%s[%d]: parseTypeDef: unable to allocate newType\n", FILE__, __LINE__);
2245 while ((stabstr[cnt] != '#') && (stabstr[cnt])) {
2247 paramType = parseTypeUse(mod, stabstr, cnt, name);
2248 newType = tc->findOrCreateType(paramType);
2249 newFunction2->addParam(newType);
2250 //newFunction2->addField(buffer, newType->getDataClass(), newType, curOffset, newType->getSize());
2255 if (stabstr[cnt] == '#') cnt++;
2261 typdescr = dataFunction;
2263 cnt++; /* skip the f */
2264 type = parseTypeUse(mod, stabstr, cnt, name);
2265 ptrType = tc->findOrCreateType(type);
2268 std::string tName = convertCharToString(name);
2269 newType = new typeFunction(ID, ptrType, tName);
2270 newType = tc->addOrUpdateType((typeFunction *) newType);
2272 // skip to end - SunPro Compilers output extra info here - jkh 6/9/3
2273 // cnt = strlen(stabstr);
2282 int baseType = parseSymDesc(stabstr, cnt);
2283 if (baseType != -2 || (stabstr[cnt] != ';')) {
2284 //bperr("unexpected non character array %s\n", stabstr);
2288 if (stabstr[cnt] == 'T') {
2289 /* Fortran stack-based array bounds */
2292 (void) parseSymDesc(stabstr, cnt);
2293 } else if (stabstr[cnt] == 'J') {
2294 /* Unbounded range */
2297 (void) parseSymDesc(stabstr, cnt);
2299 size = parseSymDesc(stabstr, cnt);
2301 ptrType = tc->findOrCreateType(baseType);
2302 std::string tName = convertCharToString(name);
2304 Type *newAType = new typeArray(ID, ptrType, 1, size, tName);
2305 newType = tc->addOrUpdateType((typeArray* ) newAType);
2312 // Define a floating point type - R fp-type; bytes;
2314 (void) parseSymDesc(stabstr, cnt);
2317 int bytes = parseSymDesc(stabstr, cnt);
2319 newType = new typeScalar(ID, bytes, name);
2320 newType = tc->addOrUpdateType((typeScalar *) newType);
2322 if (stabstr[cnt] == ';') cnt++; // skip the final ';'
2324 // gcc 3.0 adds an extra field that is always 0 (no indication in the code why)
2325 if (stabstr[cnt] == '0') cnt += 2; // skip the final '0;'
2332 // builtin type b - signed char-flag width; offset; nbits
2333 int limit = strlen(&stabstr[cnt]);
2336 while (!isdigit(stabstr[cnt+i]) && (i < limit)) i++;
2337 if (i >= limit) return(&(stabstr[cnt]));
2340 int size = parseSymDesc(stabstr,cnt);
2342 i++; // skip the ';'
2345 while (stabstr[cnt+i] != ';' && (i < limit)) i++;
2346 if (i >= limit) return(&(stabstr[cnt]));
2350 parseSymDesc(stabstr, cnt);
2352 if (stabstr[cnt]) cnt++; // skip the final ';'
2354 newType = new typeScalar(ID, size, name);
2356 newType = tc->addOrUpdateType((typeScalar *) newType);
2358 return &stabstr[cnt];
2361 case 'r': // range type
2363 return parseRangeType(mod, name, ID, stabstr, sizeHint);
2366 case 'e': // Enumerated type
2368 cnt++; /* skip the 'e' */
2370 // Create new Enum type
2371 std::string tName = convertCharToString(name);
2372 typeEnum *newEnumType = new typeEnum(ID, tName);
2373 // Add type to collection
2374 newEnumType = dynamic_cast<typeEnum *>(tc->addOrUpdateType(newEnumType));
2376 while (stabstr[cnt]) {
2377 /* Get enum component value */
2378 compsymdesc = getIdentifier(stabstr, cnt);
2379 cnt++; /* skip colon */
2381 #ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
2382 //bperr( "%s[%d]: before parseSymDesc -- enumerated type \n",
2383 // __FILE__, __LINE__);
2385 value = parseSymDesc(stabstr, cnt);
2387 // add enum field to type
2388 newEnumType->addConstant(compsymdesc, value);
2390 cnt++; /* skip trailing comma */
2391 if ((stabstr[cnt]) == ';') cnt++; /* End of enum stab record */
2395 case '@': // type attribute, defines size and type (negative num)
2397 return parseAttrType(mod, name, ID, stabstr, cnt);
2400 case '&': //XXX- Need to complete, may be more to parse jdd 4/22/99
2402 return parseRefType(mod, name, ID, stabstr, cnt);
2405 case 'k': // Sun constant type s<typeDef> - parse as <typeDef>
2407 return parseTypeDef(mod, &stabstr[cnt+1], name, ID);
2410 case 'V': // AIX colatile ? type V<typeDef> - parse as <typeDef>
2411 case 'B': // Sun volatile type B<typeDef> - parse as <typeDef>
2412 return parseTypeDef(mod, &stabstr[cnt+1], name, ID);
2417 case 'T': // Fortran TYPE
2419 /* Type descriptor */
2420 if (stabstr[cnt] == 's' || stabstr[cnt] == 'T') {
2421 typdescr = dataStructure;
2423 typdescr = dataUnion;
2426 cnt++; // skip to size
2427 structsize = parseSymDesc(stabstr, cnt);
2429 std::string tName = convertCharToString(name);
2431 if (typdescr == dataStructure) {
2432 newFieldType = new typeStruct(ID, tName);
2433 newFieldType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeStruct *) newFieldType));
2436 newFieldType = new typeUnion(ID, tName);
2437 newFieldType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeUnion *) newFieldType));
2439 //add to type collection
2441 //TODO What if two different files have the same structure?? // on AIX
2443 newFieldType2 = dynamic_cast<fieldListType *>(newFieldType);
2444 if(newFieldType2 != newFieldType)
2445 newFieldType->decrRefCount();
2446 char *ret = parseFieldList(mod, newFieldType2, &stabstr[cnt], false);
2453 // C++ specific stabs (Sun compiler)
2454 return parseCPlusPlusInfo(mod, stabstr, name, ID);
2457 case 'Z': // What is this ??? - jkh 10/14/99 (xlc compiler uses it)
2459 return (&stabstr[1]);
2464 //Class method definition
2466 if (stabstr[cnt] == '#') {
2469 parseTypeUse(mod, stabstr, cnt, name);
2473 //Skip class type, return typ and arg types
2474 parseTypeUse(mod, stabstr, cnt, name);
2475 if (stabstr[cnt] == ',')
2477 else if (stabstr[cnt] == ';')
2483 return(&(stabstr[cnt]));
2487 //bperr( "ERROR: Unrecognized str = %s\n", &stabstr[cnt]);
2489 // Null probably isn't the right choice here.
2490 cnt = strlen(stabstr);
2495 return(&(stabstr[cnt]));
2496 } /* end of parseTypeDef*/
2499 // parseConstantUse - parse a constant (used by Fortran PARAMETERS)
2501 // <constantUse> = =i<int> |
2505 static Type *parseConstantUse(Module *mod, char *stabstr, int &cnt)
2507 typeCollection *tc = typeCollection::getModTypeCollection(mod);
2513 if (stabstr[cnt] == 'i') {
2514 ret = tc->findType("integer*4");
2515 } else if (stabstr[cnt] == 'r') {
2516 ret = tc->findType("double");
2517 } else if (stabstr[cnt] == 's') {
2518 ret = tc->findType("char *");
2520 //bperr("unknown constant type %s\n", &stabstr[cnt]);
2524 cnt = strlen(stabstr);