diff options
Diffstat (limited to 'ndk/sources/android/libportable/arch-mips/mmap.c')
| -rw-r--r-- | ndk/sources/android/libportable/arch-mips/mmap.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/ndk/sources/android/libportable/arch-mips/mmap.c b/ndk/sources/android/libportable/arch-mips/mmap.c new file mode 100644 index 000000000..d165e2b3e --- /dev/null +++ b/ndk/sources/android/libportable/arch-mips/mmap.c @@ -0,0 +1,93 @@ +/* + * Copyright 2012, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <unistd.h> +#include <errno.h> +#include <sys/mman.h> +#include <mman_portable.h> + +#if MAP_ANONYMOUS_PORTABLE==MAP_ANONYMOUS +#error Bad build environment +#endif + +static inline int mips_change_prot(int prot) +{ + /* Only PROT_SEM is different */ + if (prot & PROT_SEM_PORTABLE) { + prot &= ~PROT_SEM_PORTABLE; + prot |= PROT_SEM; + } + + return prot; +} + +static inline int mips_change_flags(int flags) +{ + int mipsflags = 0; + if (flags & MAP_SHARED_PORTABLE) + mipsflags |= MAP_SHARED; + if (flags & MAP_PRIVATE_PORTABLE) + mipsflags |= MAP_PRIVATE; + if (flags & MAP_FIXED_PORTABLE) + mipsflags |= MAP_FIXED; + if (flags & MAP_ANONYMOUS_PORTABLE) + mipsflags |= MAP_ANONYMOUS; + if (flags & MAP_GROWSDOWN_PORTABLE) + mipsflags |= MAP_GROWSDOWN; + if (flags & MAP_DENYWRITE_PORTABLE) + mipsflags |= MAP_DENYWRITE; + if (flags & MAP_EXECUTABLE_PORTABLE) + mipsflags |= MAP_EXECUTABLE; + if (flags & MAP_LOCKED_PORTABLE) + mipsflags |= MAP_LOCKED; + if (flags & MAP_NORESERVE_PORTABLE) + mipsflags |= MAP_NORESERVE; + if (flags & MAP_POPULATE_PORTABLE) + mipsflags |= MAP_POPULATE; + if (flags & MAP_NONBLOCK_PORTABLE) + mipsflags |= MAP_NONBLOCK; + + return mipsflags; +} + +#define MMAP2_SHIFT 12 +extern void *__mmap2(void *, size_t, int, int, int, size_t); +void *mmap_portable(void *addr, size_t size, int prot, int flags, int fd, long offset) +{ + void *ret; + int mips_prot, mips_flags; + + if (offset & ((1UL << MMAP2_SHIFT)-1)) { + errno = EINVAL; + return MAP_FAILED; + } + + mips_prot = mips_change_prot(prot); + mips_flags = mips_change_flags(flags); + ret = __mmap2(addr, size, mips_prot, mips_flags, fd, + (size_t)offset >> MMAP2_SHIFT); + + if (ret && (mips_flags & (MAP_PRIVATE | MAP_ANONYMOUS))) + madvise(ret, size, MADV_MERGEABLE); + + return ret; +} + +extern int mprotect(const void *, size_t, int); +int mprotect_portable(const void *addr, size_t size, int prot) +{ + return mprotect(addr, size, mips_change_prot(prot)); +} |
