crashpad/compat/android/sys/mman_mmap.cc
Mark Mentovai b9c828ea83 android: Fix “gn analyze”
On Android, the compat library built compat/android/sys/mman.cc, which
provides a fallback for mmap, and compat/linux/sys/mman.cc, which
provides a fallback for memfd_create. This can result in two object
files colliding in the library, which is flagged as a “gn analyze”
error:

> ERROR at //crashpad/compat/BUILD.gn:62:5: Duplicate object file
>     static_library(target_name) {
>     ^----------------------------
> The target //crashpad/compat:compat
> generates two object files with the same name:
>   obj/crashpad/compat/compat/mman.o
>
> It could be you accidentally have a file listed twice in the
> sources. Or, depending on how your toolchain maps sources to
> object files, two source files with the same name in different
> directories could map to the same object file.
>
> In the latter case, either rename one of the files or move one of
> the sources to a separate source_set to avoid them both being in
> the same target.

The files are renamed to avoid this collision. The associated headers
cannot be renamed because they need to shadow the SDK’s copies. There is
no “gn analyze” conflict reported for headers with the same name.

Change-Id: Ia49ef5ff8375673395597e96555f72f7c69e3564
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2285965
Commit-Queue: Mark Mentovai <mark@chromium.org>
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2020-07-08 13:53:20 +00:00

106 lines
3.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// 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 <sys/mman.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include "dlfcn_internal.h"
#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ < 21
// Bionic has provided a wrapper for __mmap2() since the beginning of time. See
// bionic/libc/SYSCALLS.TXT in any Android version.
extern "C" void* __mmap2(void* addr,
size_t size,
int prot,
int flags,
int fd,
size_t pgoff);
namespace {
template <typename T>
T Align(T value, size_t alignment) {
return (value + alignment - 1) & ~(alignment - 1);
}
// Adapted from Android 8.0.0 bionic/libc/bionic/mmap.cpp.
void* LocalMmap64(void* addr,
size_t size,
int prot,
int flags,
int fd,
off64_t offset) {
constexpr int kMmap2Shift = 12;
if (offset < 0 || (offset & ((1UL << kMmap2Shift) - 1)) != 0) {
errno = EINVAL;
return MAP_FAILED;
}
const size_t rounded = Align(size, getpagesize());
if (rounded < size || rounded > PTRDIFF_MAX) {
errno = ENOMEM;
return MAP_FAILED;
}
const bool is_private_anonymous =
(flags & (MAP_PRIVATE | MAP_ANONYMOUS)) == (MAP_PRIVATE | MAP_ANONYMOUS);
const bool is_stack_or_grows_down =
(flags & (MAP_STACK | MAP_GROWSDOWN)) != 0;
void* const result =
__mmap2(addr, size, prot, flags, fd, offset >> kMmap2Shift);
static bool kernel_has_MADV_MERGEABLE = true;
if (result != MAP_FAILED && kernel_has_MADV_MERGEABLE &&
is_private_anonymous && !is_stack_or_grows_down) {
const int saved_errno = errno;
const int rc = madvise(result, size, MADV_MERGEABLE);
if (rc == -1 && errno == EINVAL) {
kernel_has_MADV_MERGEABLE = false;
}
errno = saved_errno;
}
return result;
}
} // namespace
extern "C" {
void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) {
// Use the systems mmap64() wrapper if available. It will be available on
// Android 5.0 (“Lollipop”) and later.
using Mmap64Type = void* (*)(void*, size_t, int, int, int, off64_t);
static const Mmap64Type mmap64 = reinterpret_cast<Mmap64Type>(
crashpad::internal::Dlsym(RTLD_DEFAULT, "mmap64"));
if (mmap64) {
return mmap64(addr, size, prot, flags, fd, offset);
}
// Otherwise, use the local implementation, which should amount to exactly the
// same thing.
return LocalMmap64(addr, size, prot, flags, fd, offset);
}
} // extern "C"
#endif // defined(__USE_FILE_OFFSET64) && __ANDROID_API__ < 21