gcc/libmpx/mpxwrap/mpx_wrappers.c
Ilya Enkovich 3ba99d8a03 mpx_wrappers.c (__mpx_wrapper_memmove): Add zero length check.
libmpx/

	* mpxwrap/mpx_wrappers.c (__mpx_wrapper_memmove): Add
	zero length check.

gcc/testsuite/

	* gcc.target/i386/mpx/memmove-zero-length.c: New.

From-SVN: r221944
2015-04-09 10:11:30 +00:00

282 lines
6.1 KiB
C

/* MPX Wrappers Library
Copyright (C) 2014 Free Software Foundation, Inc.
Contributed by Ilya Enkovich (ilya.enkovich@intel.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include "stdlib.h"
#include "string.h"
#include <sys/mman.h>
void *
__mpx_wrapper_malloc (size_t size)
{
void *p = (void *)malloc (size);
if (!p) return __bnd_null_ptr_bounds (p);
return __bnd_set_ptr_bounds (p, size);
}
void *
__mpx_wrapper_mmap (void *addr, size_t length, int prot, int flags,
int fd, off_t offset)
{
void *p = mmap (addr, length, prot, flags, fd, offset);
if (!p) return __bnd_null_ptr_bounds (p);
return __bnd_set_ptr_bounds (p, length);
}
void *
__mpx_wrapper_realloc (void *ptr, size_t n)
{
if (!ptr)
return __mpx_wrapper_malloc (n);
/* We don't kwnow how much data is copied by realloc
and therefore may check only lower bounds. */
__bnd_chk_ptr_lbounds (ptr);
ptr = realloc (ptr, n);
if (!ptr)
return __bnd_null_ptr_bounds (ptr);
return __bnd_set_ptr_bounds (ptr, n);
}
void *
__mpx_wrapper_calloc (size_t n_elements, size_t element_size)
{
void *p = calloc (n_elements, element_size);
if (!p)
return __bnd_null_ptr_bounds (p);
return __bnd_set_ptr_bounds (p, n_elements * element_size);
}
void *
__mpx_wrapper_memset (void *dstpp, int c, size_t len)
{
if (len > 0)
{
__bnd_chk_ptr_bounds (dstpp, len);
memset (dstpp, c, len);
}
return dstpp;
}
void
__mpx_wrapper_bzero (void *dst, size_t len)
{
__mpx_wrapper_memset (dst, 0, len);
}
void *
__mpx_wrapper_memmove (void *dst, const void *src, size_t n)
{
const char *s = (const char*)src;
char *d = (char*)dst;
void *ret = dst;
size_t offset_src = ((size_t) s) & (sizeof (void *) - 1);
size_t offset_dst = ((size_t) d) & (sizeof (void *) - 1);
if (n == 0)
return ret;
__bnd_chk_ptr_bounds (dst, n);
__bnd_chk_ptr_bounds (src, n);
/* Different alignment means that even if
pointers exist in memory, we don't how
pointers are aligned and therefore cann't
copy bounds anyway. */
if (offset_src != offset_dst)
memmove (dst, src, n);
else
{
if (s < d)
{
d += n;
s += n;
offset_src = (offset_src + n) & (sizeof (void *) -1);
while (n-- && offset_src--)
*--d = *--s;
n++;
if (!n)
return ret;
void **d1 = (void **)d;
void **s1 = (void **)s;
/* This loop will also copy bounds. */
while (n >= sizeof (void *))
{
n -= sizeof (void *);
*--d1 = *--s1;
}
s = (char *)s1;
d = (char *)d1;
while (n--)
*--d = *--s;
}
else
{
offset_src = sizeof (void *) - offset_src;
while (n-- && offset_src--)
*d++ = *s++;
n++;
if (!n)
return ret;
void **d1 = (void **)d;
void **s1 = (void **)s;
/* This loop will also copy bounds. */
while (n >= sizeof (void *))
{
n -= sizeof (void *);
*d1++ = *s1++;
}
s = (char *)s1;
d = (char *)d1;
while (n--)
*d++ = *s++;
}
}
return ret;
}
void *
__mpx_wrapper_memcpy (void *dst, const void *src, size_t n)
{
return __mpx_wrapper_memmove (dst, src, n);
}
void *
__mpx_wrapper_mempcpy (void *dst, const void *src, size_t n)
{
return (char *)__mpx_wrapper_memcpy (dst, src, n) + n;
}
char *
__mpx_wrapper_strncat (char *dst, const char *src, size_t n)
{
size_t dst_size = strlen (dst);
size_t src_size = strnlen (src, n);
__bnd_chk_ptr_bounds (dst, dst_size + src_size + 1);
if (src_size < n)
__bnd_chk_ptr_bounds (src, src_size + 1);
else
__bnd_chk_ptr_bounds (src, src_size);
strncat (dst, src, n);
return dst;
}
char *
__mpx_wrapper_strcat (char *dst, const char *src)
{
size_t dst_size = strlen (dst);
size_t src_size = strlen (src);
__bnd_chk_ptr_bounds (dst, dst_size + src_size + 1);
__bnd_chk_ptr_bounds (src, src_size + 1);
strcat (dst, src);
return dst;
}
char *
__mpx_wrapper_stpcpy (char *dst, const char *src)
{
size_t src_size = strlen (src);
__bnd_chk_ptr_bounds (dst, src_size + 1);
__bnd_chk_ptr_bounds (src, src_size + 1);
memcpy (dst, src, src_size + 1);
return dst + src_size;
}
char *
__mpx_wrapper_stpncpy (char *dst, const char *src, size_t n)
{
size_t src_size = strnlen (src, n);
char *res;
__bnd_chk_ptr_bounds (dst, n);
if (src_size < n)
{
__bnd_chk_ptr_bounds (src, src_size + 1);
res = dst + src_size;
}
else
{
__bnd_chk_ptr_bounds (src, src_size);
res = dst + n;
}
memcpy (dst, src, src_size);
if (n > src_size)
memset (dst + src_size, 0, n - src_size);
return res;
}
char *
__mpx_wrapper_strcpy (char *dst, const char *src)
{
size_t src_size = strlen (src);
__bnd_chk_ptr_bounds (dst, src_size + 1);
__bnd_chk_ptr_bounds (src, src_size + 1);
memcpy (dst, src, src_size + 1);
return dst;
}
char *
__mpx_wrapper_strncpy (char *dst, const char *src, size_t n)
{
size_t src_size = strnlen (src, n);
__bnd_chk_ptr_bounds (dst, n);
if (src_size < n)
__bnd_chk_ptr_bounds (src, src_size + 1);
else
__bnd_chk_ptr_bounds (src, src_size);
memcpy (dst, src, src_size);
if (n > src_size)
memset (dst + src_size, 0, n - src_size);
return dst;
}
size_t
__mpx_wrapper_strlen (const char *s)
{
size_t length = strlen (s);
__bnd_chk_ptr_bounds (s, length + 1);
return length;
}