blob: b6eb2b3d062a13cd5d310969e6e769450cafc927 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
2 * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
3 *
4 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
5 */
6/* Massivly hacked up for uClibc by Erik Andersen */
7
8#include <_lfs_64.h>
9
10#ifdef __UCLIBC_HAS_LFS__
11
12#include <errno.h>
13#include <stdint.h>
14#include <unistd.h>
15#include <sys/mman.h>
16#include <sys/syscall.h>
17#include <bits/uClibc_page.h>
18
19
20# if !defined __NR_mmap2
21
22/*
23 * This version is a stub that just chops off everything at the mmap 32 bit
24 * mmap() address space... You will probably need to add in an arch specific
25 * implementation to override this as there is not a generic way for me to
26 * implement this particular syscall if your arch lacks _syscall6...
27 *
28 */
29
30__ptr_t mmap64(__ptr_t addr, size_t len, int prot, int flags, int fd, __off64_t offset)
31{
32 if (offset != (off_t) offset ||
33 (offset + len) != (off_t) (offset + len)) {
34 __set_errno(EINVAL);
35 return MAP_FAILED;
36 }
37
38 return mmap(addr, len, prot, flags, fd, (off_t) offset);
39}
40
41# else
42
43/* Some architectures always use 12 as page shift for mmap2() eventhough the
44 * real PAGE_SHIFT != 12. Other architectures use the same value as
45 * PAGE_SHIFT...
46 */
47# ifndef MMAP2_PAGE_SHIFT
48# define MMAP2_PAGE_SHIFT 12
49# endif
50
51__ptr_t mmap64(__ptr_t addr, size_t len, int prot, int flags, int fd, __off64_t offset)
52{
53 /*
54 * Some arches check the size in INLINE_SYSCALL() and barf if it's
55 * too big (i.e. a 64bit value getting truncated to 32bit).
56 */
57# if __WORDSIZE == 32
58 uint32_t sysoff;
59# else
60 uint64_t sysoff;
61# endif
62
63 if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) {
64 __set_errno(EINVAL);
65 return MAP_FAILED;
66 }
67
68 /*
69 * We know __off64_t is always a signed 64-bit type, but need things
70 * to be unsigned before doing the shift. If it isn't, we might
71 * sign extend things and pass in the wrong value. So cast it to
72 * an unsigned 64-bit value before doing the shift.
73 */
74 sysoff = (uint64_t)offset >> MMAP2_PAGE_SHIFT;
75
76 return (__ptr_t) INLINE_SYSCALL(mmap2, 6, addr, len, prot, flags, fd, sysoff);
77}
78
79# endif
80#endif /* __UCLIBC_HAS_LFS__ */