1 /*
2 * (c) 2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU Lesser General Public License 2.1.
7 * Please see the COPYING-LGPL-2.1 file for details.
8 */
9
10 #include <l4/sys/compiler.h>
11 #include <l4/re/rm>
12 #include <l4/re/dataspace>
13 #include <l4/re/env>
14 #include <l4/re/util/cap_alloc>
15 #include <sys/mman.h>
16 #include <unistd.h>
17 #include <cstdio>
18 #include <errno.h>
19 #include <l4/l4re_vfs/backend>
20 #include <bits/l4-malloc.h>
21 #include "redirect.h"
22
23 #define L4B_REDIRECT(ret, func, ptlist, plist) \
24 ret func ptlist noexcept(noexcept(func plist)) \
25 { \
26 ret r = L4B(func plist); \
27 POST(); \
28 }
29
30 void *mmap2(void *addr, size_t length, int prot, int flags,
31 int fd, off_t pgoffset) noexcept;
mmap2(void * addr,size_t length,int prot,int flags,int fd,off_t pgoffset)32 void *mmap2(void *addr, size_t length, int prot, int flags,
33 int fd, off_t pgoffset) noexcept
34 {
35 void *resptr;
36 int r = L4B(mmap2(addr, length, prot, flags, fd, pgoffset, &resptr));
37 if (r < 0)
38 {
39 errno = -r;
40 return MAP_FAILED;
41 }
42
43 return resptr;
44 }
45
46
47 /* Other versions of mmap */
mmap64(void * addr,size_t length,int prot,int flags,int fd,off64_t offset)48 void *mmap64(void *addr, size_t length, int prot, int flags,
49 int fd, off64_t offset)
50 noexcept(noexcept(mmap64(addr, length, prot, flags, fd, offset)))
51 {
52 if (offset & ~L4_PAGEMASK)
53 {
54 errno = EINVAL;
55 return MAP_FAILED;
56 }
57 return mmap2(addr, length, prot, flags, fd, offset >> 12);
58 }
59
mmap(void * addr,size_t length,int prot,int flags,int fd,off_t offset)60 void *mmap(void *addr, size_t length, int prot, int flags,
61 int fd, off_t offset)
62 noexcept(noexcept(mmap(addr, length, prot, flags, fd, offset)))
63 {
64 return mmap64(addr, length, prot, flags, fd, offset);
65 }
66
67 L4B_REDIRECT_2(int, munmap, void*, size_t)
68 L4B_REDIRECT_3(int, mprotect, void *, size_t, int);
69 L4B_REDIRECT_3(int, madvise, void *, size_t, int);
70 L4B_REDIRECT_3(int, msync, void *, size_t, int);
71
mremap(void * old_addr,size_t old_size,size_t new_size,int flags,...)72 void *mremap(void *old_addr, size_t old_size, size_t new_size,
73 int flags, ...)
74 noexcept(noexcept(mremap(old_addr, old_size, new_size, flags)))
75 {
76 void *resptr;
77 if (flags & MREMAP_FIXED)
78 {
79 va_list a;
80 va_start(a, flags);
81 resptr = va_arg(a, void *);
82 va_end(a);
83 }
84
85 int r = L4B(mremap(old_addr, old_size, new_size, flags, &resptr));
86 if (r < 0)
87 {
88 errno = -r;
89 return MAP_FAILED;
90 }
91
92 return resptr;
93 }
94
95 static void *current_morecore_end;
96
uclibc_morecore(long bytes)97 void *uclibc_morecore(long bytes)
98 {
99 // calling morecore with 0 size is done by the malloc implementation
100 // to check for the amount of memory it got from the last call to morecore
101 // With a negative value, 'free' wants to return memory, we do not support
102 // that here.
103 if (bytes <= 0)
104 return current_morecore_end;
105
106 size_t s = l4_round_page(bytes);
107 void *b = mmap2(0, s, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
108 if (L4_UNLIKELY(b == MAP_FAILED))
109 return b;
110
111 current_morecore_end = static_cast<char *>(b) + s;
112 return b;
113 }
114
115