-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- a0673e81da7ee7e322283e518331a4cdaeca837b Internal change by Abseil…
… Team <absl-team@google.com> - 537e863510a423968c2d319263dd1c100695a2e9 Add internal-only functionality to examine the stack, to ... by Derek Mauro <dmauro@google.com> - 1ded12406d8b8fd7be910c8dfe8c2a8edf66136e Explicitly suppress the default move constructor and assi... by Derek Mauro <dmauro@google.com> - 347d38447ebc38e5d33fec6b67988880eb3cd249 Move implementation detail do_mmap64 to a new file. by Greg Falcon <gfalcon@google.com> GitOrigin-RevId: a0673e81da7ee7e322283e518331a4cdaeca837b Change-Id: I5a347d34d5173082b3a78eb53432481b32c94b69
- Loading branch information
1 parent
475d64f
commit a7e522d
Showing
5 changed files
with
186 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// Copyright 2017 The Abseil Authors. | ||
// | ||
// 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. | ||
// | ||
// Functions for directly invoking mmap() via syscall, avoiding the case where | ||
// mmap() has been locally overridden. | ||
|
||
#ifndef ABSL_BASE_INTERNAL_DIRECT_MMAP_H_ | ||
#define ABSL_BASE_INTERNAL_DIRECT_MMAP_H_ | ||
|
||
#include "absl/base/config.h" | ||
|
||
#if ABSL_HAVE_MMAP | ||
|
||
#include <sys/mman.h> | ||
|
||
#ifdef __linux__ | ||
|
||
#include <sys/types.h> | ||
#ifdef __BIONIC__ | ||
#include <sys/syscall.h> | ||
#else | ||
#include <syscall.h> | ||
#endif | ||
|
||
#include <linux/unistd.h> | ||
#include <unistd.h> | ||
#include <cerrno> | ||
#include <cstdarg> | ||
#include <cstdint> | ||
|
||
#ifdef __mips__ | ||
// Include definitions of the ABI currently in use. | ||
#ifdef __BIONIC__ | ||
// Android doesn't have sgidefs.h, but does have asm/sgidefs.h, which has the | ||
// definitions we need. | ||
#include <asm/sgidefs.h> | ||
#else | ||
#include <sgidefs.h> | ||
#endif // __BIONIC__ | ||
#endif // __mips__ | ||
|
||
// SYS_mmap and SYS_munmap are not defined in Android. | ||
#ifdef __BIONIC__ | ||
extern "C" void* __mmap2(void*, size_t, int, int, int, long); | ||
#if defined(__NR_mmap) && !defined(SYS_mmap) | ||
#define SYS_mmap __NR_mmap | ||
#endif | ||
#ifndef SYS_munmap | ||
#define SYS_munmap __NR_munmap | ||
#endif | ||
#endif // __BIONIC__ | ||
|
||
namespace absl { | ||
namespace base_internal { | ||
|
||
// Platform specific logic extracted from | ||
// https://chromium.googlesource.com/linux-syscall-support/+/master/linux_syscall_support.h | ||
inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd, | ||
off64_t offset) __THROW { | ||
#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ | ||
(defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ | ||
(defined(__PPC__) && !defined(__PPC64__)) || \ | ||
(defined(__s390__) && !defined(__s390x__)) | ||
// On these architectures, implement mmap with mmap2. | ||
static int pagesize = 0; | ||
if (pagesize == 0) { | ||
pagesize = getpagesize(); | ||
} | ||
if (offset < 0 || offset % pagesize != 0) { | ||
errno = EINVAL; | ||
return MAP_FAILED; | ||
} | ||
#ifdef __BIONIC__ | ||
// SYS_mmap2 has problems on Android API level <= 16. | ||
// Workaround by invoking __mmap2() instead. | ||
return __mmap2(start, length, prot, flags, fd, offset / pagesize); | ||
#else | ||
return reinterpret_cast<void*>( | ||
syscall(SYS_mmap2, start, length, prot, flags, fd, | ||
static_cast<off_t>(offset / pagesize))); | ||
#endif | ||
#elif defined(__s390x__) | ||
// On s390x, mmap() arguments are passed in memory. | ||
uint32_t buf[6] = { | ||
reinterpret_cast<uint32_t>(start), static_cast<uint32_t>(length), | ||
static_cast<uint32_t>(prot), static_cast<uint32_t>(flags), | ||
static_cast<uint32_t>(fd), static_cast<uint32_t>(offset)}; | ||
return reintrepret_cast<void*>(syscall(SYS_mmap, buf)); | ||
#elif defined(__x86_64__) | ||
// The x32 ABI has 32 bit longs, but the syscall interface is 64 bit. | ||
// We need to explicitly cast to an unsigned 64 bit type to avoid implicit | ||
// sign extension. We can't cast pointers directly because those are | ||
// 32 bits, and gcc will dump ugly warnings about casting from a pointer | ||
// to an integer of a different size. We also need to make sure __off64_t | ||
// isn't truncated to 32-bits under x32. | ||
#define MMAP_SYSCALL_ARG(x) ((uint64_t)(uintptr_t)(x)) | ||
return reinterpret_cast<void*>( | ||
syscall(SYS_mmap, MMAP_SYSCALL_ARG(start), MMAP_SYSCALL_ARG(length), | ||
MMAP_SYSCALL_ARG(prot), MMAP_SYSCALL_ARG(flags), | ||
MMAP_SYSCALL_ARG(fd), static_cast<uint64_t>(offset))); | ||
#undef MMAP_SYSCALL_ARG | ||
#else // Remaining 64-bit aritectures. | ||
static_assert(sizeof(unsigned long) == 8, "Platform is not 64-bit"); | ||
return reinterpret_cast<void*>( | ||
syscall(SYS_mmap, start, length, prot, flags, fd, offset)); | ||
#endif | ||
} | ||
|
||
inline int DirectMunmap(void* start, size_t length) { | ||
return static_cast<int>(syscall(SYS_munmap, start, length)); | ||
} | ||
|
||
} // namespace base_internal | ||
} // namespace absl | ||
|
||
#else // !__linux__ | ||
|
||
// For non-linux platforms where we have mmap, just dispatch directly to the | ||
// actual mmap()/munmap() methods. | ||
|
||
inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd, | ||
off_t offset) { | ||
return mmap(start, length, prot, flags, fd, offset); | ||
} | ||
|
||
inline int DirectMunmap(void* start, size_t length) { | ||
return munmap(start, length); | ||
} | ||
|
||
#endif // __linux__ | ||
|
||
#endif // ABSL_HAVE_MMAP | ||
|
||
#endif // ABSL_BASE_INTERNAL_DIRECT_MMAP_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters