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