1 /*
2  * mmap() for uClibc
3  *
4  * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
5  *
6  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
7  */
8 
9 #include <sys/mman.h>
10 #include <sys/syscall.h>
11 
12 #if defined __UCLIBC_MMAP_HAS_6_ARGS__ && defined __NR_mmap
13 
14 # ifndef _syscall6
15 #  error disable __UCLIBC_MMAP_HAS_6_ARGS__ for this arch
16 # endif
17 
18 # define __NR__mmap __NR_mmap
19 static _syscall6(void *, _mmap, void *, addr, size_t, len,
20 		 int, prot, int, flags, int, fd, __off_t, offset)
21 
22 #elif defined __NR_mmap2 && defined _syscall6
23 
24 
25 # include <errno.h>
26 # include <bits/uClibc_page.h>
27 # ifndef MMAP2_PAGE_SHIFT
28 #  define MMAP2_PAGE_SHIFT 12
29 # endif
30 
31 # define __NR___syscall_mmap2 __NR_mmap2
32 static __inline__ _syscall6(void *, __syscall_mmap2, void *, addr, size_t, len,
33 			    int, prot, int, flags, int, fd, __off_t, offset)
34 
35 static void *_mmap(void *addr, size_t len, int prot, int flags,
36 		   int fd, __off_t offset)
37 {
38 	const int mmap2_shift = MMAP2_PAGE_SHIFT;
39 	const __off_t mmap2_mask = ((__off_t) 1 << MMAP2_PAGE_SHIFT) - 1;
40 	/* check if offset is page aligned */
41 	if (offset & mmap2_mask) {
42 		__set_errno(EINVAL);
43 		return MAP_FAILED;
44 	}
45 # ifdef __USE_FILE_OFFSET64
46 	return __syscall_mmap2(addr, len, prot, flags, fd,
47 				((__u_quad_t) offset >> mmap2_shift));
48 # else
49 	return __syscall_mmap2(addr, len, prot, flags, fd,
50 				((__u_long) offset >> mmap2_shift));
51 # endif
52 }
53 
54 #elif defined __NR_mmap
55 # define __NR___syscall_mmap __NR_mmap
56 static __inline__ _syscall1(void *, __syscall_mmap, unsigned long *, buffer)
57 
58 static void *_mmap(void *addr, size_t len, int prot, int flags,
59 		   int fd, __off_t offset)
60 {
61 	unsigned long buffer[6];
62 
63 	buffer[0] = (unsigned long) addr;
64 	buffer[1] = (unsigned long) len;
65 	buffer[2] = (unsigned long) prot;
66 	buffer[3] = (unsigned long) flags;
67 	buffer[4] = (unsigned long) fd;
68 	buffer[5] = (unsigned long) offset;
69 	return __syscall_mmap(buffer);
70 }
71 
72 #else
73 
74 # error "Your architecture doesn't seem to provide mmap() !?"
75 
76 #endif
77 
78 strong_alias(_mmap,mmap)
79 libc_hidden_def(mmap)
80