cplusDemStub.c
上传用户:baixin
上传日期:2008-03-13
资源大小:4795k
文件大小:9k
开发平台:

MultiPlatform

  1. /* cplusDemStub.c - C++ symbol demangler stub */
  2. /* Copyright 1998 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01g,13mar02,sn   SPR 74275 - allow demangler to be decoupled from target shell
  8. 01f,21jan02,sn   changed to C file to avoid C++ being pulled in by timexShow
  9. 01e,12dec01,jab  added coldfire to PREPENDS_UNDERSCORE list
  10. 01d,04dec01,sn   moved PREPENDS_UNDERSCORE here
  11. 01c,30oct01,sn   got building with Diab
  12. 01b,12jun98,sn   moved function symbolStartOf from cplusDem.cpp to here.
  13. 01a,10apr98,sn   written.
  14. */
  15. /*
  16. DESCRIPTION
  17. This module seperates the interface of cplusDemangle from its implementation
  18. in cplusDem.cpp. 
  19. Many "show" routines such as timexShowCalls attempt to present demangled 
  20. symbol names to the user  by calling cplusDemangle. If
  21. C++ is not configured into vxWorks the correct behaviour
  22. is simply to return the mangled name. We have seperated out a "stub"
  23. of cplusDemangle from its body (_cplusDemangle) to avoid dragging in the 
  24. entire C++ runtime with any vxWorks image that contains show routines. 
  25. NOMANUAL
  26. */
  27. /* includes */
  28. #include "vxWorks.h"
  29. #include "cplusLib.h"
  30. #include "stdio.h"
  31. #include "stdlib.h"
  32. /* defines */
  33. /* PREPENDS_UNDERSCORE should be 1 if the compiler prepends an underscore 
  34.  * to symbol names; otherwise 0.
  35.  */
  36. #if (CPU_FAMILY==SPARC || 
  37.      CPU_FAMILY==I960 || 
  38.      CPU_FAMILY==MC680X0 || 
  39.      CPU_FAMILY==SIMSPARCSUNOS || 
  40.      CPU_FAMILY==SIMNT || 
  41.      CPU_FAMILY==COLDFIRE)
  42. #define PREPENDS_UNDERSCORE 1
  43. #else
  44. #define PREPENDS_UNDERSCORE 0
  45. #endif
  46. #define MAX_OVERLOAD_SYMS 50
  47. /* typedefs */
  48. /* globals */
  49. CPLUS_DEMANGLER_MODES cplusDemanglerMode = COMPLETE;
  50. DEMANGLER_STYLE cplusDemanglerStyle;
  51. char * (*cplusDemangleFunc) (char *, char *, int) = 0;
  52. /* locals */
  53. LOCAL char * overloadMatches [MAX_OVERLOAD_SYMS];
  54. LOCAL int overloadMatchCount;
  55. LOCAL BOOL findMatches
  56.     (
  57.     char *name,
  58.     int,
  59.     SYM_TYPE,
  60.     int string
  61.     );
  62. LOCAL const char * startsWith
  63.     (
  64.     const char * string,
  65.     const char * isubstr
  66.     );
  67. /* forward declarations */
  68. /******************************************************************************
  69. *
  70. * cplusDemanglerSet - change C++ demangling mode (C++)
  71. *
  72. * This command sets the C++ demangling mode to <mode>.
  73. * The default mode is 2.
  74. *
  75. * There are three demangling modes, <complete>, <terse>, and <off>.
  76. * These modes are represented by numeric codes:
  77. *
  78. * .TS
  79. * center,tab(|);
  80. * lf3 lf3
  81. * l l.
  82. * Mode     | Code
  83. * _
  84. * off      | 0
  85. * terse    | 1
  86. * complete | 2
  87. * .TE
  88. *
  89. * In complete mode, when C++ function names are printed, the class
  90. * name (if any) is prefixed and the function's parameter type list
  91. * is appended.
  92. *
  93. * In terse mode, only the function name is printed. The class name
  94. * and parameter type list are omitted.
  95. *
  96. * In off mode, the function name is not demangled.
  97. *
  98. * EXAMPLES
  99. * The following example shows how one function name would be printed
  100. * under each demangling mode:
  101. *
  102. * .TS
  103. * center,tab(|);
  104. * lf3 lf3
  105. * l l.
  106. * Mode     | Printed symbol
  107. * _
  108. * off      | _member_^_5classFPFl_PvPFPv_v
  109. * terse    | _member
  110. * complete | foo::_member(void* (*)(long),void (*)(void*))
  111. * .TE
  112. *
  113. * RETURNS: N/A
  114. */
  115. void cplusDemanglerSet
  116.     (
  117.     int mode
  118.     )
  119.     {
  120.     cplusDemanglerMode = (CPLUS_DEMANGLER_MODES) mode;
  121.     }
  122. /*******************************************************************************
  123. *
  124. * cplusDemanglerStyleSet - change C++ demangling style (C++)
  125. *
  126. * This command sets the C++ demangling mode to <style>.
  127. * The default demangling style depends on the toolchain
  128. * used to build the kernel. For example if the Diab
  129. * toolchain is used to build the kernel then the default
  130. * demangler style is DMGL_STYLE_DIAB.
  131. *
  132. * RETURNS: N/A
  133. */
  134. void cplusDemanglerStyleSet
  135.     (          
  136.     DEMANGLER_STYLE style
  137.     )          
  138.     {
  139.     cplusDemanglerStyle = style;
  140.     }
  141. /*******************************************************************************
  142. *
  143. * symbolStartOf - skip leading underscore
  144. *
  145. * RETURNS: pointer to the start of the symbol name after any compiler 
  146. *          prepended leading underscore.
  147. *        
  148. *
  149. * NOMANUAL
  150. */
  151. LOCAL char *symbolStartOf (
  152.   char *str
  153.   )
  154. {
  155.     if (PREPENDS_UNDERSCORE && (str [0] == '_'))
  156.         return str + 1;
  157.     else
  158.         return str;
  159. }
  160. /******************************************************************************
  161. *
  162. * cplusDemangle - demangle symbol
  163. *
  164. * This function takes a symbol (source), removes any compiler prepended 
  165. * underscore, and then attempts to demangle it. If demangling succeeds
  166. * the (first n chars of) the demangled string are placed in dest [] and
  167. * a pointer to dest is returned. Otherwise a pointer to the start of
  168. * the symbol proper (after any compiler prepended underscore) is returned.
  169. * RETURNS:
  170. * A pointer to a human readable version of source.
  171. *
  172. * NOMANUAL
  173. */
  174. char * cplusDemangle
  175.     (
  176.     char * source, /* mangled name */
  177.     char * dest, /* buffer for demangled copy */
  178.     int   n /* maximum length of copy */
  179.     )
  180.     {
  181.     source = symbolStartOf (source);
  182.     if (cplusDemangleFunc == 0  )
  183. {
  184. return source;
  185. }
  186.     else
  187. {
  188.         return cplusDemangleFunc (source, dest, n);
  189. }
  190.     }
  191. /*******************************************************************************
  192. *
  193. * askUser - ask user to choose among overloaded name alternatives
  194. *
  195. * This routine is used by cplusMatchMangled when a name is overloaded.
  196. *
  197. * RETURNS:
  198. * index into overloadMatches, or negative if no symbol is selected
  199. *
  200. * NOMANUAL
  201. */
  202. LOCAL int askUser
  203.     (
  204.     char *name
  205.     )
  206.     {
  207.     CPLUS_DEMANGLER_MODES   savedMode;
  208.     char   demangled [MAX_SYS_SYM_LEN + 1];
  209.     char   userInput [10];
  210.     const char  * nameToPrint;
  211.     int   choice;
  212.     int   i;
  213.     savedMode = cplusDemanglerMode;
  214.     cplusDemanglerMode = COMPLETE;
  215.     do
  216. {
  217. printf (""%s" is overloaded - Please select:n", name);
  218. for (i = 0; i < overloadMatchCount; i++)
  219.     {
  220.     nameToPrint = cplusDemangle (overloadMatches [i], demangled,
  221.  MAX_SYS_SYM_LEN + 1);
  222.     printf ("  %3d: %sn", i+1, nameToPrint);
  223.     }
  224. printf ("Enter <number> to select, anything else to stop: ");
  225. fgets (userInput, 10, stdin);
  226. choice = atoi (userInput) - 1;
  227. }
  228.     while (choice >= overloadMatchCount);
  229.     cplusDemanglerMode = savedMode;
  230.     return choice;
  231.     }
  232. /*******************************************************************************
  233. *
  234. * cplusMatchMangled - match string against mangled symbol table entries
  235. *
  236. * This function seeks a partial match between the given <string> and
  237. * symbols in the given <symTab>. If <string> matches one symbol, that
  238. * symbol's value and type are copied to <pValue> and <pType>. If <string>
  239. * matches multiple symbols, the shell user is prompted to disambiguate
  240. * her choice among the various alternatives.
  241. *
  242. * RETURNS: TRUE if a unique match is resolved, otherwise FALSE.
  243. *
  244. * NOMANUAL
  245. */
  246. BOOL cplusMatchMangled
  247.     (
  248.     SYMTAB_ID symTab, /* symbol table to search */
  249.     char *string, /* goal string */
  250.     SYM_TYPE *pType, /* type of matched symbol */
  251.     int *pValue /* value of matched symbol */
  252.     )
  253.     {
  254.     int userChoice;
  255.     
  256.     overloadMatchCount = 0;
  257.     symEach (symTab, (FUNCPTR) findMatches, (int) string);
  258.     switch (overloadMatchCount)
  259. {
  260.     case 0:
  261. return FALSE;
  262.     case 1:
  263. return (symFindByName (symTab, overloadMatches[0],
  264.        (char **) pValue, pType)
  265. == OK);
  266.     default:
  267. userChoice = askUser (string);
  268. if (userChoice >= 0)
  269.     {
  270.     return (symFindByName (symTab, overloadMatches [userChoice],
  271.    (char **)pValue, pType)
  272.     == OK);
  273.     }
  274. else
  275.     {
  276.     return FALSE;
  277.     }
  278. }
  279.     }
  280. /*******************************************************************************
  281. *
  282. * findMatches - find (possibly overloaded) symbols that match goal string
  283. *
  284. * This function is used by cplusMatchMangled. A match occurs when
  285. * <goalString> is an initial substring of <name> and the occurrence
  286. * of <goalString> is followed in <name> by "__", which is assumed
  287. * to be followed by the function's encoded signature.
  288. *
  289. * RETURNS: TRUE
  290. *
  291. * NOMANUAL
  292. */
  293. LOCAL BOOL findMatches
  294.     (
  295.     char *name,
  296.     int dummy1,
  297.     SYM_TYPE dummy2,
  298.     int string
  299.     )
  300.     {
  301.     const char *pMatch;
  302.     const char * goalString = (const char *) string;
  303.     if ((pMatch = startsWith (name + 1, goalString)) != 0
  304. &&
  305. (startsWith (pMatch + 1, "__") != 0))
  306.     {
  307.     if (overloadMatchCount < MAX_OVERLOAD_SYMS)
  308. {
  309. overloadMatches [overloadMatchCount++] = name;
  310. }
  311.             }
  312.     /* Check for symbol does not start with underscore */
  313.     else if ((pMatch = startsWith (name, goalString)) != 0
  314.      && 
  315.      (startsWith (pMatch + 1, "__") != 0))
  316.      {
  317.      if (overloadMatchCount < MAX_OVERLOAD_SYMS)
  318. {
  319. overloadMatches [overloadMatchCount++] = name;
  320. }
  321.      }
  322.     return TRUE;
  323.     }
  324. /*******************************************************************************
  325. *
  326. * startsWith - determine if <string> starts with <isubstr>
  327. *
  328. * RETURNS:
  329. * Pointer to final non-EOS character of <isubstr> where it occurs in <string>,
  330. * if <string> in fact starts with <isubstr>, otherwise 0.
  331. *
  332. * NOMANUAL
  333. */
  334. LOCAL const char * startsWith
  335.     (
  336.     const char * string,
  337.     const char * isubstr
  338.     )
  339.     {
  340.     if (*isubstr == EOS || *string == EOS)
  341. {
  342. return 0;
  343. }
  344.     for ( ; (*string == *isubstr); string++, isubstr++)
  345. {
  346. if (*isubstr == EOS)
  347.     {
  348.     return string - 1;
  349.     }
  350. }
  351.     if (*isubstr == EOS)
  352. {
  353. return string - 1;
  354. }
  355.     return 0;
  356.     }