1/*
2 * Copyright 2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <portability.h>
18#include <unistd.h>
19#include <errno.h>
20#include <sys/mman.h>
21#include <mman_portable.h>
22
23#if MAP_ANONYMOUS_PORTABLE==MAP_ANONYMOUS
24#error Bad build environment
25#endif
26
27#define PORTABLE_TAG "mmap_portable"
28#include <log_portable.h>
29
30static inline int mmap_prot_pton(int portable_prot)
31{
32    int native_prot = portable_prot;
33
34    ALOGV("%s(portable_prot:0x%x) {", __func__, portable_prot);
35
36    /* Only PROT_SEM is different */
37    if (portable_prot & PROT_SEM_PORTABLE) {
38        native_prot &= ~PROT_SEM_PORTABLE;
39        native_prot |= PROT_SEM;
40    }
41
42    ALOGV("%s: return(native_prot:0x%x); }", __func__, native_prot);
43    return native_prot;
44}
45
46
47static inline int mmap_flags_pton(int portable_flags)
48{
49    int native_flags = 0;
50
51    ALOGV("%s(portable_flags:0x%x) {", __func__, portable_flags);
52
53    if (portable_flags & MAP_SHARED_PORTABLE) {
54       native_flags |= MAP_SHARED;
55    }
56    if (portable_flags & MAP_PRIVATE_PORTABLE) {
57       native_flags |= MAP_PRIVATE;
58    }
59    if (portable_flags & MAP_FIXED_PORTABLE) {
60       native_flags |= MAP_FIXED;
61    }
62    if (portable_flags & MAP_ANONYMOUS_PORTABLE) {
63       native_flags |= MAP_ANONYMOUS;
64    }
65    if (portable_flags & MAP_GROWSDOWN_PORTABLE) {
66       native_flags |= MAP_GROWSDOWN;
67    }
68    if (portable_flags & MAP_DENYWRITE_PORTABLE) {
69       native_flags |= MAP_DENYWRITE;
70    }
71    if (portable_flags & MAP_EXECUTABLE_PORTABLE) {
72       native_flags |= MAP_EXECUTABLE;
73    }
74    if (portable_flags & MAP_LOCKED_PORTABLE) {
75       native_flags |= MAP_LOCKED;
76    }
77    if (portable_flags & MAP_NORESERVE_PORTABLE) {
78       native_flags |= MAP_NORESERVE;
79    }
80    if (portable_flags & MAP_POPULATE_PORTABLE) {
81       native_flags |= MAP_POPULATE;
82    }
83    if (portable_flags & MAP_NONBLOCK_PORTABLE) {
84       native_flags |= MAP_NONBLOCK;
85    }
86
87    ALOGV("%s: return(native_flags:0x%x); }", __func__, native_flags);
88    return native_flags;
89}
90
91extern void* REAL(mmap)(void *, size_t, int, int, int, off_t);
92void *WRAP(mmap)(void *addr, size_t size, int prot, int flags, int fd, long byte_offset)
93{
94    int native_prot, native_flags;
95    int saved_errno;
96    void *ret_addr;
97
98    ALOGV(" ");
99    ALOGV("%s(addr:%p, size:%d, prot:0x%x, flags:0x%x, fd:%d, byte_offset:0x%lx) {", __func__,
100              addr,    size,    prot,      flags,      fd,    byte_offset);
101
102    native_prot = mmap_prot_pton(prot);
103    native_flags = mmap_flags_pton(flags);
104
105    ret_addr = REAL(mmap)(addr, size, native_prot, native_flags, fd, byte_offset);
106
107    ALOGV("%s: return(ret_addr:%p); }", __func__, ret_addr);
108    return ret_addr;
109}
110
111
112extern int mprotect(const void *, size_t, int);
113
114int WRAP(mprotect)(const void *addr, size_t size, int portable_prot)
115{
116    int rv;
117    int native_prot;
118
119    ALOGV(" ");
120    ALOGV("%s(addr:%p, size:%d, portable_prot:0x%x); {", __func__,
121              addr,    size,    portable_prot);
122
123    native_prot = mmap_prot_pton(portable_prot);
124
125    rv = REAL(mprotect)(addr, size, native_prot);
126
127    ALOGV("%s: return(rv:%d); }", __func__, rv);
128    return rv;
129}
130