00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 #include "src/common/shared.hpp"
00018 #include "src/common/string.hpp"
00019 #include "src/common/blist.hpp"
00020 #include "src/memory/memset.hpp"
00021 #include "src/memory/align.hpp"
00022 #include "src/memory/heap.hpp"
00023 #include "src/module/coresyms.hpp"
00024 #include "src/module/elf.hpp"
00025 #include "src/module/mangle.hpp"
00026 
00027 namespace Syms
00028 {
00029    namespace Mangle
00030    {
00031 
00032 
00033       
00034       int demangle (char *name, class string * dest, uint32 * args)
00035       {
00036          int i;
00037          dest->done ();
00038          
00039          i = Cxx::demangle (name, dest, args);
00040          if (i == ESUCCESS)
00041             return ESUCCESS;
00042          
00043          i = C::demangle (name, dest, args);
00044          if (i == ESUCCESS)
00045             return ESUCCESS;
00046 
00047          
00048          return EFAIL;
00049       }
00050 
00051       namespace Cxx
00052       {
00053 
00054          
00055 
00056 
00057 #define isCipher(c)     ( ((c) >= '0') && ((c) <= '9') )
00058 
00059          int d_subst (char **name, string * dest, blist_t * li);        
00060          int d_type (char **name, string * dest, blist_t * li, struct data_type *dt);   
00061          int d_number (char **name, int *i, int *lgth); 
00062          int d_nestedname (char **t, string * dest, blist_t * li);      
00063          int d_sourcename (char **t, string * dest, blist_t * li);      
00064          int d_name (char **t, string * dest, blist_t * li, bool flag1);        
00065          int d_symb (char **t, string * dest, blist_t * li);    
00066          int d_check (char **t, char *tx);      
00067          int demangle (char *n, class string * dest, uint32 * args);    
00068 
00069          const int CXX_NULL = 0;        
00070          const int CXX_OTHER = 1;       
00071          const int CXX_VOID = 2;        
00072          const int CXX_WCHAR_T = 3;     
00073          const int CXX_BOOL = 4;        
00074          const int CXX_CHAR = 5;        
00075          const int CXX_SIGNED_CHAR = 6; 
00076          const int CXX_UNSIGNED_CHAR = 7;       
00077          const int CXX_SHORT = 8;       
00078          const int CXX_UNSIGNED_SHORT = 9;      
00079          const int CXX_INT = 10;        
00080          const int CXX_UNSIGNED_INT = 11;       
00081          const int CXX_LONG = 12;       
00082          const int CXX_UNSIGNED_LONG = 13;      
00083          const int CXX_LONG_LONG = 14;  
00084          const int CXX_UNSIGNED_LONG_LONG = 15; 
00085          const int CXX___INT128 = 16;   
00086          const int CXX_UNSIGNED___INT128 = 17;  
00087          const int CXX_FLOAT = 18;      
00088          const int CXX_DOUBLE = 19;     
00089          const int CXX_LONG_DOUBLE = 20;        
00090          const int CXX___FLOAT128 = 21; 
00091          const int CXX_ELLIPSIS = 22;   
00092          const int CXX_POINTER = 23;    
00093          
00094 
00095          struct data_type
00096          {
00097             uint32 size;        
00098             uint32 stack_size;  
00099             const char *name;
00100          };
00101 
00102 #define __MAX1(a,b)  ((a)>(b)?(a):(b))
00103 #define TYPE(name)              {sizeof(name),__MAX1((sizeof(name)),STACK_ALIGN), (#name)}
00104 
00105          struct data_type types[] = {
00106             {NULL, STACK_ALIGN, "type?"},
00107             {NULL, STACK_ALIGN, "n/a"},
00108             {NULL, NULL, "void"},
00109             TYPE (wchar_t),
00110             TYPE (bool),
00111             TYPE (char),
00112             TYPE (signed char),
00113             TYPE (unsigned char),
00114             TYPE (short),
00115             TYPE (unsigned short),
00116             TYPE (int),
00117             TYPE (unsigned int),
00118             TYPE (long),
00119             TYPE (unsigned long),
00120             TYPE (long long),
00121             TYPE (unsigned long long),
00122             {16, 16, "__int128"},       
00123             {16, 16, "unsigned __int128"},
00124             TYPE (float),       
00125             TYPE (double),
00126             TYPE (long double),
00127             {16, 16, "__float128"},     
00128             {4, 4, "ellipsis"}, 
00129             {STACK_ALIGN, STACK_ALIGN, "void*"}
00130             
00131             
00132 
00133 
00134          };
00135          
00136          
00137          
00138          
00139          
00140 
00141          
00142          int d_subst (char **name, string * dest, blist_t * li)
00143          {
00144             int i = 0;
00145             bool flag = false;
00146             if (**name != 'S')
00147                return EFAIL;
00148             
00149             while (*(++(*name)) != '_')
00150             {
00151                if (**name == '\0')
00152                   return EINVAL;
00153                flag = true;
00154                i *= 36; 
00155                if (isCipher (**name))
00156                   i += **name - '0';    
00157                else
00158                   i += **name - 'A' + 10;
00159             }
00160             (*name)++;
00161             if (flag)
00162                i++;     
00163             
00164             blist_s *item;
00165             for (item = li->head; item; item = item->next)
00166                if (i-- == 0)    
00167                {
00168                   dest->strncat (bli_dt (item, char *));
00169                   return ESUCCESS;
00170                }
00171             return EFAIL;
00172          }
00173 
00174          
00175          int d_type (char **name, string * dest, blist_t * li,
00176                data_type * dt)
00177          {
00178             int i = CXX_NULL;
00179             
00180             if (**name == 'P') {
00181                (*name)++;
00182                i = d_type (name, dest, li, dt);
00183                
00184                memmove (dt, &types[CXX_POINTER], sizeof (*dt));
00185                if (i == ESUCCESS)
00186                   dest->add_char ('*');
00187                return i;
00188             };
00189             
00190             switch (**name) {
00191                case 'v':
00192                   i = CXX_VOID;
00193                   break;
00194                case 'w':
00195                   i = CXX_WCHAR_T;
00196                   break;
00197                case 'b':
00198                   i = CXX_BOOL;
00199                   break;
00200                case 'c':
00201                   i = CXX_CHAR;
00202                   break;
00203                case 'a':
00204                   i = CXX_SIGNED_CHAR;
00205                   break;
00206                case 'h':
00207                   i = CXX_UNSIGNED_CHAR;
00208                   break;
00209                case 's':
00210                   i = CXX_SHORT;
00211                   break;
00212                case 't':
00213                   i = CXX_UNSIGNED_SHORT;
00214                   break;
00215                case 'i':
00216                   i = CXX_INT;
00217                   break;
00218                case 'j':
00219                   i = CXX_UNSIGNED_INT;
00220                   break;
00221                case 'l':
00222                   i = CXX_LONG;
00223                   break;
00224                case 'm':
00225                   i = CXX_UNSIGNED_LONG;
00226                   break;
00227                case 'x':
00228                   i = CXX_LONG_LONG;
00229                   break;
00230                case 'y':
00231                   i = CXX_UNSIGNED_LONG_LONG;
00232                   break;
00233                case 'n':
00234                   i = CXX___INT128;
00235                   break;        
00236                case 'o':
00237                   i = CXX_UNSIGNED___INT128;
00238                   break;
00239                case 'f':
00240                   i = CXX_FLOAT;
00241                   break;
00242                case 'd':
00243                   i = CXX_DOUBLE;
00244                   break;
00245                case 'e':
00246                   i = CXX_LONG_DOUBLE;
00247                   break;
00248                case 'g':
00249                   i = CXX___FLOAT128;
00250                   break;
00251                case 'z':
00252                   i = CXX_ELLIPSIS;
00253             };
00254             
00255             if (i != CXX_NULL) {
00256                (*name) += 1;
00257                dest->strncat (types[i].name);
00258                memmove (dt, &types[i], sizeof (*dt));
00259                return ESUCCESS;
00260             }
00261             
00262             if (**name == 'u')
00263                (*name)++;
00264             
00265             memmove (dt, &types[CXX_OTHER], sizeof (*dt));
00266             return d_name (name, dest, li, false);
00267          }
00268 
00269          
00270          int d_number (char **name, int *i, int *lgth)
00271          {
00272             char ch;
00273             *i = 0;
00274             *lgth = 0;
00275             while (isCipher (**name) && (**name)) {
00276                (*lgth)++;
00277                ch = **name;
00278                (*name)++;
00279                (*i) *= 10;
00280                (*i) += ch - '0';
00281             }
00282             return ESUCCESS;
00283          }
00284 
00285          
00286          int d_nestedname (char **t, string * dest, blist_t * li)
00287          {
00288             int i;
00289             uint32 t1;
00290             char c;
00291             t1 = dest->length ();
00292             (*t)++;
00293             do {
00294                c = **t;
00295                i = d_name (t, dest, li, true);
00296                if (c != 'S') {
00297                   li->add (dest->v () + t1, dest->length () - t1 + 1,
00298                         NULL);
00299                }
00300 
00301                
00302 
00303 
00304 
00305                
00306                if (**t == 'E') {
00307                   (*t)++;
00308                   return ESUCCESS;
00309                }
00310                dest->strncat ("::");
00311                if (i != ESUCCESS)
00312                   return EINVAL;
00313             }
00314             while (1);
00315 
00316          }
00317 
00318          
00319          int d_sourcename (char **t, string * dest, blist_t * li)
00320          {
00321             int j, i, n;
00322             char *t1;
00323             t1 = *t;
00324             
00325             if (!d_number (t, &i, &n))
00326                return EFAIL;
00327             
00328             n += i;             
00329             
00330             j = i;
00331             for (; i > 0; i--)
00332                dest->add_char (*((*t)++));
00333             
00334             if (li) {
00335                li->add (t1 + 1, lgth (t1) - 1   + 1, NULL);
00336             }
00337             return ESUCCESS;
00338          }
00339 
00340          
00341          int d_name (char **t, string * dest, blist_t * li, bool flag1)
00342          {
00343             
00344             if (**t == 'S')
00345                return d_subst (t, dest, li);
00346             
00347             if (**t == 'N')
00348                return d_nestedname (t, dest, li);
00349             
00350             if ((**t >= '1') && (**t <= '9')) {
00351                if (flag1)
00352                   li = NULL;
00353                return d_sourcename (t, dest, li);
00354             }
00355             
00356             bool flag2 = false;
00357             if (**t == 'C') {
00358                (*t)++;
00359                if ((**t < '1') || (**t > '3'))
00360                   return EINVAL;
00361                (*t)++;
00362                flag2 = true;
00363             }
00364             if (**t == 'D') {
00365                (*t)++;
00366                if ((**t < '0') || (**t > '2'))
00367                   return EINVAL;
00368                (*t)++;
00369                flag2 = true;
00370                dest->add_char ('~');
00371             }
00372             if (flag2) {
00373                
00374                char *c, *d;
00375                d = c = bli_dt (li->tail, char *);
00376                c += lgth (c);
00377                while ((c > d) && (*(c - 1) != ':'))
00378                   c--;
00379                
00380                while (*c)
00381                   dest->add_char (*(c++));
00382                return ESUCCESS;
00383             }
00384 
00385             return EFAIL;
00386          }
00387 
00388          
00389          int d_symb (char **t, string * dest, blist_t * li)
00390          {
00391             int i;
00392             
00393             i = d_name (t, dest, li, false);
00394             return i;
00395          }
00396 
00397          
00398          int d_check (char **t, const char *tx)
00399          {
00400             char *t1;
00401             t1 = *t;
00402             do {
00403                if (*tx == '\0') {
00404                   return ESUCCESS;
00405                }
00406             }
00407             while (*((*t)++) == *(tx++));
00408 
00409             return EFAIL;
00410          }
00411 
00412          
00413          int demangle (char *n, class string * dest, uint32 * args)
00414        {
00415           char *pos = n;
00416           blist_t frags;
00417           int i;
00418           string arg_list, num;
00419           memset (&arg_list, 0, sizeof (arg_list));
00420           memset (&num, 0, sizeof (num));
00421           
00422           frags.init (FAC_OTHER | FAC_MANGLE);
00423           arg_list.verify (1);
00424           
00425           do {
00426              
00427              i = d_check (&pos, "_Z");
00428              if (i != ESUCCESS)
00429                 break;
00430              
00431              i = d_symb (&pos, dest, &frags);
00432              
00433              int flag = 0;
00434              data_type last_type;       
00435              if (i == ESUCCESS)
00436                 while (*pos) {
00437                    if (flag == 0)
00438                       dest->add_char ('(');
00439                    if (flag > 0)
00440                       dest->strncat (", ");
00441                    
00442                    if (!args)
00443                       i = d_type (&pos, dest, &frags, &last_type);
00444                    else {
00445                       if ((*pos == 'v') && (*(pos + 1) == '\0'))        
00446                       {
00447                          dest->strncat ("void)");
00448                          i = ESUCCESS;
00449                          break;
00450                       }
00451                       
00452                       num.decim (flag + 1);
00453                       
00454                       dest->add_char ('A');
00455                       dest->strncat (num.v ());
00456                       
00457                       arg_list.strncat ("\n\t\tA");
00458                       arg_list.strncat (num.v ());
00459                       arg_list.strncat ("= (");
00460                       i = d_type (&pos, &arg_list, &frags,
00461                             &last_type);
00462                       arg_list.strncat (")\t");
00463                       arg_list.strncat ("0x");
00464                       
00465                       if (last_type.stack_size == 4)
00466                          num.hex (*args, '0');
00467                       else
00468                          num.num64 (*(uint64 *) args, 0x10,
00469                                0x1000000000000000ll, 1, '0',
00470                                0);
00471                       
00472                       args = (uint32 *) ((uint32) args + last_type.stack_size); 
00473                       arg_list.strncat (num.v ());
00474                    }
00475                    flag++;
00476                    if (i != ESUCCESS)
00477                       break;
00478                 }
00479              if (flag > 0)
00480                 dest->add_char (')');
00481           }
00482           while (0);
00483 
00484       
00485       if (args) {
00486          dest->strncat (arg_list.v ());
00487       }
00488       
00489       frags.done ();
00490       arg_list.done ();
00491       if (i == ESUCCESS) {
00492       } else
00493          dest->strncat ("n/a");
00494       return i;
00495        }
00496 
00497 
00498        };                       
00499 
00500        
00501        namespace C
00502        {
00503 
00504 
00505           
00506           int demangle (char *name, class string * dest, uint32 * args)
00507           {
00508              dest->copy (name);
00509              return ESUCCESS;
00510           }
00511 
00512 
00513 
00514         };                      
00515 
00516     };                          
00517 };                              
00518 
00519 
00520 
00521 
00522 
00523 
00524