libgcc: use syscall rather than __mmap/__munmap

PR libgcc/94513
	* generic-morestack.c: Give up trying to use __mmap/__munmap, use
	syscall instead.
This commit is contained in:
Ian Lance Taylor 2020-04-07 11:29:41 -07:00
parent 3d947f1f27
commit 50c7853216
2 changed files with 53 additions and 8 deletions

View file

@ -1,3 +1,9 @@
2020-04-07 Ian Lance Taylor <iant@golang.org>
PR libgcc/94513
* generic-morestack.c: Give up trying to use __mmap/__munmap, use
syscall instead.
2020-04-04 Ian Lance Taylor <iant@golang.org>
* generic-morestack.c: Only use __mmap on glibc >= 2.26.

View file

@ -56,17 +56,56 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
/* Some systems use LD_PRELOAD or similar tricks to add hooks to
mmap/munmap. That breaks this code, because when we call mmap
there is enough stack space for the system call but there is not,
in general, enough stack space to run a hook. At least when using
glibc on GNU/Linux we can avoid the problem by calling __mmap and
__munmap. */
in general, enough stack space to run a hook. Try to avoid the
problem by calling syscall directly. We only do this on GNU/Linux
for now, but it should be easy to add support for more systems with
testing. */
#if defined(__gnu_linux__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 26))
#if defined(__gnu_linux__)
extern void *__mmap (void *, size_t, int, int, int, off_t);
extern int __munmap (void *, size_t);
#include <sys/syscall.h>
#define mmap __mmap
#define munmap __munmap
#if defined(SYS_mmap) || defined(SYS_mmap2)
#ifdef SYS_mmap2
#define MORESTACK_MMAP SYS_mmap2
#define MORESTACK_ADJUST_OFFSET(x) ((x) / 4096ULL)
#else
#define MORESTACK_MMAP SYS_mmap
#define MORESTACK_ADJUST_OFFSET(x) (x)
#endif
static void *
morestack_mmap (void *addr, size_t length, int prot, int flags, int fd,
off_t offset)
{
offset = MORESTACK_ADJUST_OFFSET (offset);
#ifdef __s390__
long args[6] = { (long) addr, (long) length, (long) prot, (long) flags,
(long) fd, (long) offset };
return (void *) syscall (MORESTACK_MMAP, args);
#else
return (void *) syscall (MORESTACK_MMAP, addr, length, prot, flags, fd,
offset);
#endif
}
#define mmap morestack_mmap
#endif /* defined(SYS_MMAP) || defined(SYS_mmap2) */
#if defined(SYS_munmap)
static int
morestack_munmap (void * addr, size_t length)
{
return (int) syscall (SYS_munmap, addr, length);
}
#define munmap morestack_munmap
#endif /* defined(SYS_munmap) */
#endif /* defined(__gnu_linux__) */