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