Commit 10d48c59 by David Tolnay Committed by Mark Wielaard

libiberty: Add Rust symbol demangling.

Adds Rust symbol demangler. Rust mangles symbols using GNU_V3 style,
adding a hash and various special character subtitutions. This adds
a new rust style to cplus_demangle and adds 3 helper functions
rust_demangle, rust_demangle_sym and rust_is_mangled.

rust-demangle.c was written by David. Mark did the code formatting to
GNU style and integration into the gcc/libiberty build system and
testsuite.

include/ChangeLog:

2016-11-03  David Tolnay <dtolnay@gmail.com>
           Mark Wielaard  <mark@klomp.org>

       * demangle.h (DMGL_RUST): New macro.
       (DMGL_STYLE_MASK): Add DMGL_RUST.
       (demangling_styles): Add dlang_rust.
       (RUST_DEMANGLING_STYLE_STRING): New macro.
       (RUST_DEMANGLING): New macro.
       (rust_demangle): New prototype.
       (rust_is_mangled): Likewise.
       (rust_demangle_sym): Likewise.

libiberty/ChangeLog:

2016-11-03  David Tolnay <dtolnay@gmail.com>
           Mark Wielaard  <mark@klomp.org>

       * Makefile.in (CFILES): Add rust-demangle.c.
       (REQUIRED_OFILES): Add rust-demangle.o.
       * cplus-dem.c (libiberty_demanglers): Add rust_demangling case.
       (cplus_demangle): Handle RUST_DEMANGLING.
       (rust_demangle): New function.
       * rust-demangle.c: New file.
       * testsuite/Makefile.in (really-check): Add check-rust-demangle.
       (check-rust-demangle): New rule.
       * testsuite/rust-demangle-expected: New file.

Co-Authored-By: Mark Wielaard <mark@klomp.org>

