A patch for cplus-dem.c
H.J. Lu
hjl@valinux.com
Sun Oct 10 16:08:00 GMT 1999
Here is my first patch for cplus-dem.c:
1. Rename the entry point from cplus_demangle to demangle_symbol.
2. Add init_demangler.
3. Add Ada/GNAT support.
4. Provide cplus_demangle () for backward compatibility.
If you don't want to use the new interface, nothing needs to be done.
You can use
s1 = demangle_symbol (name1);
s2 = demangle_symbol (name1);
It is equivalent to
s1 = cplus_demangle (name1, DMGL_ANSI | DMGL_PARAMS);
s2 = cplus_demangle (name2, DMGL_ANSI | DMGL_PARAMS);
init_demangler () can be used to control how a symbol is demangled
by demangle_symbol ().
I didn't rename the file. It will be in my followup patches. BTW, my
patch has some dlopen code, but it is not enabled. When -static is
used, you can build static binaries using cplus-dem.c only under
Linux since there are no dlopen/dlsym in the static library on
other platforms. I will come up with something in my followup patches.
BTW, I was told that the GNAT patch was from GNAT. Kenner may know more
about its copyright status.
Thanks.
--
H.J. Lu (hjl@gnu.org)
--
Sun Oct 10 15:48:07 1999 H.J. Lu (hjl@gnu.org)
* cplus-dem.c (usage): Modified -s/--format. Added
-d/--demangler.
(long_options): Add demangler.
(main): Handle 'd'. Use o_style () for setting
current_demangling_style. Call init_demangler ().
Sun Oct 10 10:46:41 1999 H.J. Lu (hjl@gnu.org)
* cplus-dem.c (demangle_symbol, demangle_symbol_with_options,
init_demangler): New prototypes.
Fri Oct 1 08:15:24 1999 H.J. Lu (hjl@gnu.org)
* cplus-dem.c (gnat_demangle): Renamed from ada_demangle.
(internal_ada_demangle): New.
(cplus_demangle): Call internal_ada_demangle instead of
ada_demangle.
Sun Feb 14 12:22:14 1999 H.J. Lu (hjl@gnu.org)
Based on patch from Juergen.Pfeifer@t-online.de (Juergen
Pfeifer) on Tue, 09 Feb 1999 22:54:07:
* cplus-dem.c (ada_demangle): New.
(cplus_demangle): Call ada_demangle () if options & DMGL_GNAT
is not zero.
Sat Oct 9 09:52:54 1999 H.J. Lu (hjl@gnu.org)
* demangle.h (DMGL_COMPAQ): New.
(demangling_styles): Add gnat_demangling and compaq_demangling.
(GNAT_DEMANGLING_STYLE_STRING, COMPAQ_DEMANGLING_STYLE_STRING):
New macros.
(demangle_symbol, demangle_symbol_with_options,
init_demangler): New prototypes.
Sun Feb 14 12:26:18 1999 H.J. Lu (hjl@gnu.org)
* demangle.h (DMGL_GNAT): New.
--- ../../import/egcs/libiberty/cplus-dem.c Sun Oct 10 09:08:14 1999
+++ libiberty/cplus-dem.c Sun Oct 10 09:21:29 1999
@@ -38,6 +38,10 @@ Boston, MA 02111-1307, USA. */
#include <string.h>
#include <stdio.h>
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
@@ -51,6 +55,13 @@ char * realloc ();
#include "libiberty.h"
+static char *internal_ada_demangle PARAMS ((const char*, int));
+static char *gnat_demangle PARAMS ((const char*));
+static int o_mnemonic PARAMS ((const char *mnemonic));
+static enum demangling_styles o_style PARAMS ((const char *style));
+static char *(*demangler_function) PARAMS ((const char *, int)) = NULL;
+static int demangler_options = DMGL_ANSI | DMGL_PARAMS;
+
#define min(X,Y) (((X) < (Y)) ? (X) : (Y))
extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
@@ -436,12 +447,6 @@ static void
recursively_demangle PARAMS ((struct work_stuff *, const char **, string *,
int));
-static const char *
-standard_symbol_characters PARAMS ((void));
-
-static const char *
-hp_symbol_characters PARAMS ((void));
-
/* Translate count to integer, consuming tokens in the process.
Conversion terminates on the first non-digit character.
@@ -785,6 +790,7 @@ cplus_demangle (mangled, options)
{
char *ret;
struct work_stuff work[1];
+
memset ((char *) work, 0, sizeof (work));
work -> options = options;
if ((work -> options & DMGL_STYLE_MASK) == 0)
@@ -795,6 +801,166 @@ cplus_demangle (mangled, options)
return (ret);
}
+static int
+o_mnemonic (mnemonic)
+ const char *mnemonic;
+{
+ if (strncasecmp (mnemonic, "PARAMS", sizeof ("PARAMS") - 1) == 0)
+ return DMGL_PARAMS;
+ else if (strncasecmp (mnemonic, "ANSI", sizeof ("ANSI") - 1) == 0)
+ return DMGL_ANSI;
+ else if (strncasecmp (mnemonic, "JAVA", sizeof ("JAVA") - 1) == 0)
+ return DMGL_JAVA;
+ else if (strncasecmp (mnemonic, "AUTO", sizeof ("AUTO") - 1) == 0)
+ return DMGL_AUTO;
+ else if (strncasecmp (mnemonic, "GNU", sizeof ("GNU") - 1) == 0)
+ return DMGL_GNU;
+ else if (strncasecmp (mnemonic, "LUCID", sizeof ("LUCID") - 1) == 0)
+ return DMGL_LUCID;
+ else if (strncasecmp (mnemonic, "ARM", sizeof ("ARM") - 1) == 0)
+ return DMGL_ARM;
+ else if (strncasecmp (mnemonic, "HP", sizeof ("HP") - 1) == 0)
+ return DMGL_HP;
+ else if (strncasecmp (mnemonic, "EDG", sizeof ("EDG") - 1) == 0)
+ return DMGL_EDG;
+ else if (strncasecmp (mnemonic, "GNAT", sizeof ("GNAT") - 1) == 0)
+ return DMGL_GNAT;
+ else if (strncasecmp (mnemonic, "COMPAQ", sizeof ("COMPAQ") - 1) == 0)
+ return DMGL_COMPAQ;
+ else
+ return DMGL_NO_OPTS;
+}
+
+static enum demangling_styles
+o_style (style)
+ const char *style;
+{
+ if (strcasecmp (style, "gnu") == 0)
+ return gnu_demangling;
+ else if (strcasecmp (style, "lucid") == 0)
+ return lucid_demangling;
+ else if (strcasecmp (style, "arm") == 0)
+ return arm_demangling;
+ else if (strcasecmp (style, "hp") == 0)
+ return hp_demangling;
+ else if (strcasecmp (style, "edg") == 0)
+ return edg_demangling;
+ else if (strcasecmp (style, "gnat") == 0)
+ return gnat_demangling;
+ else if (strcasecmp (style, "compaq") == 0)
+ return compaq_demangling;
+ return unknown_demangling;
+}
+
+int
+init_demangler (style, options, demangler)
+ const char *style;
+ const char *options;
+ const char *demangler;
+{
+#ifdef HAVE_DLFCN_H
+ char *dso = NULL;
+ char *function = NULL;
+#endif
+
+ if (style != NULL)
+ {
+ current_demangling_style = o_style (style);
+ if (current_demangling_style == unknown_demangling)
+ {
+ fprintf (stderr, "init_demangler: unknown demangling style `%s'\n",
+ style);
+ exit (1);
+ }
+ }
+
+ if (options == NULL)
+ demangler_options = DMGL_ANSI | DMGL_PARAMS;
+ else
+ {
+ const char *cp;
+
+ for (cp = options; *cp; )
+ {
+ if (*cp == ';')
+ cp++;
+ demangler_options |= o_mnemonic (cp);
+ while (*cp && *cp != ':')
+ cp++;
+ }
+ }
+
+#ifdef HAVE_DLFCN_H
+ if (demangler)
+ {
+ dso = alloca (strlen (demangler) + 1);
+ strcpy (dso, demangler);
+ function = strchr (dso, ':');
+ if (!function)
+ {
+ fprintf (stderr, "init_demangler: invalid `dso:function': `%s'\n",
+ demangler);
+ exit (1);
+ }
+ *function = '\0';
+ function++;
+ }
+
+ if (current_demangling_style == compaq_demangling)
+ {
+ if (dso == NULL || *dso == '\0')
+ dso = "compaq/libcompaq_demangle.so";
+ if (function == NULL)
+ function = "libiberty_demangle_string";
+ }
+
+ if (dso && function)
+ {
+ void *handle;
+
+ handle = dlopen (dso, RTLD_LAZY);
+ if (handle == NULL)
+ {
+ fprintf(stderr, "init_demangler: %s\n", dlerror ());
+ exit (1);
+ }
+
+ demangler_function = dlsym (handle, function);
+ if (demangler_function == NULL)
+ {
+ fprintf(stderr, "init_demangler: %s\n", dlerror ());
+ exit (1);
+ }
+ }
+ else
+#endif
+ if (current_demangling_style == gnat_demangling)
+ demangler_function = internal_ada_demangle;
+ else
+ demangler_function = cplus_demangle;
+
+ return 0;
+}
+
+char *
+demangle_symbol (mangled)
+ const char *mangled;
+{
+ return demangle_symbol_with_options (mangled, demangler_options);
+}
+
+char *
+demangle_symbol_with_options (mangled, options)
+ const char *mangled;
+ int options;
+{
+ if (demangler_function)
+ return (*demangler_function) (mangled, options);
+ if (options & DMGL_GNAT)
+ return internal_ada_demangle (mangled, options);
+ else
+ return cplus_demangle (mangled, options);
+}
/* This function performs most of what cplus_demangle use to do, but
to be able to demangle a name with a B, K or n code, we need to
@@ -4356,6 +4522,8 @@ static int flags = DMGL_PARAMS | DMGL_AN
static void demangle_it PARAMS ((char *));
static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
static void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN;
+static const char * standard_symbol_characters PARAMS ((void));
+static const char * hp_symbol_characters PARAMS ((void));
static void
demangle_it (mangled_name)
@@ -4381,9 +4549,10 @@ usage (stream, status)
int status;
{
fprintf (stream, "\
-Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
- [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
- [--help] [--version] [arg...]\n",
+Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg,gnat,compaq}] [--strip-underscores]\n\
+ [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg,gnat,compaq}]\n\
+ [-d dso:function] [--demangler=dso:function]\n\
+ [--help] [--version] [arg...]\n",
program_name);
exit (status);
}
@@ -4399,6 +4568,7 @@ int strip_underscore = 0;
static struct option long_options[] = {
{"strip-underscores", no_argument, 0, '_'},
{"format", required_argument, 0, 's'},
+ {"demangler", required_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
{"java", no_argument, 0, 'j'},
{"no-strip-underscores", no_argument, 0, 'n'},
@@ -4474,12 +4644,13 @@ main (argc, argv)
char *result;
int c;
const char *valid_symbols;
+ const char *demangler = NULL;
program_name = argv[0];
strip_underscore = prepends_underscore;
- while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
+ while ((c = getopt_long (argc, argv, "_ns:jd:", long_options, (int *) 0)) != EOF)
{
switch (c)
{
@@ -4500,28 +4671,12 @@ main (argc, argv)
case 'j':
flags |= DMGL_JAVA;
break;
+ case 'd':
+ demangler = optarg;
+ break;
case 's':
- if (strcmp (optarg, "gnu") == 0)
- {
- current_demangling_style = gnu_demangling;
- }
- else if (strcmp (optarg, "lucid") == 0)
- {
- current_demangling_style = lucid_demangling;
- }
- else if (strcmp (optarg, "arm") == 0)
- {
- current_demangling_style = arm_demangling;
- }
- else if (strcmp (optarg, "hp") == 0)
- {
- current_demangling_style = hp_demangling;
- }
- else if (strcmp (optarg, "edg") == 0)
- {
- current_demangling_style = edg_demangling;
- }
- else
+ current_demangling_style = o_style (optarg);
+ if (current_demangling_style == unknown_demangling)
{
fprintf (stderr, "%s: unknown demangling style `%s'\n",
program_name, optarg);
@@ -4546,6 +4701,8 @@ main (argc, argv)
case lucid_demangling:
case arm_demangling:
case edg_demangling:
+ case gnat_demangling:
+ case compaq_demangling:
valid_symbols = standard_symbol_characters ();
break;
case hp_demangling:
@@ -4558,6 +4715,8 @@ main (argc, argv)
abort ();
}
+ init_demangler (NULL, NULL, demangler);
+
for (;;)
{
int i = 0;
@@ -4635,3 +4794,140 @@ xrealloc (ptr, size)
return value;
}
#endif /* main */
+
+/* Assuming *OLD_VECT points to an array of *SIZE objects of size
+ ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
+ updating *OLD_VECT and *SIZE as necessary. */
+static void
+DEFUN (grow_vect, (old_vect, size, min_size, element_size),
+ void** old_vect
+ AND size_t* size
+ AND size_t min_size
+ AND int element_size)
+{
+ if (*size < min_size) {
+ *size *= 2;
+ if (*size < min_size)
+ *size = min_size;
+ *old_vect = xrealloc (*old_vect, *size * element_size);
+ }
+}
+
+/* Demangle ada names:
+ 1. Discard final __{DIGIT}+ or ${DIGIT}+
+ 2. Convert other instances of embedded "__" to `.'.
+ 3. Discard leading _ada_.
+ 4. Remove everything after first ___ if it is followed by
+ 'X'.
+ 5. Put symbols that should be suppressed in <...> brackets.
+ The resulting string is valid until the next call of ada_demangle.
+*/
+static char *
+DEFUN (gnat_demangle, (mangled), const char* mangled)
+{
+ int i, j;
+ int len0;
+ const char* p;
+ char* demangled = NULL;
+ int at_start_name;
+ int changed;
+ char* demangling_buffer = NULL;
+ size_t demangling_buffer_size = 0;
+
+ changed = 0;
+
+ if (strncmp (mangled, "_ada_", 5) == 0)
+ {
+ mangled += 5;
+ changed = 1;
+ }
+
+ if (mangled[0] == '_' || mangled[0] == '<')
+ goto Suppress;
+
+ p = strstr (mangled, "___");
+ if (p == NULL)
+ len0 = strlen (mangled);
+ else
+ {
+ if (p[3] == 'X')
+ {
+ len0 = p - mangled;
+ changed = 1;
+ }
+ else
+ goto Suppress;
+ }
+
+ /* Make demangled big enough for possible expansion by operator name. */
+ grow_vect ((void**) &(demangling_buffer),
+ &demangling_buffer_size, 2 * len0 + 1,
+ sizeof (char));
+ demangled = demangling_buffer;
+
+ if (isdigit (mangled[len0 - 1])) {
+ for (i = len0-2; i >= 0 && isdigit (mangled[i]); i -= 1)
+ ;
+ if (i > 1 && mangled[i] == '_' && mangled[i-1] == '_')
+ {
+ len0 = i - 1;
+ changed = 1;
+ }
+ else if (mangled[i] == '$')
+ {
+ len0 = i;
+ changed = 1;
+ }
+ }
+
+ for (i = 0, j = 0; i < len0 && ! isalpha (mangled[i]); i += 1, j += 1)
+ demangled[j] = mangled[i];
+
+ at_start_name = 1;
+ while (i < len0)
+ {
+ at_start_name = 0;
+
+ if (i < len0-2 && mangled[i] == '_' && mangled[i+1] == '_')
+ {
+ demangled[j] = '.';
+ changed = at_start_name = 1;
+ i += 2; j += 1;
+ }
+ else
+ {
+ demangled[j] = mangled[i];
+ i += 1; j += 1;
+ }
+ }
+ demangled[j] = '\000';
+
+ for (i = 0; demangled[i] != '\0'; i += 1)
+ if (isupper (demangled[i]) || demangled[i] == ' ')
+ goto Suppress;
+
+ if (! changed)
+ return NULL;
+ else
+ return demangled;
+
+ Suppress:
+ grow_vect ((void**) &(demangling_buffer),
+ &demangling_buffer_size, strlen (mangled) + 3,
+ sizeof (char));
+ demangled = demangling_buffer;
+ if (mangled[0] == '<')
+ strcpy (demangled, mangled);
+ else
+ sprintf (demangled, "<%s>", mangled);
+
+ return demangled;
+}
+
+static char *
+DEFUN (internal_ada_demangle, (mangled, option),
+ const char* mangled
+ AND int option ATTRIBUTE_UNUSED)
+{
+ return gnat_demangle (mangled);
+}
--- ../../import/egcs/include/demangle.h Sun Dec 13 22:55:06 1998
+++ include/demangle.h Sat Oct 9 15:54:50 1999
@@ -36,6 +36,8 @@
#define DMGL_HP (1 << 12) /* For the HP aCC compiler; same as ARM
except for template arguments, etc. */
#define DMGL_EDG (1 << 13)
+#define DMGL_GNAT (1 << 14)
+#define DMGL_COMPAQ (1 << 15)
/* If none of these are set, use 'current_demangling_style' as the default. */
#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG)
@@ -56,7 +58,9 @@ extern enum demangling_styles
lucid_demangling = DMGL_LUCID,
arm_demangling = DMGL_ARM,
hp_demangling = DMGL_HP,
- edg_demangling = DMGL_EDG
+ edg_demangling = DMGL_EDG,
+ gnat_demangling = DMGL_GNAT,
+ compaq_demangling = DMGL_COMPAQ
} current_demangling_style;
/* Define string names for the various demangling styles. */
@@ -67,6 +71,8 @@ extern enum demangling_styles
#define ARM_DEMANGLING_STYLE_STRING "arm"
#define HP_DEMANGLING_STYLE_STRING "hp"
#define EDG_DEMANGLING_STYLE_STRING "edg"
+#define GNAT_DEMANGLING_STYLE_STRING "gnat"
+#define COMPAQ_DEMANGLING_STYLE_STRING "compaq"
/* Some macros to test what demangling style is active. */
@@ -91,5 +97,16 @@ cplus_mangle_opname PARAMS ((const char
extern void
set_cplus_marker_for_demangling PARAMS ((int ch));
+
+extern char *
+demangle_symbol PARAMS ((const char *mangled));
+
+extern char *
+demangle_symbol_with_options PARAMS ((const char *mangled,
+ int options));
+
+extern int
+init_demangler PARAMS ((const char *style, const char *options,
+ const char *demangler));
#endif /* DEMANGLE_H */
More information about the Gcc-patches
mailing list