glibc/sysdeps/unix/sysv/linux/mmap.c
Adhemerval Zanella 1f14d0c3dd posix: Fix mmap for m68k and ia64 (BZ#21908)
Default semantic for mmap2 syscall is to take the offset in 4096-byte
units.  However m68k and ia64 mmap2 implementation take in the
configured pageunit units and for both architecture it can be
different values.

This patch fixes the m68k runtime discover of mmap2 offset unit
and adds the ia64 definition to find it at runtime.

Checked the basic tst-mmap and tst-mmap-offset on m68k (the system
is configured with 4k, so current code is already passing on this
system) and a sanity check on x86_64-linux-gnu (which should not be
affected by this change).  Sergei also states that ia64 loader now
work correctly with this change.

	Adhemerval Zanella  <adhemerval.zanella@linaro.org>
	Sergei Trofimovich  <slyfox@inbox.ru>

	* sysdeps/unix/sysv/linux/m68k/mmap_internal.h (MMAP2_PAGE_SHIFT):
	Rename to MMAP2_PAGE_UNIT.
	* sysdeps/unix/sysv/linux/mmap.c: Include mmap_internal iff
	__OFF_T_MATCHES_OFF64_T is not defined.
	* sysdeps/unix/sysv/linux/mmap_internal.h (page_unit): Declare as
	uint64_t.
	(MMAP2_PAGE_UNIT) [MMAP2_PAGE_UNIT == -1]: Redefine to page_unit.
	(page_unit) [MMAP2_PAGE_UNIT != -1]: Remove definition.
2017-08-14 10:35:14 -03:00

53 lines
1.6 KiB
C

/* mmap - map files or devices into memory. Linux version.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <errno.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sysdep.h>
#include <stdint.h>
#ifndef __OFF_T_MATCHES_OFF64_T
# include <mmap_internal.h>
/* An architecture may override this. */
# ifndef MMAP_ADJUST_OFFSET
# define MMAP_ADJUST_OFFSET(offset) offset
# endif
void *
__mmap (void *addr, size_t len, int prot, int flags, int fd, off_t offset)
{
MMAP_CHECK_PAGE_UNIT ();
if (offset & MMAP_OFF_LOW_MASK)
return (void *) INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
#ifdef __NR_mmap2
return (void *) MMAP_CALL (mmap2, addr, len, prot, flags, fd,
offset / (uint32_t) MMAP2_PAGE_UNIT);
#else
return (void *) MMAP_CALL (mmap, addr, len, prot, flags, fd,
MMAP_ADJUST_OFFSET (offset));
#endif
}
weak_alias (__mmap, mmap)
libc_hidden_def (__mmap)
#endif /* __OFF_T_MATCHES_OFF64_T */