00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <ctype.h>
00032 #include <iostream>
00033
00034 #define DMGL_PARAMS (1 << 0)
00035 #define DMGL_ANSI (1 << 1)
00036 #define DMGL_VERBOSE (1 << 3)
00037
00038 #include "symutil.h"
00039 #include "Symtab.h"
00040 #include "Symbol.h"
00041 #include "Function.h"
00042 #include "Variable.h"
00043 #include "Module.h"
00044 #include "Collections.h"
00045 #include "annotations.h"
00046 #include "common/h/headers.h"
00047 #include "Type-mem.h"
00048
00049 #include "debug.h"
00050
00051 using namespace Dyninst;
00052 using namespace Dyninst::SymtabAPI;
00053
00054
00055
00056
00057
00058
00059 extern std::string symt_current_func_name;
00060 extern std::string symt_current_mangled_func_name;
00061 extern Function *symt_current_func;
00062 namespace Dyninst{
00063 namespace SymtabAPI{
00064 std::string parseStabString(Module *mod, int linenum, char *stabstr,
00065 int framePtr, typeCommon *commonBlock = NULL);
00066 }
00067 }
00068
00069
00070 static int parseSymDesc(char *stabstr, int &cnt);
00071 static Type *parseConstantUse(Module *, char *stabstr, int &cnt);
00072 static char *parseTypeDef(Module *, char *stabstr,
00073 const char *name, int ID, unsigned int sizeHint = 0);
00074 static int parseTypeUse(Module*, char *&stabstr, int &cnt,
00075 const char *name);
00076 static inline bool isSymId(char ch);
00077 static std::string getIdentifier(char *stabstr, int &cnt, bool stopOnSpace=false);
00078
00079 static std::string currentRawSymbolName;
00080
00081 std::string convertCharToString(const char *ptr){
00082 if(ptr)
00083 return ptr;
00084 else
00085 return "";
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 void vectorNameMatchKLUDGE(Module *mod, char *demangled_sym, std::vector<Function *> &bpfv, std::vector<int> &matches)
00100 {
00101
00102 for (unsigned int i = 0; i < bpfv.size(); ++i) {
00103 std::string l_mangled;
00104 std::vector<Symbol *> syms;
00105 bpfv[i]->getSymbols(syms);
00106 if (syms.size()) {
00107 l_mangled = syms[0]->getMangledName();
00108
00109 char * l_demangled_raw = P_cplus_demangle(l_mangled.c_str(), mod->exec()->isNativeCompiler());
00110 if( l_demangled_raw == NULL ) {
00111 l_demangled_raw = strdup(l_mangled.c_str());
00112 }
00113
00114 if (!strcmp(l_demangled_raw, demangled_sym)) {
00115 matches.push_back(i);
00116 }
00117 free(l_demangled_raw);
00118 }
00119 }
00120 }
00121
00122 Function *mangledNameMatchKLUDGE(const char *pretty, const char *mangled,
00123 Module *mod)
00124 {
00125
00126 std::vector<Function *> bpfv;
00127 if (!mod->exec()->findFunctionsByName(bpfv, pretty)) {
00128
00129 return NULL;
00130 }
00131
00132
00133
00134
00135 if (lang_Fortran_with_pretty_debug == mod->language()) {
00136
00137 if (bpfv.size() == 1)
00138 return bpfv[0];
00139 else {
00140 cerr << __FILE__ << __LINE__ << ": FIXME!" << endl;
00141 return NULL;
00142 }
00143 }
00144
00145
00146 char * demangled_sym = P_cplus_demangle( mangled, mod->exec()->isNativeCompiler(), true );
00147 if( demangled_sym == NULL ) {
00148 demangled_sym = strdup( mangled );
00149 assert( demangled_sym != NULL );
00150 }
00151
00152 std::vector<int> matches;
00153
00154 vectorNameMatchKLUDGE(mod, demangled_sym, bpfv, matches);
00155
00156 Function *ret = NULL;
00157
00158 if (matches.size() == 1) {ret = bpfv[matches[0]]; goto clean_up;}
00159 if (matches.size() > 1) goto clean_up;
00160
00161
00162 bpfv.clear();
00163 matches.clear();
00164
00165 vectorNameMatchKLUDGE(mod, demangled_sym, bpfv, matches);
00166 if (matches.size() == 1) {ret = bpfv[matches[0]]; goto clean_up;}
00167 if (matches.size() > 1) goto clean_up;
00168
00169 clean_up:
00170 free( demangled_sym );
00171 return ret;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 std::string Dyninst::SymtabAPI::parseStabString(Module *mod, int linenum, char *stabstr,
00198 int framePtr, typeCommon *commonBlock)
00199 {
00200 typeCollection *tc = typeCollection::getModTypeCollection(mod);
00201 int cnt;
00202 int ID = 0;
00203 int symdescID = 0;
00204 int funcReturnID = 0;
00205 Function *fp = NULL;
00206 Type * ptrType = NULL;
00207 Type * newType = NULL;
00208 localVar *locVar = NULL;
00209 cnt= 0;
00210
00211 types_printf("parseStabString, mod %p/%s, linenum %d, stabstr %s\n",
00212 mod,
00213 (mod != NULL) ? mod->fileName().c_str() : "NULL",
00214 linenum,
00215 stabstr);
00216
00217 std::string fName = mod->fileName();
00218
00219
00220 std::string mangledname = getIdentifier( stabstr, cnt );
00221
00222 currentRawSymbolName = mangledname;
00223 char * demangled = P_cplus_demangle( mangledname.c_str(), mod->exec()->isNativeCompiler() );
00224 std::string name;
00225
00226 if ( demangled == NULL )
00227 {
00228 name = mangledname;
00229 }
00230 else
00231 {
00232 name = demangled;
00233 }
00234
00235 if ( name[0] != '\0' && stabstr[cnt] != ':' )
00236 {
00237 types_printf("\t returning name %s\n", name.c_str());
00238 return name;
00239 }
00240
00241 if (stabstr[cnt] == ':')
00242 {
00243
00244 cnt++;
00245 }
00246
00247 if (isSymId(stabstr[cnt]))
00248 {
00249
00250
00251 ID = parseSymDesc(stabstr, cnt);
00252
00253 if (stabstr[cnt] == '=')
00254 {
00255
00256
00257 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name.c_str(), ID);
00258 cnt = 0;
00259 ptrType = tc->findOrCreateType(ID);
00260 if (!symt_current_func)
00261 {
00262
00263
00264
00265
00266 std::string modName = mod->fileName();
00267
00268
00269
00270
00271 }
00272 else
00273 {
00274 locVar = new localVar(name, ptrType, fName, linenum, symt_current_func);
00275 VariableLocation loc;
00276 loc.stClass = storageRegOffset;
00277 loc.refClass = storageNoRef;
00278 loc.frameOffset = framePtr;
00279 locVar->addLocation(loc);
00280 if (!ptrType) {
00281
00282
00283 }
00284
00285 localVarCollection *lvs = NULL;
00286
00287 if (!symt_current_func->getAnnotation(lvs, FunctionLocalVariablesAnno))
00288 {
00289 lvs = new localVarCollection();
00290 if (!symt_current_func->addAnnotation(lvs, FunctionLocalVariablesAnno))
00291 {
00292 fprintf(stderr, "%s[%d]: failed to add annotation here\n", FILE__, __LINE__);
00293 }
00294 }
00295
00296 if (!lvs)
00297 {
00298 fprintf(stderr, "%s[%d]: failed to get annotation here\n", FILE__, __LINE__);
00299 }
00300
00301 lvs->addLocalVar(locVar);
00302 }
00303 }
00304 else if (symt_current_func)
00305 {
00306
00307 ptrType = tc->findOrCreateType( ID);
00308
00309 locVar = new localVar(name, ptrType, fName, linenum, symt_current_func);
00310 VariableLocation loc;
00311 loc.stClass = storageRegOffset;
00312 loc.refClass = storageNoRef;
00313 loc.frameOffset = framePtr;
00314 locVar->addLocation(loc);
00315
00316 if (!ptrType)
00317 {
00318
00319
00320 }
00321
00322 if (!symt_current_func->addLocalVar(locVar))
00323 {
00324 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
00325 }
00326
00327 }
00328 }
00329 else if (stabstr[cnt])
00330 {
00331 std::vector<Function *> bpfv;
00332
00333 switch (stabstr[cnt]) {
00334 case 'f':
00335 {
00336 std::string scopeName;
00337 std::string lfuncName;
00338 cnt++;
00339
00340 symt_current_func_name = name;
00341 symt_current_mangled_func_name = mangledname;
00342
00343 funcReturnID = parseTypeUse(mod, stabstr, cnt, name.c_str());
00344
00345 if (stabstr[cnt]==',')
00346 {
00347 cnt++;
00348
00349
00350 lfuncName = getIdentifier(stabstr, cnt);
00351
00352 assert(stabstr[cnt] == ',');
00353 cnt++;
00354
00355
00356 scopeName = getIdentifier(stabstr, cnt);
00357
00358 if (stabstr[cnt])
00359 {
00360
00361 }
00362 }
00363
00364 if (!scopeName.length())
00365 {
00366
00367
00368 ptrType = tc->findOrCreateType(funcReturnID);
00369
00370
00371
00372
00373 if ( !ptrType) ptrType = Symtab::type_Untyped().get();
00374
00375 if (!(mod->exec()->findFunctionsByName(bpfv, name)))
00376 {
00377
00378
00379
00380
00381
00382
00383
00384
00385 fp = NULL;
00386 }
00387 else
00388 {
00389 if (bpfv.size() > 1)
00390 {
00391
00392 char msg[1024];
00393 sprintf(msg, "%s[%d]: found %d functions with name %s, using the first",
00394 __FILE__, __LINE__, (int)bpfv.size(), name.c_str());
00395
00396
00397 }
00398 else if (!bpfv.size())
00399 {
00400
00401
00402 break;
00403 }
00404
00405 fp = bpfv[0];
00406
00407 fp->setReturnType(ptrType);
00408 }
00409 }
00410 else
00411 {
00412
00413 }
00414
00415 symt_current_func = fp;
00416
00417 cnt = strlen(stabstr);
00418
00419 break;
00420 }
00421
00422 case 'F':
00423 {
00424 cnt++;
00425
00426 funcReturnID = parseTypeUse(mod, stabstr, cnt, name.c_str());
00427
00428 symt_current_func_name = name;
00429 symt_current_mangled_func_name = mangledname;
00430
00431
00432
00433
00434
00435
00436 while (stabstr[cnt] == ';')
00437 {
00438 cnt++;
00439 (void) parseTypeUse(mod, stabstr, cnt, "");
00440 }
00441
00442
00443 cnt = strlen(stabstr);
00444
00445 ptrType = tc->findOrCreateType(funcReturnID);
00446 if (!ptrType) ptrType = Symtab::type_Untyped().get();
00447
00448 std::vector<Function *>fpv;
00449 if (!mod->exec()->findFunctionsByName(fpv, symt_current_mangled_func_name))
00450
00451 {
00452 std::string modName = mod->fileName();
00453
00454 if (NULL == (fp = mangledNameMatchKLUDGE(symt_current_func_name.c_str(),
00455 symt_current_mangled_func_name.c_str(), mod)))
00456 {
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 break;
00467 }
00468 }
00469 fp = fpv[0];
00470
00471 fp->setReturnType(ptrType);
00472 symt_current_func = fp;
00473 fpv.clear();
00474 }
00475 break;
00476
00477 case 'U':
00478 case 'E':
00479 case 'G':
00480 cnt++;
00481
00482
00483 symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
00484 Type *BPtype;
00485
00486 BPtype = tc->findOrCreateType(symdescID);
00487 if (BPtype)
00488 {
00489 Module *toUse = mod;
00490 std::vector<Variable *> ret;
00491 bool result = mod->findVariablesByName(ret, name);
00492 if (!result) {
00493
00494 if (mod->exec()->getDefaultModule()->findVariablesByName(ret, name))
00495 toUse = mod->exec()->getDefaultModule();
00496 }
00497 for (unsigned i=0; i<ret.size(); i++) {
00498 ret[i]->setType(BPtype);
00499 }
00500
00501 typeCollection *tc_to_use = typeCollection::getModTypeCollection(toUse);
00502 tc_to_use->addGlobalVariable(name, BPtype);
00503 }
00504 else
00505 break;
00506
00507 case 'P':
00508 case 'R':
00509 case 'v':
00510 case 'X':
00511 case 'p':
00512 {
00513
00514 cnt++;
00515
00516
00517 symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
00518
00519 if (stabstr[cnt] == ';')
00520 {
00521
00522 cnt = strlen(stabstr);
00523 }
00524
00525
00526
00527
00528
00529
00530 ptrType = tc->findOrCreateType(symdescID);
00531 if (!ptrType) ptrType = Symtab::type_Untyped().get();
00532
00533 localVar *param;
00534
00535 param = new localVar(name, ptrType, fName, linenum, symt_current_func);
00536 VariableLocation loc;
00537 loc.stClass = storageRegOffset;
00538 loc.refClass = storageNoRef;
00539 loc.frameOffset = framePtr;
00540 param->addLocation(loc);
00541
00542 if (symt_current_func)
00543 {
00544 if (!symt_current_func->addParam(param))
00545 {
00546 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
00547 }
00548 }
00549
00550 break;
00551 }
00552
00553 case 'c':
00554 {
00555 cnt++;
00556 if (symt_current_mangled_func_name.length())
00557 {
00558 std::vector<Function *>fpv;
00559 if (mod->exec()->findFunctionsByName(fpv, symt_current_mangled_func_name))
00560 {
00561
00562 fp = fpv[0];
00563 symt_current_func = fp;
00564 }
00565 fpv.clear();
00566 }
00567
00568 ptrType = parseConstantUse(mod, stabstr, cnt);
00569
00570 if (!ptrType) ptrType = Symtab::type_Untyped().get();
00571
00572 localVar *var;
00573 var = new localVar(name, ptrType, fName, linenum, symt_current_func);
00574 VariableLocation loc;
00575 loc.stClass = storageRegOffset;
00576 loc.refClass = storageNoRef;
00577 loc.frameOffset = 0;
00578 var->addLocation(loc);
00579 if (symt_current_func) {
00580 if (!symt_current_func->addParam(var))
00581 {
00582 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
00583 }
00584 }
00585 }
00586 break;
00587
00588 case 'r':
00589 cnt++;
00590
00591
00592 symdescID = parseSymDesc(stabstr, cnt);
00593 break;
00594
00595 case 'S':
00596 {
00597 cnt++;
00598
00599
00600 symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
00601
00602
00603 Type *BPtype;
00604
00605 std::string nameTrailer;
00606 if (name.find(".") < name.length())
00607 {
00608 std::string defaultNameSpace;
00609 defaultNameSpace = name.substr(0,name.find("."));
00610 nameTrailer = name.substr(name.find(".")+1,name.length()-name.find(".")-1);
00611 mod->setDefaultNamespacePrefix(defaultNameSpace);
00612 }
00613 else
00614 {
00615 nameTrailer = name;
00616 }
00617
00618 BPtype = tc->findOrCreateType(symdescID);
00619
00620 if (BPtype)
00621 {
00622 Symtab *img = mod->exec();
00623 std::vector<Symbol *>syms;
00624 if (img->findSymbol(syms,
00625 nameTrailer,
00626 Symbol::ST_OBJECT,
00627 mangledName) ||
00628 img->findSymbol(syms,
00629 nameTrailer,
00630 Symbol::ST_OBJECT,
00631 mangledName,
00632 true))
00633 {
00634
00635 tc->addGlobalVariable(nameTrailer, BPtype);
00636 }
00637 }
00638
00639
00640
00641
00642
00643
00644
00645 break;
00646 }
00647
00648 case 't':
00649 cnt++;
00650
00651
00652 symdescID = parseSymDesc(stabstr, cnt);
00653
00654
00655 if (stabstr[cnt] == '=')
00656 {
00657
00658
00659 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name.c_str(), symdescID);
00660 cnt = 0;
00661
00662
00663
00664 if (stabstr[0] && strcmp(stabstr, ";"))
00665 {
00666
00667
00668 }
00669 }
00670 else
00671 {
00672
00673
00674 ptrType = tc->findOrCreateType(symdescID);
00675 if (!ptrType)
00676 {
00677 ptrType = Symtab::type_Untyped().get();
00678 }
00679
00680
00681
00682
00683 typeTypedef *newType = new typeTypedef(ptrType, name);
00684
00685 if (newType)
00686 {
00687 tc->addOrUpdateType(newType);
00688 }
00689 }
00690 break;
00691
00692 case ':':
00693 if ((stabstr[cnt+1] == 't') || (stabstr[cnt+1] == 'T'))
00694 {
00695
00696 parseStabString(mod, linenum, &stabstr[cnt+1], framePtr);
00697 }
00698
00699
00700
00701
00702
00703
00704 break;
00705
00706 case 'T':
00707 cnt++;
00708
00709 if (stabstr[cnt] == 't')
00710 {
00711
00712
00713 cnt++;
00714 }
00715
00716
00717 symdescID = parseSymDesc(stabstr, cnt);
00718
00719
00720 if (stabstr[cnt] == '=')
00721 {
00722
00723 stabstr = parseTypeDef(mod,(&stabstr[cnt+1]),name.c_str(),symdescID);
00724 cnt = 0;
00725
00726
00727
00728
00729
00730
00731
00732 }
00733 else
00734 {
00735
00736
00737 newType = Type::createPlaceholder(symdescID, name);
00738 }
00739
00740 break;
00741
00742 case 'V':
00743 cnt++;
00744
00745
00746
00747
00748 symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
00749
00750
00751 BPtype = tc->findOrCreateType(symdescID);
00752
00753 if (!BPtype)
00754 {
00755
00756
00757 break;
00758 }
00759
00760 if (commonBlock)
00761 {
00762
00763
00764
00765
00766
00767
00768 bool found = false;
00769 const std::vector<Field *> *fields;
00770 fields = commonBlock->getFields();
00771 if (fields)
00772 {
00773 for (unsigned int i=0; i < fields->size(); i++)
00774 {
00775 if (name == (*fields)[i]->getName())
00776 {
00777 found = true;
00778 break;
00779 }
00780
00781 int start1, start2, end1, end2;
00782 start1 = (*fields)[i]->getOffset();
00783 end1 = start1 + (*fields)[i]->getSize();
00784 start2 = framePtr;
00785 end2 = framePtr + BPtype->getSize();
00786 if ( ((start2 >= start1) && (start2 < end1))
00787 || ((start1 >= start2) && (start1 < end2)) )
00788 {
00789
00790
00791
00792
00793 found = true;
00794 break;
00795 }
00796 }
00797 }
00798
00799 if (!found)
00800 {
00801 commonBlock->addField(name, BPtype, framePtr);
00802 }
00803 }
00804 else
00805 {
00806
00807 if (symt_current_func)
00808 {
00809 locVar = new localVar(name, BPtype, fName, linenum, symt_current_func);
00810 VariableLocation loc;
00811 loc.stClass = storageAddr;
00812 loc.refClass = storageNoRef;
00813 loc.frameOffset = framePtr;
00814 locVar->addLocation(loc);
00815
00816 if (!symt_current_func->addLocalVar(locVar))
00817 {
00818 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
00819 }
00820 }
00821
00822
00823
00824
00825
00826
00827 }
00828 break;
00829 case 'l':
00830
00831
00832
00833
00834
00835 cnt = strlen(stabstr);
00836 break;
00837
00838 case 'Y':
00839 cnt++;
00840 if (stabstr[cnt] == 'I')
00841 {
00842
00843 cnt++;
00844 if (stabstr[cnt] == 'f')
00845 {
00846 while (stabstr[cnt] != '@') cnt++;
00847 cnt++;
00848 cnt++;
00849 cnt++;
00850 while (stabstr[cnt] != ':') cnt++;
00851
00852 char *dupstring = strdup(stabstr);
00853 strcpy(dupstring, mangledname.c_str());
00854 strcat(dupstring, stabstr+cnt);
00855 parseStabString(mod, linenum, dupstring, framePtr, commonBlock);
00856 free(dupstring);
00857 }
00858 }
00859 cnt = strlen(stabstr);
00860 break;
00861
00862 default:
00863
00864
00865 break;
00866 }
00867 }
00868
00869 return(&stabstr[cnt]);
00870 }
00871
00872
00873
00874
00875
00876 inline bool isSymId(char ch)
00877 {
00878 return ((ch == '(') || isdigit(ch) || (ch == '-'));
00879 }
00880
00881
00882
00883
00884
00885 int parseSymDesc(char *stabstr, int &cnt)
00886 {
00887 int id;
00888 int lid;
00889 int hid;
00890 int sign = 1;
00891 bool newForm = false;
00892
00893 hid = 0;
00894
00895 if (stabstr[cnt] == '(') {
00896 cnt++;
00897 while (isdigit(stabstr[cnt])) {
00898 hid = hid * 10 + stabstr[cnt] - '0';
00899 cnt++;
00900 }
00901
00902
00903 if (stabstr[cnt] == ',') cnt++;
00904 newForm = true;
00905 }
00906
00907 if (stabstr[cnt] == '-') {
00908 sign = -1;
00909 cnt++;
00910 }
00911
00912 lid = 0;
00913 while (isdigit(stabstr[cnt])) {
00914 lid = lid * 10 + stabstr[cnt] - '0';
00915 cnt++;
00916 }
00917 if( hid != 0 )
00918 assert(lid < 65536);
00919
00920
00921 if (newForm) cnt++;
00922
00923 id = hid * 65536 + lid;
00924 id = id * sign;
00925
00926 return id;
00927 }
00928
00929
00930
00931
00932 std::string getIdentifier( char *stabstr, int &cnt, bool stopOnSpace ) {
00933 int i = 0;
00934 int brCnt = 0;
00935 bool idChar = true;
00936
00937 while( idChar ) {
00938 switch( stabstr[ cnt + i ] ) {
00939 case '<':
00940 case '(':
00941 brCnt++;
00942 i++;
00943 break;
00944
00945 case '>':
00946 case ')':
00947 brCnt--;
00948 i++;
00949 break;
00950
00951 case ' ':
00952 if ( !stopOnSpace ) {
00953 i++;
00954 break;
00955 }
00956 case '\0':
00957 case ':':
00958 case ',':
00959 case ';':
00960
00961 if ( stabstr[ cnt + i ] == ':' && stabstr[ cnt + i + 1 ] == ':' &&
00962 (stabstr[ cnt + i + 2 ] == '_' || isalpha(stabstr[ cnt + i + 2 ])) ) {
00963 i+=3;
00964 break;
00965 }
00966
00967
00968 if( brCnt != 0 && stabstr[ cnt + i ] != '\0' ) {
00969 i++;
00970 }
00971 else if( brCnt ) {
00972
00973 idChar = false;
00974 }
00975 else {
00976 idChar = false;
00977 }
00978 break;
00979
00980 default:
00981 i++;
00982 break;
00983 }
00984 }
00985
00986 char * identifier = (char *)malloc( i + 1 );
00987 assert( identifier );
00988
00989 strncpy( identifier, & stabstr[cnt], i );
00990 identifier[i] = '\0';
00991 cnt += i;
00992
00993 std::string pd_identifier = identifier;
00994 free(identifier);
00995 return pd_identifier;
00996 }
00997
00998
00999
01000
01001
01002
01003
01004 char * getFieldName( char *stabstr, int &cnt) {
01005 int i = 0;
01006 bool idChar = true;
01007
01008 while ( idChar ) {
01009 switch( stabstr[ cnt + i ] ) {
01010 case ':':
01011 idChar = false;
01012 break;
01013 default:
01014 i++;
01015 }
01016 }
01017
01018 char * identifier = (char *) malloc(i + 1);
01019 assert(identifier);
01020
01021 strncpy(identifier, &stabstr[cnt], i);
01022 identifier[i] = '\0';
01023 cnt += i;
01024
01025 return identifier;
01026 }
01027
01028
01029
01030
01031
01032
01033 static int parseTypeUse(Module *mod,char *&stabstr, int &cnt,
01034 const char *name)
01035 {
01036 int ret = parseSymDesc(stabstr, cnt);
01037
01038 if (stabstr[cnt] == '=') {
01039
01040 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name, ret);
01041 cnt = 0;
01042 }
01043 return ret;
01044 }
01045
01046
01047
01048
01049
01050
01051 static char *parseCrossRef(typeCollection *moduleTypes,const char * ,
01052 int ID, char *stabstr, int &cnt)
01053 {
01054 std::string temp;
01055 Type *newType = NULL;
01056 char xreftype;
01057 cnt++;
01058
01059 if ((stabstr[cnt] == 's') ||
01060 (stabstr[cnt] == 'u') ||
01061 (stabstr[cnt] == 'e')) {
01062 xreftype = stabstr[cnt++];
01063
01064 temp = getIdentifier(stabstr, cnt);
01065 cnt++;
01066
01067
01068 Type *ptrType = moduleTypes->findType(temp.c_str());
01069 if (!ptrType) {
01070
01071
01072
01073 if (xreftype == 'e') {
01074 newType = new typeEnum(ID, temp);
01075 newType = moduleTypes->addOrUpdateType((typeEnum *) newType);
01076 } else if (xreftype == 'u') {
01077 newType = new typeUnion(ID, temp);
01078 newType = moduleTypes->addOrUpdateType((typeEnum *) newType);
01079 } else {
01080 newType = new typeStruct(ID, temp);
01081 newType = moduleTypes->addOrUpdateType((typeEnum *) newType);
01082 }
01083 assert(newType);
01084 }
01085 } else {
01086
01087
01088 temp = getIdentifier(stabstr, cnt);
01089 cnt++;
01090 }
01091
01092 return( &(stabstr[cnt]));
01093 }
01094
01095
01096
01097
01098
01099
01100
01101 static Type *parseArrayDef(Module *mod, const char *name,
01102 int ID, char *&stabstr, int &cnt, unsigned int sizeHint)
01103 {
01104 typeCollection *tc = typeCollection::getModTypeCollection(mod);
01105 char *symdesc;
01106 int symdescID;
01107 int elementType;
01108 Type *newType = NULL;
01109 Type *ptrType = NULL;
01110 int lowbound, hibound;
01111
01112
01113
01114 assert(stabstr[cnt] == 'a' || stabstr[cnt] == 'A');
01115
01116 if (stabstr[cnt ++] == 'A') {
01117
01118 lowbound = 1;
01119 hibound = 0;
01120 elementType = parseSymDesc(stabstr, cnt);
01121 ptrType = tc->findOrCreateType(elementType);
01122 } else {
01123
01124
01125 if (stabstr[cnt] != 'r') {
01126
01127 return(NULL);
01128 }
01129
01130
01131 symdesc = &(stabstr[cnt]);
01132
01133 cnt++;
01134
01135 symdescID = parseTypeUse(mod, stabstr, cnt, name);
01136
01137 cnt++;
01138 lowbound = parseSymDesc(stabstr, cnt);
01139
01140 cnt++;
01141 if (stabstr[cnt] == 'J') {
01142
01143 hibound = 0;
01144 cnt++;
01145 } else if (stabstr[cnt] == 'T') {
01146
01147 hibound = 0;
01148 cnt++;
01149 while (isdigit(stabstr[cnt])) cnt++;
01150 } else {
01151 hibound = parseSymDesc(stabstr, cnt);
01152 }
01153
01154 cnt++;
01155 elementType = parseSymDesc(stabstr, cnt);
01156
01157 if (stabstr[cnt] == 'a')
01158 {
01159
01160
01161
01162 ptrType = parseArrayDef(mod, name, 0, stabstr, cnt, sizeHint);
01163 }
01164 else
01165 {
01166 if (stabstr[cnt] == '=')
01167 {
01168
01169 char *temp;
01170 temp = parseTypeDef(mod, &(stabstr[cnt+1]), NULL, elementType);
01171
01172
01173
01174
01175 cnt = temp-stabstr;
01176 if (stabstr[cnt] == ':') {
01177
01178
01179 while (stabstr[cnt] != ';') cnt++;
01180 }
01181 }
01182 ptrType = tc->findOrCreateType(elementType);
01183 }
01184 }
01185
01186
01187
01188
01189 if (ptrType) {
01190
01191 std::string tName = convertCharToString(name);
01192
01193 typeArray *newAType = new typeArray(ID, ptrType, lowbound, hibound, tName, sizeHint);
01194
01195 newType = tc->addOrUpdateType((typeArray *) newAType);
01196
01197 return newAType;
01198 }
01199
01200
01201 return newType;
01202 }
01203
01204 int guessSize(const char *low, const char *hi)
01205 {
01206 long long l, h;
01207
01208 if (low[0] == '0')
01209 sscanf(low, "%llo", &l);
01210 else
01211 sscanf(low, "%lld", &l);
01212 if (hi[0] == '0')
01213 sscanf(hi, "%llo", &h);
01214 else
01215 sscanf(hi, "%lld", &h);
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228 if (l < 0) {
01229 if (l < -2147483648LL || h > 0x7fffffffLL)
01230 return 8;
01231 else if (l < 0xffff8000 || h > 0x7fff)
01232 return 4;
01233 else if (l < 0xffffff80 || h > 0x7f)
01234 return 2;
01235 else
01236 return 1;
01237 } else {
01238 if (h > 0xffffffffLL)
01239 return 8;
01240 else if (h > 0xffff)
01241 return 4;
01242 else if (h > 0xff)
01243 return 2;
01244 else
01245 return 1;
01246 }
01247 }
01248
01249 #if defined(i386_unknown_linux2_0) \
01250 || defined(x86_64_unknown_linux2_4)
01251
01252
01253
01254
01255
01256 static char *parseRangeType(Module *mod, const char *name, int ID,
01257 char *stabstr, unsigned int sizeHint = 0)
01258 {
01259 int cnt, i, symdescID;
01260
01261 Type *baseType;
01262
01263 cnt = i = 0;
01264
01265 assert(stabstr[0] == 'r');
01266 cnt++;
01267
01268
01269 symdescID = parseSymDesc(stabstr, cnt);
01270
01271 typeCollection *tc = typeCollection::getModTypeCollection(mod);
01272 if (!mod || !tc)
01273 {
01274 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
01275 return NULL;
01276 }
01277 else
01278 {
01279 baseType = tc->findType(symdescID);
01280 }
01281
01282
01283
01284 cnt++;
01285 i=0;
01286 if (stabstr[cnt] == '-' ) {
01287 i++;
01288 }
01289
01290
01291
01292 while (isdigit(stabstr[cnt+i])) i++;
01293
01294 char *low = (char *)malloc(sizeof(char)*(i+1));
01295 if(!strncpy(low, &(stabstr[cnt]), i))
01296
01297 exit(1);
01298 low[i] = '\0';
01299
01300 cnt = cnt + i + 1;
01301 i = 0;
01302 if((stabstr[cnt]) == '-') {
01303 i++;
01304 }
01305
01306 while (isdigit(stabstr[cnt+i])) i++;
01307 char *hi = (char *)malloc(sizeof(char)*(i+1));
01308 if(!strncpy(hi, &(stabstr[cnt]), i))
01309
01310 exit(1);
01311 hi[i] = '\0';
01312
01313 int j = atol(hi);
01314
01315 if (j == 0) {
01316
01317 int size = atol(low);
01318
01319
01320 Type *newType = new typeScalar(ID, size, name);
01321
01322 newType = tc->addOrUpdateType((typeScalar *) newType);
01323 }
01324 else {
01325
01326
01327 Type *newType;
01328 std::string tName = convertCharToString(name);
01329
01330 errno = 0;
01331 long low_conv = strtol(low, NULL, 10);
01332 if (errno)
01333 {
01334 low_conv = LONG_MIN;
01335 }
01336
01337 errno = 0;
01338 long hi_conv = strtol(hi, NULL, 10);
01339 if (errno)
01340 {
01341 hi_conv = LONG_MAX;
01342 }
01343
01344 if (baseType == NULL)
01345 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : guessSize(low,hi),
01346 low_conv, hi_conv, tName);
01347 else
01348 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : baseType->getSize(),
01349 low_conv, hi_conv, tName);
01350
01351 tc->addOrUpdateType((typeSubrange *) newType);
01352 }
01353 free(low);
01354 free(hi);
01355 hi=low=NULL;
01356
01357 cnt = cnt + i;
01358 if( stabstr[cnt] == ';')
01359 cnt++;
01360
01361 return(&(stabstr[cnt]));
01362 }
01363
01364 #else
01365
01366
01367
01368
01369
01370 static char *parseRangeType(Module *mod, const char *name, int ID,
01371 char *stabstr, unsigned int sizeHint = 0)
01372 {
01373 int cnt, i, symdescID;
01374 Type *baseType;
01375 Type *newType;
01376
01377 cnt = i = 0;
01378
01379 assert(stabstr[0] == 'r');
01380 cnt++;
01381
01382
01383 symdescID = parseSymDesc(stabstr, cnt);
01384
01385 typeCollection *tc = typeCollection::getModTypeCollection(mod);
01386 baseType = tc->findType(symdescID);
01387
01388
01389
01390 cnt++;
01391 i=0;
01392 if (stabstr[cnt] == '-' ) {
01393 i++;
01394 }
01395
01396
01397 while (isdigit(stabstr[cnt+i])) i++;
01398
01399 char *temp = (char *)malloc(sizeof(char)*(i+1));
01400 if(!strncpy(temp, &(stabstr[cnt]), i))
01401
01402 exit(1);
01403 temp[i] = '\0';
01404 int j = atol(temp);
01405
01406 char *low = temp;
01407 cnt = cnt + i + 1;
01408 i = 0;
01409 if((stabstr[cnt]) == '-') {
01410 i++;
01411 }
01412
01413 while(isdigit(stabstr[cnt+i]))
01414 i++;
01415
01416 char *hi = (char *)malloc(sizeof(char)*(i+1));
01417 if(!strncpy(hi, &(stabstr[cnt]), i))
01418
01419 exit(1);
01420 hi[i] = '\0';
01421
01422 std::string tname = convertCharToString(name);
01423 if ( j <= 0 )
01424 {
01425
01426
01427
01428
01429 errno = 0;
01430 long low_conv = strtol(low, NULL, 10);
01431 if (errno)
01432 {
01433
01434
01435 low_conv = LONG_MIN;
01436 }
01437
01438 if (low_conv < LONG_MIN)
01439 {
01440 fprintf(stderr, "%s[%d]: signed variable saturation...\n", FILE__, __LINE__);
01441 low_conv = LONG_MIN;
01442 }
01443
01444 errno = 0;
01445 long hi_conv = strtol(hi, NULL, 10);
01446 if (errno)
01447 {
01448
01449
01450 hi_conv = LONG_MAX;
01451 }
01452
01453 if (hi_conv > LONG_MAX)
01454 {
01455 fprintf(stderr, "%s[%d]: signed variable saturation...\n", FILE__, __LINE__);
01456 hi_conv = LONG_MAX;
01457 }
01458
01459 if (baseType == NULL)
01460 {
01461 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : guessSize(low,hi),
01462 low_conv, hi_conv, tname);
01463 }
01464 else
01465 {
01466 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : baseType->getSize(),
01467 low_conv, hi_conv, tname);
01468 }
01469 newType = tc->addOrUpdateType((typeSubrange *) newType);
01470 }
01471 else if( j > 0)
01472 {
01473 j = atol(hi);
01474 if (j == 0)
01475 {
01476
01477 int size = (int)j;
01478
01479
01480
01481
01482 newType = new typeScalar(ID, size, convertCharToString(name));
01483
01484 newType = tc->addOrUpdateType((typeScalar *) newType);
01485 }
01486 else
01487 {
01488
01489
01490 errno = 0;
01491 long low_conv = strtol(low, NULL, 10);
01492 if (errno)
01493 {
01494 fprintf(stderr, "%s[%d]: error converting range limit '%s' to long: %s\n",
01495 FILE__, __LINE__, low, strerror(errno));
01496 low_conv = LONG_MIN;
01497 }
01498
01499 errno = 0;
01500 long hi_conv = strtol(hi, NULL, 10);
01501 if (errno)
01502 {
01503 fprintf(stderr, "%s[%d]: error converting range limit '%s' to long: %s\n",
01504 FILE__, __LINE__, hi, strerror(errno));
01505 hi_conv = LONG_MAX;
01506 }
01507
01508 if (baseType == NULL)
01509 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : sizeof(long),
01510 low_conv, hi_conv, tname);
01511 else
01512 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : baseType->getSize(),
01513 low_conv, hi_conv, tname);
01514 newType = tc->addOrUpdateType((typeSubrange *) newType);
01515 }
01516 }
01517 free(low);
01518 free(hi);
01519
01520 cnt = cnt + i;
01521 if( stabstr[cnt] == ';')
01522 cnt++;
01523
01524 return(&(stabstr[cnt]));
01525 }
01526
01527 #endif
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542 static char *parseAttrType(Module *mod, const char *name,
01543 int ID, char *stabstr, int &cnt)
01544 {
01545 assert(stabstr[cnt] == '@');
01546 cnt++;
01547
01548 if (stabstr[cnt] == 's') {
01549 cnt++;
01550
01551 int size = parseSymDesc(stabstr, cnt);
01552 cnt++;
01553
01554 char *newstr = parseTypeDef(mod, stabstr+cnt, name, ID, size);
01555 if (newstr[0] == ';')
01556 return newstr+1;
01557 else
01558 return newstr;
01559 } else {
01560
01561
01562 while (stabstr[cnt] != ';') cnt++;
01563 cnt++;
01564 return parseTypeDef(mod, stabstr+cnt, name, ID);
01565 }
01566 }
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653 // name,ID, &(stabstr[cnt]));
01654 }
01655 }
01656 */
01657
01658
01659
01660 static char *parseRefType(Module *mod, const char *name,
01661 int ID, char *stabstr, int &cnt)
01662 {
01663
01664 assert(stabstr[cnt] == '&');
01665 cnt++;
01666
01667 int refID = parseTypeUse(mod, stabstr, cnt, name);
01668
01669
01670 typeCollection *tc = typeCollection::getModTypeCollection(mod);
01671 Type *ptrType = tc->findOrCreateType(refID);
01672 if (!ptrType) ptrType = Symtab::type_Untyped().get();
01673 std::string tName = convertCharToString(name);
01674 typeRef *newType = new typeRef(ID, ptrType, tName);
01675
01676
01677 newType = tc->addOrUpdateType(newType);
01678
01679 return(&(stabstr[cnt]));
01680 }
01681
01682
01683
01684
01685 void addBaseClassToClass(Module *mod, int baseID,
01686 fieldListType *newType, int )
01687 {
01688
01689 typeCollection *tc = typeCollection::getModTypeCollection(mod);
01690
01691
01692 fieldListType *baseCl = dynamic_cast<fieldListType *>(tc->findType(baseID));
01693 if( ! baseCl ) {
01694 std::string modName = mod->fileName();
01695
01696 baseCl = new typeStruct(baseID);
01697 fieldListType *baseCl2 = dynamic_cast<typeStruct *>(tc->addOrUpdateType( (typeStruct *)baseCl ));
01698 std::string fName = "{superclass}";
01699 newType->addField( fName, baseCl2, -1, visUnknown );
01700 baseCl->decrRefCount();
01701 return;
01702 }
01703 std::string fName = "{superclass}";
01704 newType->addField( fName, baseCl, -1, visUnknown );
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718 }
01719
01720
01721
01722
01723
01724 static char *parseFieldList(Module *mod, fieldListType *newType,
01725 char *stabstr, bool sunCPlusPlus)
01726 {
01727 int cnt = 0;
01728 int size = 0;
01729 char *compname;
01730 int comptype= 0;
01731 int beg_offset=0;
01732 visibility_t _vis = visUnknown;
01733 dataClass typedescr;
01734 bool hasVirtuals = false;
01735 typeCollection *tc = typeCollection::getModTypeCollection(mod);
01736 assert(tc);
01737
01738 if (stabstr[cnt] == '!')
01739 {
01740
01741
01742
01743 cnt++;
01744
01745
01746 int baseClNum = atoi(getIdentifier(stabstr, cnt).c_str());
01747 cnt++;
01748
01749 typeStruct *newStructType = dynamic_cast<typeStruct *>(newType);
01750
01751 for (int i=0; i<baseClNum; ++i)
01752 {
01753
01754 getIdentifier(stabstr, cnt);
01755 cnt++;
01756
01757
01758 int baseID = parseSymDesc(stabstr, cnt);
01759
01760 cnt++;
01761
01762 addBaseClassToClass(mod, baseID, newStructType, 0);
01763 }
01764 }
01765
01766 while (stabstr[cnt] && (stabstr[cnt] != ';'))
01767 {
01768 typedescr = dataScalar;
01769
01770 if (stabstr[cnt] == '~')
01771 {
01772
01773 while (stabstr[cnt] != ';') cnt++;
01774 break;
01775 }
01776
01777
01778 if (sunCPlusPlus) cnt += 3;
01779
01780 if ((stabstr[cnt] == 'u') && (stabstr[cnt+1] == ':') && (!isdigit(stabstr[cnt+2])))
01781 {
01782 cnt += 2;
01783 }
01784
01785 compname = getFieldName(stabstr, cnt);
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795 cnt++;
01796
01797 if ((stabstr[cnt]) == ':')
01798 {
01799
01800 typedescr = dataFunction;
01801 cnt++;
01802 }
01803
01804 if ((stabstr[cnt]) == '/')
01805 {
01806 cnt++;
01807 switch (stabstr[cnt]) {
01808 case '0':
01809 _vis = visPrivate;
01810 break;
01811 case '1':
01812 _vis = visProtected;
01813 break;
01814 case '2':
01815 _vis = visPublic;
01816 break;
01817 default:
01818 _vis = visUnknown;
01819 }
01820 cnt++;
01821 }
01822
01823
01824 comptype = parseTypeUse(mod, stabstr, cnt, "");
01825
01826 if (stabstr[cnt] == ':')
01827 {
01828 while (stabstr[cnt] == ':')
01829 {
01830 cnt++;
01831 beg_offset = 0;
01832 size = 0;
01833 std::string varName = getIdentifier(stabstr, cnt);
01834
01835 if (typedescr == dataFunction)
01836 {
01837
01838 cnt++;
01839 cnt++;
01840 cnt++;
01841 if (stabstr[cnt] == '*')
01842 {
01843
01844 hasVirtuals = true;
01845 cnt++;
01846 while(stabstr[cnt] != ';') cnt++;
01847 cnt++;
01848 if (stabstr[cnt] != ';')
01849 {
01850 parseTypeUse(mod, stabstr, cnt, "");
01851 }
01852 cnt++;
01853 if (isSymId(stabstr[cnt]))
01854 {
01855 parseTypeUse(mod, stabstr, cnt, "");
01856 }
01857 } else if ( (stabstr[cnt] == '.')
01858 || (stabstr[cnt] == '?') )
01859 {
01860 cnt++;
01861 if (isSymId(stabstr[cnt]))
01862 {
01863 parseTypeUse(mod, stabstr, cnt, "");
01864 }
01865 }
01866 }
01867
01868 if (stabstr[cnt] == ';')
01869 cnt++;
01870 }
01871 }
01872 else if (stabstr[cnt] == ',')
01873 {
01874 cnt++;
01875 beg_offset = parseSymDesc(stabstr, cnt);
01876
01877 if (stabstr[cnt] == ',')
01878 {
01879 cnt++;
01880 size = parseSymDesc(stabstr, cnt);
01881 }
01882 else
01883 size = 0;
01884 }
01885
01886 if (stabstr[cnt] == ';')
01887 cnt++;
01888
01889
01890
01891
01892 Type *fieldType = tc->findOrCreateType( comptype );
01893 if (fieldType == NULL)
01894 {
01895
01896
01897 fieldType = tc->findType("void");
01898 }
01899 std::string fName = convertCharToString(compname);
01900 if (_vis == visUnknown)
01901 {
01902 newType->addField(fName, fieldType, beg_offset);
01903 }
01904 else
01905 {
01906
01907 newType->addField(fName, fieldType, beg_offset, _vis);
01908
01909 }
01910 free(compname);
01911 }
01912
01913 if (hasVirtuals &&
01914 stabstr[cnt] == ';' &&
01915 stabstr[cnt+1] == '~' &&
01916 stabstr[cnt+2] == '%')
01917 {
01918 cnt+=3;
01919 while (stabstr[cnt] != ';') cnt++;
01920 }
01921
01922
01923 if (stabstr[cnt] == ';')
01924 {
01925 return &stabstr[cnt+1];
01926 }
01927 else if (stabstr[cnt] == '\0')
01928 {
01929 return &stabstr[cnt];
01930 }
01931 else
01932 {
01933
01934 abort();
01935 return NULL;
01936 }
01937 }
01938
01939
01940
01941
01942
01943
01944
01945 static char *parseCPlusPlusInfo(Module *mod,
01946 char *stabstr, const char *mangledName, int ID)
01947 {
01948 typeCollection *tc = typeCollection::getModTypeCollection(mod);
01949 int cnt;
01950 char *name;
01951 int structsize;
01952 bool sunStyle = true;
01953 bool nestedType = false;
01954 dataClass typdescr;
01955 fieldListType * newType = NULL, *newType2 = NULL;
01956
01957 assert(stabstr[0] == 'Y');
01958 cnt = 1;
01959
01960
01961 if (isdigit(stabstr[cnt])) {
01962 structsize = parseSymDesc(stabstr, cnt);
01963 sunStyle = false;
01964 }
01965
01966 switch(stabstr[cnt]) {
01967 case 'C':
01968 case 'c':
01969 typdescr = dataTypeClass;
01970 break;
01971
01972 case 'S':
01973 nestedType = true;
01974 case 's':
01975 typdescr = dataStructure;
01976 break;
01977
01978 case 'U':
01979 nestedType = true;
01980 case 'u':
01981 typdescr = dataUnion;
01982 break;
01983
01984 case 'n':
01985 cnt = strlen(stabstr);
01986 return(&(stabstr[cnt]));
01987 break;
01988
01989 default:
01990
01991 cnt = strlen(stabstr);
01992 return(&(stabstr[cnt]));
01993 break;
01994 }
01995
01996 cnt++;
01997 if (isdigit(stabstr[cnt])) {
01998 structsize = parseSymDesc(stabstr, cnt);
01999 }
02000
02001 if (stabstr[cnt] == 'V') cnt++;
02002 if (stabstr[cnt] == '(') cnt++;
02003
02004 if (sunStyle && (stabstr[cnt] != ';')) {
02005 int len;
02006 char *n;
02007
02008
02009 n = &stabstr[cnt];
02010 while (stabstr[cnt] != ';') cnt++;
02011 len = &stabstr[cnt] - n;
02012 name = (char *) calloc(len + 1, sizeof(char));
02013 strncpy(name, n, len);
02014 } else {
02015 name = const_cast< char * >( mangledName );
02016 }
02017
02018 std::string tName = convertCharToString(name);
02019
02020 switch (typdescr) {
02021 case dataTypeClass:
02022 case dataStructure:
02023 newType = new typeStruct(ID, tName);
02024 newType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeStruct *) newType));
02025 break;
02026 case dataUnion:
02027 newType = new typeUnion(ID, tName);
02028 newType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeUnion *) newType));
02029 break;
02030 default:
02031 assert(0);
02032 }
02033
02034
02035 if(newType2 != newType)
02036 newType->decrRefCount();
02037
02038 if (sunStyle) {
02039 cnt++;
02040
02041 while (stabstr[cnt] != ';') {
02042
02043 cnt++;
02044
02045 int offset = parseSymDesc(stabstr, cnt);
02046
02047
02048 int baseID = parseSymDesc(stabstr, cnt);
02049 addBaseClassToClass(mod, baseID, newType2, offset);
02050 }
02051
02052 cnt++;
02053 }
02054
02055
02056 stabstr = parseFieldList(mod, newType2, &stabstr[cnt], sunStyle);
02057 cnt = 0;
02058
02059 if (stabstr[0]) {
02060
02061 cnt++;
02062 while (stabstr[cnt] && (stabstr[cnt] != ';')) {
02063 std::string pd_funcName = getIdentifier(stabstr, cnt, true);
02064 const char *funcName = pd_funcName.c_str();
02065
02066 funcName++;
02067
02068 if (*funcName == '-') funcName++;
02069
02070 while (isdigit(*funcName)) funcName++;
02071 funcName++;
02072
02073 char *className = strdup(currentRawSymbolName.c_str());
02074 className[3] = 'c';
02075 className[strlen(className)-1] = '\0';
02076 std::string methodName = std::string(className) + std::string(funcName) + std::string("_");
02077 char * name = P_cplus_demangle( methodName.c_str(), mod->exec()->isNativeCompiler() );
02078 if( name != NULL ) {
02079 funcName = strrchr( name, ':' );
02080 if( funcName ) { funcName++; }
02081 else { funcName = name; }
02082 }
02083
02084
02085 Type *fieldType = tc->findType("void");
02086
02087 std::string fName = convertCharToString(funcName);
02088
02089 typeFunction *funcType = new typeFunction( ID, fieldType, fName);
02090 newType2->addField( fName, funcType);
02091
02092 free(name);
02093 free(className);
02094 if (stabstr[cnt] == ' ') cnt++;
02095 }
02096 }
02097
02098 cnt = strlen(stabstr);
02099 return(&(stabstr[cnt]));
02100 }
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127 static char *parseTypeDef(Module *mod, char *stabstr,
02128 const char *name, int ID, unsigned int sizeHint)
02129 {
02130 typeCollection *tc = typeCollection::getModTypeCollection(mod);
02131 Type * newType = NULL;
02132 fieldListType * newFieldType = NULL, *newFieldType2 = NULL;
02133 Type * ptrType = NULL;
02134
02135 std::string compsymdesc;
02136
02137 dataClass typdescr;
02138 int ptrID=0;
02139
02140 int value;
02141 int cnt,i,j,k;
02142 int structsize;
02143 int type;
02144 cnt = i = j = k = 0;
02145
02146 assert (stabstr[0] != '=');
02147
02148
02149 if (isSymId(stabstr[0]))
02150 {
02151 typdescr = dataScalar;
02152 type = parseSymDesc(stabstr, cnt);
02153
02154 if (ID == type)
02155 {
02156
02157
02158
02159
02160 std::string tName = convertCharToString(name);
02161 newType = new typeScalar(ID, 0, tName);
02162 newType = tc->addOrUpdateType((typeScalar *) newType);
02163 }
02164 else if (stabstr[cnt] == '=')
02165 {
02166
02167
02168 stabstr = parseTypeDef(mod, &(stabstr[cnt+i+1]), name, type);
02169 cnt = 0;
02170 Type *oldType;
02171
02172 oldType = tc->findOrCreateType(type);
02173 if (!oldType) oldType = Symtab::type_Untyped().get();
02174 std::string tName = convertCharToString(name);
02175 newType = new typeTypedef(ID, oldType, tName, sizeHint);
02176 tc->addOrUpdateType((typeTypedef *) newType);
02177
02178 }
02179 else
02180 {
02181 Type *oldType;
02182 std::string tName = convertCharToString(name);
02183 oldType = tc->findOrCreateType(type);
02184 newType = new typeTypedef(ID, oldType, tName, sizeHint);
02185 newType = tc->addOrUpdateType((typeTypedef *) newType);
02186 }
02187 } else {
02188 switch (stabstr[0]) {
02189 case 'x':
02190 {
02191 parseCrossRef(tc, name, ID, stabstr, cnt);
02192 break;
02193 }
02194 case '*':
02195 {
02196
02197 cnt++;
02198 ptrID = parseTypeUse(mod, stabstr, cnt, NULL);
02199
02200
02201 ptrType = tc->findOrCreateType(ptrID);
02202 if (!ptrType) ptrType = Symtab::type_Untyped().get();
02203
02204 newType = new typePointer(ID, ptrType);
02205
02206 newType = tc->addOrUpdateType((typePointer *) newType);
02207 return(&(stabstr[cnt]));
02208 break;
02209 }
02210 case 'a':
02211 case 'A':
02212 {
02213 (void) parseArrayDef(mod, name, ID, stabstr, cnt, sizeHint);
02214 return (&stabstr[cnt]);
02215 break;
02216 }
02217 case 'g':
02218 {
02219
02220
02221
02222 typdescr = dataFunction;
02223
02224 cnt++;
02225 type = parseTypeUse(mod, stabstr, cnt, name);
02226 ptrType = tc->findOrCreateType(type);
02227
02228 {
02229 std::string tName = convertCharToString(name);
02230 typeFunction *newFunction =
02231 new typeFunction(ID, ptrType, tName);
02232 typeFunction *newFunction2 = NULL;
02233
02234 if (newFunction) {
02235 newFunction2 = dynamic_cast<typeFunction*>(tc->addOrUpdateType(newFunction));
02236 if(newFunction2 != newFunction)
02237 newFunction->decrRefCount();
02238 }
02239 if (!newFunction2) {
02240
02241 types_printf("%s[%d]: parseTypeDef: unable to allocate newType\n", FILE__, __LINE__);
02242
02243 }
02244
02245 while ((stabstr[cnt] != '#') && (stabstr[cnt])) {
02246 int paramType;
02247 paramType = parseTypeUse(mod, stabstr, cnt, name);
02248 newType = tc->findOrCreateType(paramType);
02249 newFunction2->addParam(newType);
02250
02251 }
02252 }
02253
02254
02255 if (stabstr[cnt] == '#') cnt++;
02256 break;
02257 }
02258 case 'f':
02259 {
02260
02261 typdescr = dataFunction;
02262
02263 cnt++;
02264 type = parseTypeUse(mod, stabstr, cnt, name);
02265 ptrType = tc->findOrCreateType(type);
02266
02267
02268 std::string tName = convertCharToString(name);
02269 newType = new typeFunction(ID, ptrType, tName);
02270 newType = tc->addOrUpdateType((typeFunction *) newType);
02271
02272
02273
02274 break;
02275 }
02276
02277 case 'M':
02278 {
02279
02280 cnt++;
02281
02282 int baseType = parseSymDesc(stabstr, cnt);
02283 if (baseType != -2 || (stabstr[cnt] != ';')) {
02284
02285 } else {
02286 cnt++;
02287 int size;
02288 if (stabstr[cnt] == 'T') {
02289
02290 size = 0;
02291 cnt++;
02292 (void) parseSymDesc(stabstr, cnt);
02293 } else if (stabstr[cnt] == 'J') {
02294
02295 size = 0;
02296 cnt++;
02297 (void) parseSymDesc(stabstr, cnt);
02298 } else
02299 size = parseSymDesc(stabstr, cnt);
02300
02301 ptrType = tc->findOrCreateType(baseType);
02302 std::string tName = convertCharToString(name);
02303
02304 Type *newAType = new typeArray(ID, ptrType, 1, size, tName);
02305 newType = tc->addOrUpdateType((typeArray* ) newAType);
02306 }
02307 break;
02308
02309 }
02310 case 'R':
02311 {
02312
02313 cnt++;
02314 (void) parseSymDesc(stabstr, cnt);
02315 cnt ++;
02316
02317 int bytes = parseSymDesc(stabstr, cnt);
02318
02319 newType = new typeScalar(ID, bytes, name);
02320 newType = tc->addOrUpdateType((typeScalar *) newType);
02321
02322 if (stabstr[cnt] == ';') cnt++;
02323
02324
02325 if (stabstr[cnt] == '0') cnt += 2;
02326
02327 break;
02328 }
02329
02330 case 'b':
02331 {
02332
02333 int limit = strlen(&stabstr[cnt]);
02334
02335
02336 while (!isdigit(stabstr[cnt+i]) && (i < limit)) i++;
02337 if (i >= limit) return(&(stabstr[cnt]));
02338
02339 cnt += i;
02340 int size = parseSymDesc(stabstr,cnt);
02341 cnt -= i;
02342 i++;
02343
02344
02345 while (stabstr[cnt+i] != ';' && (i < limit)) i++;
02346 if (i >= limit) return(&(stabstr[cnt]));
02347 i++;
02348
02349 cnt += i;
02350 parseSymDesc(stabstr, cnt);
02351
02352 if (stabstr[cnt]) cnt++;
02353
02354 newType = new typeScalar(ID, size, name);
02355
02356 newType = tc->addOrUpdateType((typeScalar *) newType);
02357
02358 return &stabstr[cnt];
02359 break;
02360 }
02361 case 'r':
02362 {
02363 return parseRangeType(mod, name, ID, stabstr, sizeHint);
02364 break;
02365 }
02366 case 'e':
02367 {
02368 cnt++;
02369
02370
02371 std::string tName = convertCharToString(name);
02372 typeEnum *newEnumType = new typeEnum(ID, tName);
02373
02374 newEnumType = dynamic_cast<typeEnum *>(tc->addOrUpdateType(newEnumType));
02375
02376 while (stabstr[cnt]) {
02377
02378 compsymdesc = getIdentifier(stabstr, cnt);
02379 cnt++;
02380
02381 #ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
02382
02383
02384 #endif
02385 value = parseSymDesc(stabstr, cnt);
02386
02387
02388 newEnumType->addConstant(compsymdesc, value);
02389
02390 cnt++;
02391 if ((stabstr[cnt]) == ';') cnt++;
02392 }
02393 break;
02394 }
02395 case '@':
02396 {
02397 return parseAttrType(mod, name, ID, stabstr, cnt);
02398 break;
02399 }
02400 case '&':
02401 {
02402 return parseRefType(mod, name, ID, stabstr, cnt);
02403 break;
02404 }
02405 case 'k':
02406 {
02407 return parseTypeDef(mod, &stabstr[cnt+1], name, ID);
02408 break;
02409 }
02410 case 'V':
02411 case 'B':
02412 return parseTypeDef(mod, &stabstr[cnt+1], name, ID);
02413 break;
02414
02415 case 's':
02416 case 'u':
02417 case 'T':
02418 {
02419
02420 if (stabstr[cnt] == 's' || stabstr[cnt] == 'T') {
02421 typdescr = dataStructure;
02422 } else {
02423 typdescr = dataUnion;
02424 }
02425
02426 cnt++;
02427 structsize = parseSymDesc(stabstr, cnt);
02428
02429 std::string tName = convertCharToString(name);
02430
02431 if (typdescr == dataStructure) {
02432 newFieldType = new typeStruct(ID, tName);
02433 newFieldType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeStruct *) newFieldType));
02434 }
02435 else {
02436 newFieldType = new typeUnion(ID, tName);
02437 newFieldType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeUnion *) newFieldType));
02438 }
02439
02440
02441
02442 if(!newFieldType2)
02443 newFieldType2 = dynamic_cast<fieldListType *>(newFieldType);
02444 if(newFieldType2 != newFieldType)
02445 newFieldType->decrRefCount();
02446 char *ret = parseFieldList(mod, newFieldType2, &stabstr[cnt], false);
02447 return ret;
02448
02449 break;
02450 }
02451 case 'Y':
02452 {
02453
02454 return parseCPlusPlusInfo(mod, stabstr, name, ID);
02455 break;
02456 }
02457 case 'Z':
02458 {
02459 return (&stabstr[1]);
02460 break;
02461 }
02462 case '#':
02463 {
02464
02465 cnt++;
02466 if (stabstr[cnt] == '#') {
02467
02468 cnt++;
02469 parseTypeUse(mod, stabstr, cnt, name);
02470 }
02471 else {
02472 while(1) {
02473
02474 parseTypeUse(mod, stabstr, cnt, name);
02475 if (stabstr[cnt] == ',')
02476 cnt++;
02477 else if (stabstr[cnt] == ';')
02478 break;
02479 }
02480 }
02481
02482 cnt++;
02483 return(&(stabstr[cnt]));
02484 break;
02485 }
02486 default:
02487
02488
02489
02490 cnt = strlen(stabstr);
02491 break;
02492 }
02493 }
02494
02495 return(&(stabstr[cnt]));
02496 }
02497
02498
02499
02500
02501
02502
02503
02504
02505 static Type *parseConstantUse(Module *mod, char *stabstr, int &cnt)
02506 {
02507 typeCollection *tc = typeCollection::getModTypeCollection(mod);
02508
02509 cnt++;
02510
02511 Type *ret;
02512
02513 if (stabstr[cnt] == 'i') {
02514 ret = tc->findType("integer*4");
02515 } else if (stabstr[cnt] == 'r') {
02516 ret = tc->findType("double");
02517 } else if (stabstr[cnt] == 's') {
02518 ret = tc->findType("char *");
02519 } else {
02520
02521 ret = NULL;
02522 }
02523
02524 cnt = strlen(stabstr);
02525
02526 return ret;
02527 }
02528