libiberty: upstream updates.

There is a new ChangeLog.gcc43 file but most notable:

* floatformat.c (get_field): Fix segfault with little-endian word
  order on 64-bit hosts.
  (put_field): Likewise.
  (min): Move definition.

gcc/cp/ChangeLog
2007-05-04  Geoffrey Keating  <geoffk@apple.com>

  PR 31775
  * mangle.c (write_mangled_name): Mangle static variable names.
  (write_unqualified_name): Use local-source-name for
  namespace-scope static variables.
(Completes FreeBSD's r258017 )

Obtained from:	gcc 4.3 (rev. 118552, 120097, 20698, 120702,
			 121364, 122972, 126588; GPLv2)
MFC after:	2 weeks
This commit is contained in:
pfg 2013-12-01 22:08:19 +00:00
parent 9051411db5
commit 49bd75ce1c
12 changed files with 253 additions and 116 deletions

View File

@ -1,4 +1,4 @@
2007-07-09 Geoffrey Keating <geoffk@apple.com>
2007-07-09 Geoffrey Keating <geoffk@apple.com> (r126529)
PR 32617
* decl.c (cxx_init_decl_processing): Don't set
@ -18,6 +18,13 @@
* decl2.c (determine_visibility): Remove duplicate code for
handling type info.
2007-05-05 Geoffrey Keating <geoffk@apple.com> (r124467)
PR 31775
* mangle.c (write_mangled_name): Mangle static variable names.
(write_unqualified_name): Use local-source-name for
namespace-scope static variables.
2007-03-12 Seongbae Park <seongbae.park@gmail.com> (r122851)
* decl.c (compute_array_index_type): New warning flag warn_vla.

View File

@ -688,7 +688,8 @@ write_mangled_name (const tree decl, bool top_level)
}
}
else if (TREE_CODE (decl) == VAR_DECL
/* The names of global variables aren't mangled. */
/* The names of non-static global variables aren't mangled. */
&& DECL_EXTERNAL_LINKAGE_P (decl)
&& (CP_DECL_CONTEXT (decl) == global_namespace
/* And neither are `extern "C"' variables. */
|| DECL_EXTERN_C_P (decl)))
@ -1086,7 +1087,10 @@ write_template_prefix (const tree node)
<unqualified-name> ::= <operator-name>
::= <special-name>
::= <source-name> */
::= <source-name>
::= <local-source-name>
<local-source-name> ::= L <source-name> <discriminator> */
static void
write_unqualified_name (const tree decl)
@ -1126,6 +1130,16 @@ write_unqualified_name (const tree decl)
write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name);
}
else if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
&& DECL_NAMESPACE_SCOPE_P (decl)
&& decl_linkage (decl) == lk_internal)
{
MANGLE_TRACE_TREE ("local-source-name", decl);
write_char ('L');
write_source_name (DECL_NAME (decl));
/* The default discriminator is 1, and that's all we ever use,
so there's no code to output one here. */
}
else
write_source_name (DECL_NAME (decl));
}

View File

@ -0,0 +1,60 @@
2007-05-05 Geoffrey Keating <geoffk@apple.com> (r124467)
PR 31775
* mangle.c (write_mangled_name): Mangle static variable names.
(write_unqualified_name): Use local-source-name for
namespace-scope static variables.
2007-03-15 Geoffrey Keating <geoffk@apple.com> (r122972)
* cp-demangle.c (d_encoding): Exit early on error.
(d_pointer_to_member_type): Exit early if cplus_demangle_type
returns NULL.
(cplus_demangle_type): Likewise.
* testsuite/demangle-expected: New testcase.
2007-01-31 Ben Elliston <bje@au.ibm.com> (r121364)
* strsignal.c (psignal): Change type of signo to int.
* functions.texi: Regenerate.
2007-01-12 Ben Elliston <bje@au.ibm.com> (r120702)
* pex-unix.c (writeerr): Cast write result to void.
* choose-temp.c (choose_temp_base): Check the result of the call
to mktemp rather than testing the length of the modified string.
2006-12-20 Geoffrey Keating <geoffk@apple.com> (r120097)
* cp-demangle.h: Add comment explaining what to do to avoid
overrunning string.
(d_check_char): New.
(d_next_char): Don't advance past trailing '\0'.
* cp-demangle.c (cplus_demangle_mangled_name): Use d_check_char.
(d_nested_name): Likewise.
(d_special_name): Likewise.
(d_call_offset): Likewise.
(d_function_type): Likewise.
(d_array_type): Likewise.
(d_pointer_to_member_type): Likewise.
(d_template_param): Likewise.
(d_template_args): Likewise.
(d_template_arg): Likewise.
(d_expr_primary): Likewise.
(d_local_name): Likewise.
(d_substitution): Likewise.
(d_ctor_dtor_name): Use d_advance rather than d_next_char.
* testsuite/test-demangle.c: Include sys/mman.h.
(MAP_ANONYMOUS): Define.
(protect_end): New.
(main): Use protect_end.
* testsuite/demangle-expected: Add testcases for overrunning
the end of the string.
2006-11-07 Julian Brown <julian@codesourcery.com> (r118552)
* floatformat.c (get_field): Fix segfault with little-endian word
order on 64-bit hosts.
(put_field): Likewise.
(min): Move definition.

