diff options
Diffstat (limited to 'libiberty/testsuite')
-rw-r--r-- | libiberty/testsuite/Makefile.in | 3 | ||||
-rw-r--r-- | libiberty/testsuite/demangle-expected | 53 | ||||
-rw-r--r-- | libiberty/testsuite/test-demangle.c | 56 |
3 files changed, 107 insertions, 5 deletions
diff --git a/libiberty/testsuite/Makefile.in b/libiberty/testsuite/Makefile.in index 534626e952d44..56800a7a7ce00 100644 --- a/libiberty/testsuite/Makefile.in +++ b/libiberty/testsuite/Makefile.in @@ -73,7 +73,8 @@ test-expandargv: $(srcdir)/test-expandargv.c ../libiberty.a $(srcdir)/test-expandargv.c ../libiberty.a # Standard (either GNU or Cygnus) rules we don't use. -html install-html info install-info clean-info dvi install etags tags installcheck: +html install-html info install-info clean-info dvi pdf install-pdf \ +install etags tags installcheck: # The standard clean rules. mostlyclean: diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index fa2a2fed24586..f1afc45c8c9b0 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -3805,3 +3805,56 @@ java::lang::Math::acos(double)double _Z4makeI7FactoryiET_IT0_Ev make<Factory, int>()Factory<int> make<Factory, int> +# +# From PR 28797 +--format=auto --no-params +_Z1fM1AKiPKS1_ +f(int const A::*, int const A::* const*) +f +# This used to cause a core dump in the demangler -- PR 29176 +--format=auto --no-params +SASDASDFASDF_sdfsdf +SASDASDFASDF_sdfsdf +SASDASDFASDF_sdfsdf +# These are all cases of invalid manglings where the demangler would read +# past the end of the string. +# d_name wasn't honouring a NULL from d_substitution +--format=gnu-v3 +_ZSA +_ZSA +# d_expr_primary wasn't honouring NULL from cplus_demangle_mangled_name +--format=gnu-v3 +_ZN1fIL_ +_ZN1fIL_ +# d_operator_name was taking two characters in a row +--format=gnu-v3 +_Za +_Za +# d_prefix wasn't honouring NULL from d_substitution +--format=gnu-v3 +_ZNSA +_ZNSA +# d_prefix wasn't honouring NULL from d_template_param +--format=gnu-v3 +_ZNT +_ZNT +# Dereferencing NULL in d_pointer_to_member_type +--format=gnu-v3 +_Z1aMark +_Z1aMark +# <local-source-name> test 1 +--format=gnu-v3 +_ZL3foo_2 +foo +# <local-source-name> test 2 +--format=gnu-v3 +_ZZL3foo_2vE4var1 +foo()::var1 +# <local-source-name> test 3 +--format=gnu-v3 +_ZZL3foo_2vE4var1_0 +foo()::var1 +# <local-source-name> test 4 +--format=gnu-v3 +_ZZN7myspaceL3foo_1EvEN11localstruct1fEZNS_3fooEvE16otherlocalstruct +myspace::foo()::localstruct::f(myspace::foo()::otherlocalstruct) diff --git a/libiberty/testsuite/test-demangle.c b/libiberty/testsuite/test-demangle.c index 93793996fe0d2..12b07dd6476cd 100644 --- a/libiberty/testsuite/test-demangle.c +++ b/libiberty/testsuite/test-demangle.c @@ -86,6 +86,50 @@ getline(buf) buf->alloced = alloc; } +/* If we have mmap() and mprotect(), copy the string S just before a + protected page, so that if the demangler runs over the end of the + string we'll get a fault, and return the address of the new string. + If no mmap, or it fails, or it looks too hard, just return S. */ + +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif +#if defined(MAP_ANON) && ! defined (MAP_ANONYMOUS) +#define MAP_ANONYMOUS MAP_ANON +#endif + +static const char * +protect_end (const char * s) +{ +#if defined(HAVE_MMAP) && defined (MAP_ANONYMOUS) + size_t pagesize = getpagesize(); + static char * buf; + size_t s_len = strlen (s); + char * result; + + /* Don't try if S is too long. */ + if (s_len >= pagesize) + return s; + + /* Allocate one page of allocated space followed by an unmapped + page. */ + if (buf == NULL) + { + buf = mmap (NULL, pagesize * 2, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (! buf) + return s; + munmap (buf + pagesize, pagesize); + } + + result = buf + (pagesize - s_len - 1); + memcpy (result, s, s_len + 1); + return result; +#else + return s; +#endif +} + static void fail (lineno, opts, in, out, exp) int lineno; @@ -150,6 +194,8 @@ main(argc, argv) for (;;) { + const char *inp; + getline (&format); if (feof (stdin)) break; @@ -157,6 +203,8 @@ main(argc, argv) getline (&input); getline (&expect); + inp = protect_end (input.data); + tests++; no_params = 0; @@ -237,14 +285,14 @@ main(argc, argv) { enum gnu_v3_ctor_kinds kc; - kc = is_gnu_v3_mangled_ctor (input.data); + kc = is_gnu_v3_mangled_ctor (inp); sprintf (buf, "%d", (int) kc); } else { enum gnu_v3_dtor_kinds kd; - kd = is_gnu_v3_mangled_dtor (input.data); + kd = is_gnu_v3_mangled_dtor (inp); sprintf (buf, "%d", (int) kd); } @@ -259,7 +307,7 @@ main(argc, argv) cplus_demangle_set_style (style); - result = cplus_demangle (input.data, + result = cplus_demangle (inp, DMGL_PARAMS|DMGL_ANSI|DMGL_TYPES |(ret_postfix ? DMGL_RET_POSTFIX : 0)); @@ -275,7 +323,7 @@ main(argc, argv) if (no_params) { getline (&expect); - result = cplus_demangle (input.data, DMGL_ANSI|DMGL_TYPES); + result = cplus_demangle (inp, DMGL_ANSI|DMGL_TYPES); if (result ? strcmp (result, expect.data) |