From-SVN: r242524
parent 46b2baa7
2016-11-03 David Tolnay <dtolnay@gmail.com>
Mark Wielaard <mark@klomp.org>
* demangle.h (DMGL_RUST): New macro.
(DMGL_STYLE_MASK): Add DMGL_RUST.
(demangling_styles): Add dlang_rust.
(RUST_DEMANGLING_STYLE_STRING): New macro.
(RUST_DEMANGLING): New macro.
(rust_demangle): New prototype.
(rust_is_mangled): Likewise.
(rust_demangle_sym): Likewise.
2016-11-07 Jason Merrill <jason@redhat.com>
* demangle.h (enum demangle_component_type): Add
......
......@@ -63,9 +63,10 @@ extern "C" {
#define DMGL_GNU_V3 (1 << 14)
#define DMGL_GNAT (1 << 15)
#define DMGL_DLANG (1 << 16)
#define DMGL_RUST (1 << 17) /* Rust wraps GNU_V3 style mangling. */
/* 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|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG)
#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG|DMGL_RUST)
/* Enumeration of possible demangling styles.
......@@ -88,7 +89,8 @@ extern enum demangling_styles
gnu_v3_demangling = DMGL_GNU_V3,
java_demangling = DMGL_JAVA,
gnat_demangling = DMGL_GNAT,
dlang_demangling = DMGL_DLANG
dlang_demangling = DMGL_DLANG,
rust_demangling = DMGL_RUST
} current_demangling_style;
/* Define string names for the various demangling styles. */
......@@ -104,6 +106,7 @@ extern enum demangling_styles
#define JAVA_DEMANGLING_STYLE_STRING "java"
#define GNAT_DEMANGLING_STYLE_STRING "gnat"
#define DLANG_DEMANGLING_STYLE_STRING "dlang"
#define RUST_DEMANGLING_STYLE_STRING "rust"
/* Some macros to test what demangling style is active. */
......@@ -118,6 +121,7 @@ extern enum demangling_styles
#define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA)
#define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT)
#define DLANG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_DLANG)
#define RUST_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_RUST)
/* Provide information about the available demangle styles. This code is
pulled from gdb into libiberty because it is useful to binutils also. */
......@@ -175,6 +179,27 @@ ada_demangle (const char *mangled, int options);
extern char *
dlang_demangle (const char *mangled, int options);
/* Returns non-zero iff MANGLED is a rust mangled symbol. MANGLED must
already have been demangled through cplus_demangle_v3. If this function
returns non-zero then MANGLED can be demangled (in-place) using
RUST_DEMANGLE_SYM. */
extern int
rust_is_mangled (const char *mangled);
/* Demangles SYM (in-place) if RUST_IS_MANGLED returned non-zero for SYM.
If RUST_IS_MANGLED returned zero for SYM then RUST_DEMANGLE_SYM might
replace characters that cannot be demangled with '?' and might truncate
SYM. After calling RUST_DEMANGLE_SYM SYM might be shorter, but never
larger. */
extern void
rust_demangle_sym (char *sym);
/* Demangles MANGLED if it was GNU_V3 and then RUST mangled, otherwise
returns NULL. Uses CPLUS_DEMANGLE_V3, RUST_IS_MANGLED and
RUST_DEMANGLE_SYM. Returns a new string that is owned by the caller. */
extern char *
rust_demangle (const char *mangled, int options);
enum gnu_v3_ctor_kinds {
gnu_v3_complete_object_ctor = 1,
gnu_v3_base_object_ctor,
......
2016-11-03 David Tolnay <dtolnay@gmail.com>
Mark Wielaard <mark@klomp.org>
* Makefile.in (CFILES): Add rust-demangle.c.
(REQUIRED_OFILES): Add rust-demangle.o.
* cplus-dem.c (libiberty_demanglers): Add rust_demangling case.
(cplus_demangle): Handle RUST_DEMANGLING.
(rust_demangle): New function.
* rust-demangle.c: New file.
* testsuite/Makefile.in (really-check): Add check-rust-demangle.
(check-rust-demangle): New rule.
* testsuite/rust-demangle-expected: New file.
2016-11-15 Mark Wielaard <mark@klomp.org>
* cp-demangle.c (d_expression_1): Make sure third expression
......
......@@ -146,6 +146,7 @@ CFILES = alloca.c argv.c asprintf.c atexit.c \
pex-unix.c pex-win32.c \
physmem.c putenv.c \
random.c regex.c rename.c rindex.c \
rust-demangle.c \
safe-ctype.c setenv.c setproctitle.c sha1.c sigsetmask.c \
simple-object.c simple-object-coff.c simple-object-elf.c \
simple-object-mach-o.c simple-object-xcoff.c \
......@@ -183,6 +184,7 @@ REQUIRED_OFILES = \
./partition.$(objext) ./pexecute.$(objext) ./physmem.$(objext) \
./pex-common.$(objext) ./pex-one.$(objext) \
./@pexecute@.$(objext) ./vprintf-support.$(objext) \
./rust-demangle.$(objext) \
./safe-ctype.$(objext) \
./simple-object.$(objext) ./simple-object-coff.$(objext) \
./simple-object-elf.$(objext) ./simple-object-mach-o.$(objext) \
......@@ -1188,6 +1190,17 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
else true; fi
$(COMPILE.c) $(srcdir)/rindex.c $(OUTPUT_OPTION)
./rust-demangle.$(objext): $(srcdir)/rust-demangle.c config.h \
$(INCDIR)/ansidecl.h $(INCDIR)/demangle.h $(INCDIR)/libiberty.h \
$(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/rust-demangle.c -o pic/$@; \
else true; fi
if [ x"$(NOASANFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/rust-demangle.c -o noasan/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/rust-demangle.c $(OUTPUT_OPTION)
./safe-ctype.$(objext): $(srcdir)/safe-ctype.c $(INCDIR)/ansidecl.h \
$(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
......
......@@ -323,6 +323,12 @@ const struct demangler_engine libiberty_demanglers[] =
}
,
{
RUST_DEMANGLING_STYLE_STRING,
rust_demangling,
"Rust style demangling"
}
,
{
NULL, unknown_demangling, NULL
}
};
......@@ -874,10 +880,26 @@ cplus_demangle (const char *mangled, int options)
work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
/* The V3 ABI demangling is implemented elsewhere. */
if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING)
{
ret = cplus_demangle_v3 (mangled, work->options);
if (ret || GNU_V3_DEMANGLING)
if (GNU_V3_DEMANGLING)
return ret;
if (ret)
{
/* Rust symbols are GNU_V3 mangled plus some extra subtitutions.
The subtitutions are always smaller, so do in place changes. */
if (rust_is_mangled (ret))
rust_demangle_sym (ret);
else if (RUST_DEMANGLING)
{
free (ret);
ret = NULL;
}
}
if (ret || RUST_DEMANGLING)
return ret;
}
......@@ -903,6 +925,27 @@ cplus_demangle (const char *mangled, int options)
return (ret);
}
char *
rust_demangle (const char *mangled, int options)
{
/* Rust symbols are GNU_V3 mangled plus some extra subtitutions. */
char *ret = cplus_demangle_v3 (mangled, options);
/* The Rust subtitutions are always smaller, so do in place changes. */
if (ret != NULL)
{
if (rust_is_mangled (ret))
rust_demangle_sym (ret);
else
{
free (ret);
ret = NULL;
}
}
return ret;
}
/* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
char *
......
......@@ -45,8 +45,8 @@ all:
# CHECK is set to "really_check" or the empty string by configure.
check: @CHECK@
really-check: check-cplus-dem check-d-demangle check-pexecute check-expandargv \
check-strtol
really-check: check-cplus-dem check-d-demangle check-rust-demangle \
check-pexecute check-expandargv check-strtol
# Run some tests of the demangler.
check-cplus-dem: test-demangle $(srcdir)/demangle-expected
......@@ -55,6 +55,9 @@ check-cplus-dem: test-demangle $(srcdir)/demangle-expected
check-d-demangle: test-demangle $(srcdir)/d-demangle-expected
./test-demangle < $(srcdir)/d-demangle-expected
check-rust-demangle: test-demangle $(srcdir)/rust-demangle-expected
./test-demangle < $(srcdir)/rust-demangle-expected
# Check the pexecute code.
check-pexecute: test-pexecute
./test-pexecute
......
# This file holds test cases for the Rust demangler.
# Each test case looks like this:
# options
# input to be demangled
# expected output
#
# See demangle-expected for documentation of supported options.
#
# A line starting with `#' is ignored.
# However, blank lines in this file are NOT ignored.
#
############
#
# Coverage Tests
#
#
# Demangles as rust symbol.
--format=rust
_ZN4main4main17he714a2e23ed7db23E
main::main
# Also demangles as c++ gnu v3 mangled symbol. But with extra Rust hash.
--format=gnu-v3
_ZN4main4main17he714a2e23ed7db23E
main::main::he714a2e23ed7db23
# But auto should demangle fully gnu-v3 -> rust -> demangled, not partially.
--format=auto
_ZN4main4main17he714a2e23ed7db23E
main::main
# Hash is exactly 16 hex chars. Not more.
--format=auto
_ZN4main4main18h1e714a2e23ed7db23E
main::main::h1e714a2e23ed7db23
# Not less.
--format=auto
_ZN4main4main16h714a2e23ed7db23E
main::main::h714a2e23ed7db23
# And not non-hex.
--format=auto
_ZN4main4main17he714a2e23ed7db2gE
main::main::he714a2e23ed7db2g
# $XX$ substitutions should not contain just numbers.
--format=auto
_ZN4main4$99$17he714a2e23ed7db23E
main::$99$::he714a2e23ed7db23
# _ at start of path should be removed.
# ".." translates to "::" "$GT$" to ">" and "$LT$" to "<".
--format=rust
_ZN71_$LT$Test$u20$$u2b$$u20$$u27$static$u20$as$u20$foo..Bar$LT$Test$GT$$GT$3bar17h930b740aa94f1d3aE
<Test + 'static as foo::Bar<Test>>::bar
#
--format=rust
_ZN54_$LT$I$u20$as$u20$core..iter..traits..IntoIterator$GT$9into_iter17h8581507801fb8615E
<I as core::iter::traits::IntoIterator>::into_iter
#
--format=rust
_ZN10parse_tsan4main17hdbbfdf1c6a7e27d9E
parse_tsan::main
#
--format=rust
_ZN65_$LT$std..env..Args$u20$as$u20$core..iter..iterator..Iterator$GT$4next17h420a7c8d0c7eef40E
<std::env::Args as core::iter::iterator::Iterator>::next
#
--format=rust
_ZN4core3str9from_utf817hdcea28871313776dE
core::str::from_utf8
#
--format=rust
_ZN4core3mem7size_of17h18bde9bb8c22e2cfE
core::mem::size_of
#
--format=rust
_ZN5alloc4heap8allocate17hd55c03e6cb81d924E
alloc::heap::allocate
#
--format=rust
_ZN4core3ptr8null_mut17h736cce09ca0ac11aE
core::ptr::null_mut
#
--format=rust
_ZN4core3ptr31_$LT$impl$u20$$BP$mut$u20$T$GT$7is_null17h7f9de798bc3f0879E
core::ptr::<impl *mut T>::is_null
#
--format=rust
_ZN40_$LT$alloc..raw_vec..RawVec$LT$T$GT$$GT$6double17h4166e2b47539e1ffE
<alloc::raw_vec::RawVec<T>>::double
#
--format=rust
_ZN39_$LT$collections..vec..Vec$LT$T$GT$$GT$4push17hd4b6b23c1b88141aE
<collections::vec::Vec<T>>::push
#
--format=rust
_ZN70_$LT$collections..vec..Vec$LT$T$GT$$u20$as$u20$core..ops..DerefMut$GT$9deref_mut17hf299b860dc5a831cE
<collections::vec::Vec<T> as core::ops::DerefMut>::deref_mut
#
--format=rust
_ZN63_$LT$core..ptr..Unique$LT$T$GT$$u20$as$u20$core..ops..Deref$GT$5deref17hc784b4a166cb5e5cE
<core::ptr::Unique<T> as core::ops::Deref>::deref
#
--format=rust
_ZN40_$LT$alloc..raw_vec..RawVec$LT$T$GT$$GT$3ptr17h7570b6e9070b693bE
<alloc::raw_vec::RawVec<T>>::ptr
#
--format=rust
_ZN4core3ptr31_$LT$impl$u20$$BP$mut$u20$T$GT$7is_null17h0f3228f343444ac8E
core::ptr::<impl *mut T>::is_null
#
--format=rust
_ZN53_$LT$$u5b$T$u5d$$u20$as$u20$core..slice..SliceExt$GT$10as_mut_ptr17h153241df1c7d1666E
<[T] as core::slice::SliceExt>::as_mut_ptr
#
--format=rust
_ZN11collections5slice29_$LT$impl$u20$$u5b$T$u5d$$GT$10as_mut_ptr17hf12a6d0409938c96E
collections::slice::<impl [T]>::as_mut_ptr
#
--format=rust
_ZN4core3ptr5write17h651fe53ec860e780E
core::ptr::write
#
--format=rust
_ZN65_$LT$std..env..Args$u20$as$u20$core..iter..iterator..Iterator$GT$4next17h420a7c8d0c7eef40E
<std::env::Args as core::iter::iterator::Iterator>::next
#
--format=rust
_ZN54_$LT$I$u20$as$u20$core..iter..traits..IntoIterator$GT$9into_iter17he06cb713aae5b465E
<I as core::iter::traits::IntoIterator>::into_iter
#
--format=rust
_ZN71_$LT$collections..vec..IntoIter$LT$T$GT$$u20$as$u20$core..ops..Drop$GT$4drop17hf7f23304ebe62eedE
<collections::vec::IntoIter<T> as core::ops::Drop>::drop
#
--format=rust
_ZN86_$LT$collections..vec..IntoIter$LT$T$GT$$u20$as$u20$core..iter..iterator..Iterator$GT$4next17h04b3fbf148c39713E
<collections::vec::IntoIter<T> as core::iter::iterator::Iterator>::next
#
--format=rust
_ZN75_$LT$$RF$$u27$a$u20$mut$u20$I$u20$as$u20$core..iter..iterator..Iterator$GT$4next17ha050492063e0fd20E
<&'a mut I as core::iter::iterator::Iterator>::next
# Different hashes are OK, they are just stripped.
--format=rust
_ZN13drop_contents17hfe3c0a68c8ad1c74E
drop_contents
#
--format=rust
_ZN13drop_contents17h48cb59bef15bb555E
drop_contents
#
--format=rust
_ZN4core3mem7size_of17h900b33157bf58f26E
core::mem::size_of
#
--format=rust
_ZN67_$LT$alloc..raw_vec..RawVec$LT$T$GT$$u20$as$u20$core..ops..Drop$GT$4drop17h96a5cf6e94807905E
<alloc::raw_vec::RawVec<T> as core::ops::Drop>::drop
#
--format=rust
_ZN68_$LT$core..nonzero..NonZero$LT$T$GT$$u20$as$u20$core..ops..Deref$GT$5deref17hc49056f882aa46dbE
<core::nonzero::NonZero<T> as core::ops::Deref>::deref
#
--format=rust
_ZN63_$LT$core..ptr..Unique$LT$T$GT$$u20$as$u20$core..ops..Deref$GT$5deref17h19f2ad4920655e85E
<core::ptr::Unique<T> as core::ops::Deref>::deref
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment