00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef ABSL_BASE_INTERNAL_DIRECT_MMAP_H_
00019 #define ABSL_BASE_INTERNAL_DIRECT_MMAP_H_
00020
00021 #include "absl/base/config.h"
00022
00023 #if ABSL_HAVE_MMAP
00024
00025 #include <sys/mman.h>
00026
00027 #ifdef __linux__
00028
00029 #include <sys/types.h>
00030 #ifdef __BIONIC__
00031 #include <sys/syscall.h>
00032 #else
00033 #include <syscall.h>
00034 #endif
00035
00036 #include <linux/unistd.h>
00037 #include <unistd.h>
00038 #include <cerrno>
00039 #include <cstdarg>
00040 #include <cstdint>
00041
00042 #ifdef __mips__
00043
00044 #ifdef __BIONIC__
00045
00046
00047 #include <asm/sgidefs.h>
00048 #else
00049 #include <sgidefs.h>
00050 #endif // __BIONIC__
00051 #endif // __mips__
00052
00053
00054 #ifdef __BIONIC__
00055 extern "C" void* __mmap2(void*, size_t, int, int, int, size_t);
00056 #if defined(__NR_mmap) && !defined(SYS_mmap)
00057 #define SYS_mmap __NR_mmap
00058 #endif
00059 #ifndef SYS_munmap
00060 #define SYS_munmap __NR_munmap
00061 #endif
00062 #endif // __BIONIC__
00063
00064 namespace absl {
00065 namespace base_internal {
00066
00067
00068
00069 inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd,
00070 off64_t offset) noexcept {
00071 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
00072 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
00073 (defined(__PPC__) && !defined(__PPC64__)) || \
00074 (defined(__s390__) && !defined(__s390x__))
00075
00076 static int pagesize = 0;
00077 if (pagesize == 0) {
00078 #if defined(__wasm__) || defined(__asmjs__)
00079 pagesize = getpagesize();
00080 #else
00081 pagesize = sysconf(_SC_PAGESIZE);
00082 #endif
00083 }
00084 if (offset < 0 || offset % pagesize != 0) {
00085 errno = EINVAL;
00086 return MAP_FAILED;
00087 }
00088 #ifdef __BIONIC__
00089
00090
00091 return __mmap2(start, length, prot, flags, fd, offset / pagesize);
00092 #else
00093 return reinterpret_cast<void*>(
00094 syscall(SYS_mmap2, start, length, prot, flags, fd,
00095 static_cast<off_t>(offset / pagesize)));
00096 #endif
00097 #elif defined(__s390x__)
00098
00099 unsigned long buf[6] = {reinterpret_cast<unsigned long>(start),
00100 static_cast<unsigned long>(length),
00101 static_cast<unsigned long>(prot),
00102 static_cast<unsigned long>(flags),
00103 static_cast<unsigned long>(fd),
00104 static_cast<unsigned long>(offset)};
00105 return reinterpret_cast<void*>(syscall(SYS_mmap, buf));
00106 #elif defined(__x86_64__)
00107
00108
00109
00110
00111
00112
00113 #define MMAP_SYSCALL_ARG(x) ((uint64_t)(uintptr_t)(x))
00114 return reinterpret_cast<void*>(
00115 syscall(SYS_mmap, MMAP_SYSCALL_ARG(start), MMAP_SYSCALL_ARG(length),
00116 MMAP_SYSCALL_ARG(prot), MMAP_SYSCALL_ARG(flags),
00117 MMAP_SYSCALL_ARG(fd), static_cast<uint64_t>(offset)));
00118 #undef MMAP_SYSCALL_ARG
00119 #else // Remaining 64-bit aritectures.
00120 static_assert(sizeof(unsigned long) == 8, "Platform is not 64-bit");
00121 return reinterpret_cast<void*>(
00122 syscall(SYS_mmap, start, length, prot, flags, fd, offset));
00123 #endif
00124 }
00125
00126 inline int DirectMunmap(void* start, size_t length) {
00127 return static_cast<int>(syscall(SYS_munmap, start, length));
00128 }
00129
00130 }
00131 }
00132
00133 #else // !__linux__
00134
00135
00136
00137
00138 namespace absl {
00139 namespace base_internal {
00140
00141 inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd,
00142 off_t offset) {
00143 return mmap(start, length, prot, flags, fd, offset);
00144 }
00145
00146 inline int DirectMunmap(void* start, size_t length) {
00147 return munmap(start, length);
00148 }
00149
00150 }
00151 }
00152
00153 #endif // __linux__
00154
00155 #endif // ABSL_HAVE_MMAP
00156
00157 #endif // ABSL_BASE_INTERNAL_DIRECT_MMAP_H_