View File

@ -65,8 +65,7 @@ choose_temp_base (void)
strcpy (temp_filename, base);
strcpy (temp_filename + len, TEMP_FILE);
mktemp (temp_filename);
if (strlen (temp_filename) == 0)
if (mktemp (temp_filename) == 0)
abort ();
return temp_filename;
}

View File

@ -913,9 +913,9 @@ CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_mangled_name (struct d_info *di, int top_level)
{
if (d_next_char (di) != '_')
if (! d_check_char (di, '_'))
return NULL;
if (d_next_char (di) != 'Z')
if (! d_check_char (di, 'Z'))
return NULL;
return d_encoding (di, top_level);
}
@ -1021,7 +1021,7 @@ d_encoding (struct d_info *di, int top_level)
}
peek = d_peek_char (di);
if (peek == '\0' || peek == 'E')
if (dc == NULL || peek == '\0' || peek == 'E')
return dc;
return d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, dc,
d_bare_function_type (di, has_return_type (dc)));
@ -1054,11 +1054,9 @@ d_name (struct d_info *di)
case 'Z':
return d_local_name (di);
/* APPLE LOCAL begin mainline 2007-05-09 5173149 */ \
case 'L':
return d_unqualified_name (di);
/* APPLE LOCAL end mainline 2007-05-09 5173149 */ \
case 'S':
{
int subst;
@ -1128,7 +1126,7 @@ d_nested_name (struct d_info *di)
struct demangle_component *ret;
struct demangle_component **pret;
if (d_next_char (di) != 'N')
if (! d_check_char (di, 'N'))
return NULL;
pret = d_cv_qualifiers (di, &ret, 1);
@ -1139,7 +1137,7 @@ d_nested_name (struct d_info *di)
if (*pret == NULL)
return NULL;
if (d_next_char (di) != 'E')
if (! d_check_char (di, 'E'))
return NULL;
return ret;
@ -1179,10 +1177,8 @@ d_prefix (struct d_info *di)
if (IS_DIGIT (peek)
|| IS_LOWER (peek)
|| peek == 'C'
/* APPLE LOCAL begin mainline 2007-05-09 5173149 */ \
|| peek == 'D'
|| peek == 'L')
/* APPLE LOCAL end mainline 2007-05-09 5173149 */ \
dc = d_unqualified_name (di);
else if (peek == 'S')
dc = d_substitution (di, 1);
@ -1216,11 +1212,9 @@ d_prefix (struct d_info *di)
/* <unqualified-name> ::= <operator-name>
::= <ctor-dtor-name>
::= <source-name>
APPLE LOCAL begin mainline 2007-05-09 5173149
::= <local-source-name>
<local-source-name> ::= L <source-name> <discriminator>
APPLE LOCAL end mainline 2007-05-09 5173149
*/
static struct demangle_component *
@ -1242,7 +1236,6 @@ d_unqualified_name (struct d_info *di)
}
else if (peek == 'C' || peek == 'D')
return d_ctor_dtor_name (di);
/* APPLE LOCAL begin mainline 2007-05-09 5173149 */ \
else if (peek == 'L')
{
struct demangle_component * ret;
@ -1256,7 +1249,6 @@ d_unqualified_name (struct d_info *di)
return NULL;
return ret;
}
/* APPLE LOCAL end mainline 2007-05-09 5173149 */ \
else
return NULL;
}
@ -1477,11 +1469,8 @@ d_operator_name (struct d_info *di)
static struct demangle_component *
d_special_name (struct d_info *di)
{
char c;
di->expansion += 20;
c = d_next_char (di);
if (c == 'T')
if (d_check_char (di, 'T'))
{
switch (d_next_char (di))
{
@ -1530,7 +1519,7 @@ d_special_name (struct d_info *di)
offset = d_number (di);
if (offset < 0)
return NULL;
if (d_next_char (di) != '_')
if (! d_check_char (di, '_'))
return NULL;
base_type = cplus_demangle_type (di);
/* We don't display the offset. FIXME: We should display
@ -1551,7 +1540,7 @@ d_special_name (struct d_info *di)
return NULL;
}
}
else if (c == 'G')
else if (d_check_char (di, 'G'))
{
switch (d_next_char (di))
{
@ -1598,14 +1587,14 @@ d_call_offset (struct d_info *di, int c)
else if (c == 'v')
{
d_number (di);
if (d_next_char (di) != '_')
if (! d_check_char (di, '_'))
return 0;
d_number (di);
}
else
return 0;
if (d_next_char (di) != '_')
if (! d_check_char (di, '_'))
return 0;
return 1;
@ -1629,13 +1618,13 @@ d_ctor_dtor_name (struct d_info *di)
else if (di->last_name->type == DEMANGLE_COMPONENT_SUB_STD)
di->expansion += di->last_name->u.s_string.len;
}
switch (d_next_char (di))
switch (d_peek_char (di))
{
case 'C':
{
enum gnu_v3_ctor_kinds kind;
switch (d_next_char (di))
switch (d_peek_next_char (di))
{
case '1':
kind = gnu_v3_complete_object_ctor;
@ -1649,6 +1638,7 @@ d_ctor_dtor_name (struct d_info *di)
default:
return NULL;
}
d_advance (di, 2);
return d_make_ctor (di, kind, di->last_name);
}
@ -1656,7 +1646,7 @@ d_ctor_dtor_name (struct d_info *di)
{
enum gnu_v3_dtor_kinds kind;
switch (d_next_char (di))
switch (d_peek_next_char (di))
{
case '0':
kind = gnu_v3_deleting_dtor;
@ -1670,6 +1660,7 @@ d_ctor_dtor_name (struct d_info *di)
default:
return NULL;
}
d_advance (di, 2);
return d_make_dtor (di, kind, di->last_name);
}
@ -1763,7 +1754,7 @@ cplus_demangle_type (struct d_info *di)
if (pret == NULL)
return NULL;
*pret = cplus_demangle_type (di);
if (! d_add_substitution (di, ret))
if (! *pret || ! d_add_substitution (di, ret))
return NULL;
return ret;
}
@ -1953,7 +1944,7 @@ d_function_type (struct d_info *di)
{
struct demangle_component *ret;
if (d_next_char (di) != 'F')
if (! d_check_char (di, 'F'))
return NULL;
if (d_peek_char (di) == 'Y')
{
@ -1962,7 +1953,7 @@ d_function_type (struct d_info *di)
d_advance (di, 1);
}
ret = d_bare_function_type (di, 1);
if (d_next_char (di) != 'E')
if (! d_check_char (di, 'E'))
return NULL;
return ret;
}
@ -2049,7 +2040,7 @@ d_array_type (struct d_info *di)
char peek;
struct demangle_component *dim;
if (d_next_char (di) != 'A')
if (! d_check_char (di, 'A'))
return NULL;
peek = d_peek_char (di);
@ -2077,7 +2068,7 @@ d_array_type (struct d_info *di)
return NULL;
}
if (d_next_char (di) != '_')
if (! d_check_char (di, '_'))
return NULL;
return d_make_comp (di, DEMANGLE_COMPONENT_ARRAY_TYPE, dim,
@ -2093,7 +2084,7 @@ d_pointer_to_member_type (struct d_info *di)
struct demangle_component *mem;
struct demangle_component **pmem;
if (d_next_char (di) != 'M')
if (! d_check_char (di, 'M'))
return NULL;
cl = cplus_demangle_type (di);
@ -2118,6 +2109,8 @@ d_pointer_to_member_type (struct d_info *di)
if (pmem == NULL)
return NULL;
*pmem = cplus_demangle_type (di);
if (*pmem == NULL)
return NULL;
if (pmem != &mem && (*pmem)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
{
@ -2137,7 +2130,7 @@ d_template_param (struct d_info *di)
{
long param;
if (d_next_char (di) != 'T')
if (! d_check_char (di, 'T'))
return NULL;
if (d_peek_char (di) == '_')
@ -2150,7 +2143,7 @@ d_template_param (struct d_info *di)
param += 1;
}
if (d_next_char (di) != '_')
if (! d_check_char (di, '_'))
return NULL;
++di->did_subs;
@ -2172,7 +2165,7 @@ d_template_args (struct d_info *di)
constructor or destructor. */
hold_last_name = di->last_name;
if (d_next_char (di) != 'I')
if (! d_check_char (di, 'I'))
return NULL;
al = NULL;
@ -2217,7 +2210,7 @@ d_template_arg (struct d_info *di)
case 'X':
d_advance (di, 1);
ret = d_expression (di);
if (d_next_char (di) != 'E')
if (! d_check_char (di, 'E'))
return NULL;
return ret;
@ -2344,7 +2337,7 @@ d_expr_primary (struct d_info *di)
{
struct demangle_component *ret;
if (d_next_char (di) != 'L')
if (! d_check_char (di, 'L'))
return NULL;
if (d_peek_char (di) == '_')
ret = cplus_demangle_mangled_name (di, 0);
@ -2390,7 +2383,7 @@ d_expr_primary (struct d_info *di)
}
ret = d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s));
}
if (d_next_char (di) != 'E')
if (! d_check_char (di, 'E'))
return NULL;
return ret;
}
@ -2404,12 +2397,12 @@ d_local_name (struct d_info *di)
{
struct demangle_component *function;
if (d_next_char (di) != 'Z')
if (! d_check_char (di, 'Z'))
return NULL;
function = d_encoding (di, 0);
if (d_next_char (di) != 'E')
if (! d_check_char (di, 'E'))
return NULL;
if (d_peek_char (di) == 's')
@ -2514,7 +2507,7 @@ d_substitution (struct d_info *di, int prefix)
{
char c;
if (d_next_char (di) != 'S')
if (! d_check_char (di, 'S'))
return NULL;
c = d_next_char (di);

View File

@ -123,10 +123,16 @@ struct d_info
int expansion;
};
/* To avoid running past the ending '\0', don't:
- call d_peek_next_char if d_peek_char returned '\0'
- call d_advance with an 'i' that is too large
- call d_check_char(di, '\0')
Everything else is safe. */
#define d_peek_char(di) (*((di)->n))
#define d_peek_next_char(di) ((di)->n[1])
#define d_advance(di, i) ((di)->n += (i))
#define d_next_char(di) (*((di)->n++))
#define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0)
#define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++))
#define d_str(di) ((di)->n)
/* Functions and arrays in cp-demangle.c which are referenced by

View File

@ -249,53 +249,51 @@ const struct floatformat floatformat_ia64_quad_little =
floatformat_always_valid
};
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
/* Extract a field which starts at START and is LEN bits long. DATA and
TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
static unsigned long
get_field (const unsigned char *data, enum floatformat_byteorders order,
unsigned int total_len, unsigned int start, unsigned int len)
{
unsigned long result;
unsigned long result = 0;
unsigned int cur_byte;
int cur_bitshift;
int lo_bit, hi_bit, cur_bitshift = 0;
int nextbyte = (order == floatformat_little) ? 1 : -1;
/* Start is in big-endian bit order! Fix that first. */
start = total_len - (start + len);
/* Start at the least significant part of the field. */
cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
if (order == floatformat_little)
cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
cur_bitshift =
((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
result = *(data + cur_byte) >> (-cur_bitshift);
cur_bitshift += FLOATFORMAT_CHAR_BIT;
if (order == floatformat_little)
++cur_byte;
cur_byte = start / FLOATFORMAT_CHAR_BIT;
else
--cur_byte;
cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
/* Move towards the most significant part of the field. */
while ((unsigned int) cur_bitshift < len)
lo_bit = start % FLOATFORMAT_CHAR_BIT;
hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
do
{
if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
/* This is the last byte; zero out the bits which are not part of
this field. */
result |=
(*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1))
<< cur_bitshift;
else
result |= *(data + cur_byte) << cur_bitshift;
cur_bitshift += FLOATFORMAT_CHAR_BIT;
if (order == floatformat_little)
++cur_byte;
else
--cur_byte;
unsigned int shifted = *(data + cur_byte) >> lo_bit;
unsigned int bits = hi_bit - lo_bit;
unsigned int mask = (1 << bits) - 1;
result |= (shifted & mask) << cur_bitshift;
len -= bits;
cur_bitshift += bits;
cur_byte += nextbyte;
lo_bit = 0;
hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
}
while (len != 0);
return result;
}
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
/* Convert from FMT to a double.
FROM is the address of the extended float.
Store the double in *TO. */
@ -428,43 +426,34 @@ put_field (unsigned char *data, enum floatformat_byteorders order,
unsigned long stuff_to_put)
{
unsigned int cur_byte;
int cur_bitshift;
int lo_bit, hi_bit;
int nextbyte = (order == floatformat_little) ? 1 : -1;
/* Start is in big-endian bit order! Fix that first. */
start = total_len - (start + len);
/* Start at the least significant part of the field. */
cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
if (order == floatformat_little)
cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
cur_bitshift =
((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
*(data + cur_byte) &=
~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) << (-cur_bitshift));
*(data + cur_byte) |=
(stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
cur_bitshift += FLOATFORMAT_CHAR_BIT;
if (order == floatformat_little)
++cur_byte;
cur_byte = start / FLOATFORMAT_CHAR_BIT;
else
--cur_byte;
cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
/* Move towards the most significant part of the field. */
while ((unsigned int) cur_bitshift < len)
lo_bit = start % FLOATFORMAT_CHAR_BIT;
hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
do
{
if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
{
/* This is the last byte. */
*(data + cur_byte) &=
~((1 << (len - cur_bitshift)) - 1);
*(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
}
else
*(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
& ((1 << FLOATFORMAT_CHAR_BIT) - 1));
cur_bitshift += FLOATFORMAT_CHAR_BIT;
if (order == floatformat_little)
++cur_byte;
else
--cur_byte;
unsigned char *byte_ptr = data + cur_byte;
unsigned int bits = hi_bit - lo_bit;
unsigned int mask = ((1 << bits) - 1) << lo_bit;
*byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask);
stuff_to_put >>= bits;
len -= bits;
cur_byte += nextbyte;
lo_bit = 0;
hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
}
while (len != 0);
}
/* The converse: convert the double *FROM to an extended float

View File

@ -948,7 +948,7 @@ documented.
@end deftypefn
@c strsignal.c:539
@deftypefn Supplemental void psignal (unsigned @var{signo}, char *@var{message})
@deftypefn Supplemental void psignal (int @var{signo}, char *@var{message})
Print @var{message} to the standard error, followed by a colon,
followed by the description of the signal specified by @var{signo},

View File

@ -339,7 +339,7 @@ static void
pex_child_error (struct pex_obj *obj, const char *executable,
const char *errmsg, int err)
{
#define writeerr(s) write (STDERR_FILE_NO, s, strlen (s))
#define writeerr(s) (void) write (STDERR_FILE_NO, s, strlen (s))
writeerr (obj->pname);
writeerr (": error trying to exec '");
writeerr (executable);

View File

@ -9,7 +9,7 @@
/* We need to declare sys_siglist, because even if the system provides
it we can't assume that it is declared in <signal.h> (for example,
SunOS provides sys_siglist, but it does not declare it in any
header file). fHowever, we can't declare sys_siglist portably,
header file). However, we can't declare sys_siglist portably,
because on some systems it is declared with const and on some
systems it is declared without const. If we were using autoconf,
we could work out the right declaration. Until, then we just
@ -536,7 +536,7 @@ strtosigno (const char *name)
/*
@deftypefn Supplemental void psignal (unsigned @var{signo}, char *@var{message})
@deftypefn Supplemental void psignal (int @var{signo}, char *@var{message})
Print @var{message} to the standard error, followed by a colon,
followed by the description of the signal specified by @var{signo},
@ -549,7 +549,7 @@ followed by a newline.
#ifndef HAVE_PSIGNAL
void
psignal (unsigned signo, char *message)
psignal (int signo, char *message)
{
if (signal_names == NULL)
{

View File

@ -3816,7 +3816,6 @@ f
SASDASDFASDF_sdfsdf
SASDASDFASDF_sdfsdf
SASDASDFASDF_sdfsdf
# APPLE LOCAL begin mainline 2007-05-09 5173149
# 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
@ -3843,6 +3842,29 @@ _ZNT
--format=gnu-v3
_Z1aMark
_Z1aMark
--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
@ -3859,4 +3881,3 @@ foo()::var1
--format=gnu-v3
_ZZN7myspaceL3foo_1EvEN11localstruct1fEZNS_3fooEvE16otherlocalstruct
myspace::foo()::localstruct::f(myspace::foo()::otherlocalstruct)
# APPLE LOCAL end mainline 2007-05-09 5173149

View File

@ -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)