Updated to arc-runtime-43.4410.311.0
diff --git a/mods/android/system/core/libutils/SystemClock.cpp b/mods/android/system/core/libutils/SystemClock.cpp
deleted file mode 100644
index 229c881..0000000
--- a/mods/android/system/core/libutils/SystemClock.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-
-/*
- * System clock functions.
- */
-
-#ifdef HAVE_ANDROID_OS
-/* ARC MOD BEGIN */
-#if !defined(HAVE_ARC)
-# include <linux/ioctl.h>
-# include <linux/rtc.h>
-#endif
-/* ARC MOD END */
-#include <utils/Atomic.h>
-#include <linux/android_alarm.h>
-#endif
-
-#include <sys/time.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-
-#include <utils/SystemClock.h>
-#include <utils/Timers.h>
-
-#define LOG_TAG "SystemClock"
-#include <utils/Log.h>
-
-namespace android {
-
-/*
- * native public static long uptimeMillis();
- */
-int64_t uptimeMillis()
-{
- int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- return (int64_t) nanoseconds_to_milliseconds(when);
-}
-
-/*
- * native public static long elapsedRealtime();
- */
-int64_t elapsedRealtime()
-{
- return nanoseconds_to_milliseconds(elapsedRealtimeNano());
-}
-
-#define METHOD_CLOCK_GETTIME 0
-#define METHOD_IOCTL 1
-#define METHOD_SYSTEMTIME 2
-
-/*
- * To debug/verify the timestamps returned by the kernel, change
- * DEBUG_TIMESTAMP to 1 and call the timestamp routine from a single thread
- * in the test program. b/10899829
- */
-#define DEBUG_TIMESTAMP 0
-
-static const char *gettime_method_names[] = {
- "clock_gettime",
- "ioctl",
- "systemTime",
-};
-
-#if DEBUG_TIMESTAMP
-static inline void checkTimeStamps(int64_t timestamp,
- int64_t volatile *prevTimestampPtr,
- int volatile *prevMethodPtr,
- int curMethod)
-{
- /*
- * Disable the check for SDK since the prebuilt toolchain doesn't contain
- * gettid, and int64_t is different on the ARM platform
- * (ie long vs long long).
- */
-#ifdef ARCH_ARM
- int64_t prevTimestamp = *prevTimestampPtr;
- int prevMethod = *prevMethodPtr;
-
- if (timestamp < prevTimestamp) {
- ALOGW("time going backwards: prev %lld(%s) vs now %lld(%s), tid=%d",
- prevTimestamp, gettime_method_names[prevMethod],
- timestamp, gettime_method_names[curMethod],
- gettid());
- }
- // NOTE - not atomic and may generate spurious warnings if the 64-bit
- // write is interrupted or not observed as a whole.
- *prevTimestampPtr = timestamp;
- *prevMethodPtr = curMethod;
-#endif
-}
-#else
-#define checkTimeStamps(timestamp, prevTimestampPtr, prevMethodPtr, curMethod)
-#endif
-
-/*
- * native public static long elapsedRealtimeNano();
- */
-int64_t elapsedRealtimeNano()
-{
-/* ARC MOD BEGIN */
-// /dev/alarm is not available on non-Android kernel.
-#if defined HAVE_ANDROID_OS && !(defined HAVE_ARC)
-/* ARC MOD END */
- struct timespec ts;
- int result;
- int64_t timestamp;
-#if DEBUG_TIMESTAMP
- static volatile int64_t prevTimestamp;
- static volatile int prevMethod;
-#endif
-
-#if 0
- /*
- * b/7100774
- * clock_gettime appears to have clock skews and can sometimes return
- * backwards values. Disable its use until we find out what's wrong.
- */
- result = clock_gettime(CLOCK_BOOTTIME, &ts);
- if (result == 0) {
- timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
- checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,
- METHOD_CLOCK_GETTIME);
- return timestamp;
- }
-#endif
-
- // CLOCK_BOOTTIME doesn't exist, fallback to /dev/alarm
- static int s_fd = -1;
-
- if (s_fd == -1) {
- int fd = open("/dev/alarm", O_RDONLY);
- if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
- close(fd);
- }
- }
-
- result = ioctl(s_fd,
- ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
-
- if (result == 0) {
- timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
- checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL);
- return timestamp;
- }
-
- // XXX: there was an error, probably because the driver didn't
- // exist ... this should return
- // a real error, like an exception!
- timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
- checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,
- METHOD_SYSTEMTIME);
- return timestamp;
-#else
- return systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
-}
-
-}; // namespace android
diff --git a/src/build/DEPS.arc-int b/src/build/DEPS.arc-int
index 7c16ce3..2269354 100644
--- a/src/build/DEPS.arc-int
+++ b/src/build/DEPS.arc-int
@@ -1 +1 @@
-d87cf4906a273dec40ed6249aa23555fbc1223e4
+178e78eb874a8ad7bec6dfdbbde99015f543c30d
diff --git a/src/build/ninja_generator.py b/src/build/ninja_generator.py
index caf90a7..c5f9d38 100644
--- a/src/build/ninja_generator.py
+++ b/src/build/ninja_generator.py
@@ -908,11 +908,12 @@
self.add_include_paths('android/bionic/libc/include')
if gl_flags:
self.emit_gl_common_flags()
- # We need 4-byte alignment to pass host function pointers to arm code.
- if not self._is_host and not OPTIONS.is_nacl_build():
- self.add_compiler_flags('-falign-functions=4')
self._enable_clang = (enable_clang and
toolchain.has_clang(OPTIONS.target(), self._is_host))
+ # We need 4-byte alignment to pass host function pointers to arm code.
+ if (not self._is_host and not OPTIONS.is_nacl_build() and
+ not self._enable_clang):
+ self.add_compiler_flags('-falign-functions=4')
self._object_list = []
self._shared_deps = []
self._static_deps = []
@@ -3604,9 +3605,6 @@
class AaptNinjaGenerator(NinjaGenerator):
"""Implements a simple aapt package generator."""
- _resource_paths = []
- _assets_path = None
-
def __init__(self, module_name, base_path, manifest, intermediates,
install_path=None, **kwargs):
super(AaptNinjaGenerator, self).__init__(
@@ -3614,6 +3612,8 @@
self._manifest = manifest
self._intermediates = intermediates
self._install_path = install_path
+ self._resource_paths = []
+ self._assets_path = None
def add_resource_paths(self, paths):
self._resource_paths += paths
diff --git a/src/build/staging.py b/src/build/staging.py
index 688218d..7b6d33d 100755
--- a/src/build/staging.py
+++ b/src/build/staging.py
@@ -212,7 +212,7 @@
for dirpath, dirs, fnames in os.walk(root):
for name in fnames:
link_path = os.path.join(dirpath, name)
- if os.path.islink(link_path):
+ if os.path.islink(link_path) and os.path.isfile(link_path):
link_target_map[link_path] = os.readlink(link_path)
return link_target_map
@@ -247,11 +247,36 @@
# Update modification time for files that do not point to the same location
# that they pointed to in the previous tree to make sure they are built.
- new_staging_links = _get_link_targets(staging_root)
- for key in new_staging_links:
- if key in old_staging_links:
- if old_staging_links[key] != new_staging_links[key]:
- os.utime(key, None)
+
+ if old_staging_links:
+ new_staging_links = _get_link_targets(staging_root)
+
+ # Every file under staging is in either one of following two states:
+ #
+ # F. The file itself is a symbolic link to a file under third_party or
+ # mods.
+ # D. Some ancestor directory is a symbolic link to a directory under
+ # third_party. (It is important that we do not create symbolic links to
+ # directories under mods)
+ #
+ # Note that a file is in state F if and only if it is in |*_staging_links|
+ # dictionary. Let us say a file falls under "X-Y" case if it was in state X
+ # before re-staging and now in state Y. For all 4 possible cases, we can
+ # check if the actual destination of the file changed or not in the
+ # following way:
+ #
+ # F-F: We can just compare the target of the link.
+ # F-D, D-F: The target may have changed, but it needs some complicated
+ # computation to check. We treat them as changed to be conservative.
+ # D-D: We can leave it as-is since both point third_party.
+
+ for path in set(list(old_staging_links) + list(new_staging_links)):
+ if path in old_staging_links and path in new_staging_links:
+ should_touch = old_staging_links[path] != new_staging_links[path]
+ else:
+ should_touch = True
+ if should_touch and os.path.exists(path):
+ os.utime(path, None)
timer.done()
return True
diff --git a/src/common/arc_strace.cc b/src/common/arc_strace.cc
index e75c71b..c915e80 100644
--- a/src/common/arc_strace.cc
+++ b/src/common/arc_strace.cc
@@ -10,6 +10,7 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <linux/android_alarm.h> // ANDROID_ALARM_*
#include <linux/ashmem.h> // ASHMEM_*
#include <linux/sched.h> // SCHED_BATCH
#include <linux/sync.h> // SYNC_IOC_*
@@ -675,6 +676,14 @@
g_arc_strace->ResetStats();
}
+std::string GetStraceEnterString(const char* name, const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ std::string body = base::StringPrintV(format, ap);
+ va_end(ap);
+ return base::StringPrintf("%s(%s)", name, body.c_str());
+}
+
void StraceInit(const std::string& plugin_type_prefix) {
ALOG_ASSERT(!g_arc_strace);
if (Options::GetInstance()->enable_arc_strace) {
@@ -776,8 +785,9 @@
}
std::string GetFdStr(int fd) {
- ALOG_ASSERT(g_arc_strace);
- const std::string result = g_arc_strace->GetFdString(fd);
+ std::string result;
+ if (g_arc_strace)
+ result = g_arc_strace->GetFdString(fd);
return result.empty() ? "???" : result;
}
@@ -1169,6 +1179,8 @@
std::string result;
switch (request) {
CASE_APPEND_ENUM_STR(FIONREAD, result);
+ CASE_APPEND_ENUM_STR(ANDROID_ALARM_WAIT, result);
+ CASE_APPEND_ENUM_STR(ANDROID_ALARM_SET_RTC, result);
default: {
// Unable to write switch-case since Bionic ioctl.h enables _IOC_TYPECHECK
// which is not allowed in constant expression.
@@ -1200,6 +1212,38 @@
} else if (urequest == ASHMEM_PURGE_ALL_CACHES) {
AppendResult("ASHMEM_PURGE_ALL_CACHES", &result);
} else {
+ int android_alarm_cmd = ANDROID_ALARM_BASE_CMD(request);
+ int android_alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(request);
+ std::string cmd_str;
+ // To get command value, passing "0" for each macro.
+ switch (android_alarm_cmd) {
+ case ANDROID_ALARM_GET_TIME(0):
+ cmd_str = "ANDROID_ALARM_GET_TIME";
+ break;
+ case ANDROID_ALARM_CLEAR(0):
+ cmd_str = "ANDROID_ALARM_CLEAR";
+ break;
+ case ANDROID_ALARM_SET_AND_WAIT(0):
+ cmd_str = "ANDROID_ALARM_SET_AND_WAIT";
+ break;
+ case ANDROID_ALARM_SET(0):
+ cmd_str = "ANDROID_ALARM_SET";
+ break;
+ }
+ std::string type_str;
+ switch (android_alarm_type) {
+ CASE_APPEND_ENUM_STR(ANDROID_ALARM_RTC_WAKEUP, type_str);
+ CASE_APPEND_ENUM_STR(ANDROID_ALARM_RTC, type_str);
+ CASE_APPEND_ENUM_STR(ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, type_str);
+ CASE_APPEND_ENUM_STR(ANDROID_ALARM_ELAPSED_REALTIME, type_str);
+ CASE_APPEND_ENUM_STR(ANDROID_ALARM_SYSTEMTIME, type_str);
+ }
+
+ if (!cmd_str.empty() && !type_str.empty()) {
+ result = cmd_str + "(" + type_str + ")";
+ break;
+ }
+
AppendResult(base::StringPrintf("%d???", request), &result);
}
}
diff --git a/src/common/arc_strace.h b/src/common/arc_strace.h
index 7f39852..b3a1a25 100644
--- a/src/common/arc_strace.h
+++ b/src/common/arc_strace.h
@@ -74,6 +74,8 @@
void StraceDupFD(int oldfd, int newfd);
void StraceDumpStats(const std::string& user_str);
void StraceResetStats();
+std::string GetStraceEnterString(const char* name, const char* format, ...)
+ ATTR_PRINTF(2, 3);
// Pretty printers for enum values.
std::string GetAccessModeStr(int mode);
@@ -81,7 +83,6 @@
std::string GetDlopenFlagStr(int flag);
std::string GetEpollCtlOpStr(int op);
std::string GetEpollEventStr(uint32_t events);
-std::string GetFdStr(int fd);
std::string GetMadviseAdviceStr(int advice);
std::string GetMmapProtStr(int prot);
std::string GetMmapFlagStr(int flag);
@@ -98,6 +99,10 @@
std::string GetFcntlCommandStr(int cmd);
std::string GetIoctlRequestStr(int request);
+// A pretty printer for file descriptors. You can call this even when ARC-strace
+// is not enabled, but in that case, the function returns "???".
+std::string GetFdStr(int fd);
+
// Pretty printers for struct values.
std::string GetSockaddrStr(const struct sockaddr* addr, socklen_t addrlen);
std::string GetDirentStr(const struct dirent* ent);
@@ -125,19 +130,64 @@
// display variable arguments. You must call ARC_STRACE_RETURN* if
// you called this.
//
+// Note: Unlike others, this macro emits TWO blocks. Use with caution.
+//
// TODO(crbug.com/345825): Reorganize the macros.
-# define ARC_STRACE_ENTER(...) do { \
- if (arc::StraceEnabled()) \
- arc::StraceEnter(__VA_ARGS__); \
+# define ARC_STRACE_ENTER(...) \
+ /* Remember the parameters passed to the macro without evaluating them. */ \
+ auto arc_strace_get_enter_string__ \
+ __attribute__((unused)) = [&]() -> std::string { /* NOLINT(build/c++11) */ \
+ return arc::GetStraceEnterString(__VA_ARGS__); \
+ }; \
+ do { \
+ if (arc::StraceEnabled()) \
+ arc::StraceEnter(__VA_ARGS__); \
} while (0)
// ARC_STRACE_ENTER_FD(const char* name, const char* format, int fd, ...)
//
// The pathname or stream type of |fd| will be displayed. |format|
// must start with "%d". Otherwise, this is as same as ARC_STRACE_ENTER.
-# define ARC_STRACE_ENTER_FD(...) do { \
- if (arc::StraceEnabled()) \
- arc::StraceEnterFD(__VA_ARGS__); \
+//
+// Note: Unlike others, this macro emits TWO blocks. Use with caution.
+# define ARC_STRACE_ENTER_FD(...) \
+ /* Remember the parameters passed to the macro without evaluating them. */ \
+ auto arc_strace_get_enter_string__ \
+ __attribute__((unused)) = [&]() -> std::string { /* NOLINT(build/c++11) */ \
+ return arc::GetStraceEnterString(__VA_ARGS__); \
+ }; \
+ do { \
+ if (arc::StraceEnabled()) \
+ arc::StraceEnterFD(__VA_ARGS__); \
+ } while (0)
+
+// ARC_STRACE_ALWAYS_WARN_FAILURE()
+//
+// Emits a warning log that contains the current function name,
+// its parameters (pretty-printed), and the current errno.
+// This macro works regardress of whether ARC-strace is enabled or not,
+// but ARC_STRACE_ENTER*() must be called in the same function before
+// this macro is called.
+# define ARC_STRACE_ALWAYS_WARN_FAILURE() do { \
+ /* Do not check arc::StraceEnabled() here, hence 'ALWAYS' */ \
+ ALOGW("FAILED: %s: errno=%d (%s)", \
+ arc_strace_get_enter_string__().c_str(), \
+ errno, safe_strerror(errno).c_str()); \
+ } while (0)
+
+// ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED()
+//
+// Emits a warning log that contains the current function name,
+// its parameters (pretty-printed). This also calls ARC_STRACE_REPORT
+// with "not implemented yet".
+// This macro works regardress of whether ARC-strace is enabled or not,
+// but ARC_STRACE_ENTER*() must be called in the same function before
+// this macro is called.
+# define ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED() do { \
+ /* Do not check arc::StraceEnabled() here, hence 'ALWAYS' */ \
+ ALOGW("NOT IMPLEMENTED: %s", \
+ arc_strace_get_enter_string__().c_str()); \
+ ARC_STRACE_REPORT("not implemented yet"); \
} while (0)
// ARC_STRACE_REPORT_HANDLER(const char* handler_name)
diff --git a/src/common/dlfcn_injection.cc b/src/common/dlfcn_injection.cc
index 99b85e3..8ee1874 100644
--- a/src/common/dlfcn_injection.cc
+++ b/src/common/dlfcn_injection.cc
@@ -75,9 +75,11 @@
// of host's, we inject the syscall function for ARM.
(*g_wrapped_symbol_map)["syscall"] =
reinterpret_cast<void*>(&RunArmLibcSyscall);
- // See src/common/ndk_support/mmap.cc for detail.
+ // See src/common/ndk_support/mmap.h for detail.
(*g_wrapped_symbol_map)["mmap"] =
reinterpret_cast<void*>(&MmapForNdk);
+ (*g_wrapped_symbol_map)["mprotect"] =
+ reinterpret_cast<void*>(&MprotectForNdk);
#endif
// Inject the custom symbol resolver and posix_translation based
diff --git a/src/common/ndk_support/mmap.cc b/src/common/ndk_support/mmap.cc
index fa4e89a..6953636 100644
--- a/src/common/ndk_support/mmap.cc
+++ b/src/common/ndk_support/mmap.cc
@@ -9,7 +9,12 @@
#include <sys/mman.h>
#include <unistd.h>
-#include "common/scoped_pthread_mutex_locker.h"
+#include <string>
+
+#include "base/md5.h"
+#include "common/alog.h"
+#include "common/mprotect_rwx.h"
+#include "common/options.h"
namespace arc {
@@ -17,11 +22,55 @@
uintptr_t g_mmap_hint_addr = 0x70000000;
+bool ShouldAllowDefaultAddressHint() {
+ // For now, we always give the default address hint on SFI NaCl as
+ // the address hint will not be bad for security on SFI NaCl.
+#if defined(__native_client__)
+ return true;
+#else
+ // Old NDK apps require the default address hint. If an app crashes
+ // inside its own copy of the Bionic's linker, saying something like
+ // "no vspace available", you would likely need to flip this.
+ //
+ // As this feature is bad for security, this is only for
+ // testing. You should manually flip this bit to test such apps.
+ // When we need to launch apps which require this, you should ask
+ // the app author to upgrade their runtime.
+ return false;
+#endif
+}
+
+#if defined(USE_NDK_DIRECT_EXECUTION)
+pthread_once_t g_tls_init = PTHREAD_ONCE_INIT;
+bool g_should_allow_rwx_pages;
+
+// We allow a few whitelisted apps to use RWX pages. Although an APK
+// package author can arbitrary choose the package name, this is safe
+// as long as ARC is running for only whitelisted packages.
+// TODO(crbug.com/462642): We need to update this comment and code
+// when we remove ARC whitelist.
+//
+// Please make sure you get an approval from security team when you
+// add an app to this list.
+void InitShouldAllowRwxPages() {
+ const std::string md5 = base::MD5String(
+ Options::GetInstance()->package_name);
+ g_should_allow_rwx_pages = (
+ md5 == "a1b1bbe5f63d5b96c1a0f87c197ebfae" ||
+ md5 == "77f62c7141dd3730bf844c1c55e92b1f");
+}
+
+bool ShouldAllowRwxPages() {
+ pthread_once(&g_tls_init, InitShouldAllowRwxPages);
+ return g_should_allow_rwx_pages;
+}
+#endif
+
} // namespace
void* MmapForNdk(void* addr, size_t length, int prot, int flags,
int fd, off_t offset) {
- if (!addr && !(flags & MAP_FIXED)) {
+ if (!addr && !(flags & MAP_FIXED) && ShouldAllowDefaultAddressHint()) {
// We use 0x70000000 as the first hint address. Then, the next
// hint address will be increased by |length|, so this function
// will likely keep satisfying the limitation of old Bionic's
@@ -33,8 +82,6 @@
//
// Such NDK apps call mmap with NULL |addr| only twice at their
// start-ups. On SFI NaCl these addresses are always not used.
- // TODO(hamaji): Check if ASLR on BMM does never use this region
- // and update the comment and/or code.
//
// Essentially this way we emulate Android's mmap() behavior
// better, by hinting where it shall allocate, if application has
@@ -43,7 +90,39 @@
__sync_fetch_and_add(&g_mmap_hint_addr,
(length + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)));
}
- return mmap(addr, length, prot, flags, fd, offset);
+
+#if defined(USE_NDK_DIRECT_EXECUTION)
+ bool needs_wx_prot = false;
+ if ((prot & PROT_WRITE) && (prot & PROT_EXEC) && ShouldAllowRwxPages()) {
+ prot &= ~PROT_EXEC;
+ needs_wx_prot = true;
+ }
+ // Even when RWX mmap is requested and ShouldAllowRwxPages()
+ // returns false, call normal libc's mmap which will not honor
+ // RWX permissions. See also libc/arch-nacl/syscalls/mmap.c.
+#endif
+
+ void* result = mmap(addr, length, prot, flags, fd, offset);
+
+#if defined(USE_NDK_DIRECT_EXECUTION)
+ if (needs_wx_prot && result != MAP_FAILED) {
+ int r = MprotectRWX(result, length);
+ LOG_ALWAYS_FATAL_IF(r != 0, "RWX mprotect unexpectedly failed");
+ }
+#endif
+
+ return result;
}
+#if defined(USE_NDK_DIRECT_EXECUTION)
+int MprotectForNdk(void* addr, size_t len, int prot) {
+ if ((prot & PROT_WRITE) && (prot & PROT_EXEC) && ShouldAllowRwxPages())
+ return MprotectRWX(addr, len);
+ // Even when RWX mprotect is requested and ShouldAllowRwxPages()
+ // returns false, call normal libc's mprotect which will not honor
+ // RWX permissions. See also libc/arch-nacl/syscalls/mprotect.c.
+ return mprotect(addr, len, prot);
+}
+#endif
+
} // namespace arc
diff --git a/src/common/ndk_support/mmap.h b/src/common/ndk_support/mmap.h
index 2dab9b8..e8e2a05 100644
--- a/src/common/ndk_support/mmap.h
+++ b/src/common/ndk_support/mmap.h
@@ -16,9 +16,17 @@
// https://android.googlesource.com/platform/bionic/+/gingerbread/linker/linker.c
// TODO(olonho): investigate why even with hint 0 linker expects memory
// in certain range. Short ARM branches?
+//
+// Also handle RWX pages for whitelisted apps on Bare Metal mode.
void* MmapForNdk(void* addr, size_t length, int prot, int flags,
int fd, off_t offset);
+#if defined(USE_NDK_DIRECT_EXECUTION)
+// Handles RWX pages for whitelisted apps on Bare Metal mode with NDK
+// direct execution.
+int MprotectForNdk(void* addr, size_t len, int prot);
+#endif
+
} // namespace arc
#endif // COMMON_NDK_SUPPORT_MMAP_H_
diff --git a/src/posix_translation/dev_alarm.cc b/src/posix_translation/dev_alarm.cc
new file mode 100644
index 0000000..591599f
--- /dev/null
+++ b/src/posix_translation/dev_alarm.cc
@@ -0,0 +1,132 @@
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "posix_translation/dev_alarm.h"
+
+#include <linux/android_alarm.h>
+#include <string.h>
+
+#include "posix_translation/dir.h"
+#include "posix_translation/statfs.h"
+#include "posix_translation/virtual_file_system.h"
+
+namespace posix_translation {
+
+namespace {
+
+int DoStatLocked(const std::string& pathname, struct stat* out) {
+ memset(out, 0, sizeof(struct stat));
+ // Follwoing values are from Android device.
+ out->st_dev = 11;
+ out->st_ino =
+ VirtualFileSystem::GetVirtualFileSystem()->GetInodeLocked(pathname);
+ out->st_mode = S_IFCHR | 0664;
+ out->st_nlink = 1;
+ out->st_uid = 1000;
+ out->st_gid = 1001;
+ out->st_rdev = DeviceHandler::GetDeviceId(pathname);
+ out->st_size = 0;
+ out->st_blksize = 4096;
+ out->st_blocks = 0;
+ return 0;
+}
+
+} // namespace
+
+DevAlarmHandler::DevAlarmHandler() : DeviceHandler("DevAlarmHandler") {
+}
+
+DevAlarmHandler::~DevAlarmHandler() {
+}
+
+scoped_refptr<FileStream> DevAlarmHandler::open(
+ int fd, const std::string& pathname, int oflag, mode_t cmode) {
+ if (oflag & O_DIRECTORY) {
+ errno = ENOTDIR;
+ return NULL;
+ }
+ return new DevAlarm(pathname, oflag, boottime_origin_);
+}
+
+int DevAlarmHandler::stat(const std::string& pathname, struct stat* out) {
+ return DoStatLocked(pathname, out);
+}
+
+DevAlarm::DevAlarm(const std::string& pathname, int oflag,
+ const timespec& boottime_origin)
+ : DeviceStream(oflag, pathname) {
+}
+
+DevAlarm::~DevAlarm() {
+}
+
+int DevAlarm::fstat(struct stat* out) {
+ return DoStatLocked(pathname(), out);
+}
+
+ssize_t DevAlarm::read(void* buf, size_t count) {
+ errno = EINVAL;
+ return -1;
+}
+
+ssize_t DevAlarm::write(const void* buf, size_t count) {
+ errno = EBADF;
+ return -1;
+}
+
+int DevAlarm::ioctl(int request, va_list ap) {
+ // The alarm ioctl request is constructed by two part: the upper 4 bits are
+ // for alarm type and lower 4 bits are for alarm command.
+ int command = ANDROID_ALARM_BASE_CMD(request);
+ int alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(request);
+
+ // Getting command value by specifying "0" for each macro.
+ switch (command) {
+ case ANDROID_ALARM_GET_TIME(0):
+ return GetTime(alarm_type, va_arg(ap, timespec*));
+ case ANDROID_ALARM_CLEAR(0):
+ case ANDROID_ALARM_SET_AND_WAIT(0):
+ case ANDROID_ALARM_SET(0):
+ case ANDROID_ALARM_WAIT:
+ case ANDROID_ALARM_SET_RTC:
+ ARC_STRACE_REPORT("ioctl %d for /dev/alarm is not supported.", request);
+ errno = ENOSYS;
+ return -1;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+int DevAlarm::GetTime(int alarm_type, timespec* out) {
+ if (!out) {
+ errno = EFAULT;
+ return -1;
+ }
+ // See http://developer.android.com/reference/android/app/AlarmManager.html
+ // for more details.
+ switch (alarm_type) {
+ case ANDROID_ALARM_RTC_WAKEUP:
+ case ANDROID_ALARM_RTC:
+ clock_gettime(CLOCK_REALTIME, out);
+ return 0;
+ case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:
+ case ANDROID_ALARM_ELAPSED_REALTIME: {
+ // Here, we cannot use other than CLOCK_MONOTONIC since Android calls
+ // clock_gettime(CLOCK_MONOTONIC) for getting uptime.
+ clock_gettime(CLOCK_MONOTONIC, out);
+ return 0;
+ }
+ case ANDROID_ALARM_SYSTEMTIME:
+ clock_gettime(CLOCK_MONOTONIC, out);
+ return 0;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+const char* DevAlarm::GetStreamType() const { return "alarm"; }
+
+} // namespace posix_translation
diff --git a/src/posix_translation/dev_alarm.h b/src/posix_translation/dev_alarm.h
new file mode 100644
index 0000000..adfe585
--- /dev/null
+++ b/src/posix_translation/dev_alarm.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef POSIX_TRANSLATION_DEV_ALARM_H_
+#define POSIX_TRANSLATION_DEV_ALARM_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "common/export.h"
+#include "posix_translation/device_file.h"
+
+namespace posix_translation {
+
+// This handler is for emulating /dev/alarm device in Android.
+class ARC_EXPORT DevAlarmHandler : public DeviceHandler {
+ public:
+ DevAlarmHandler();
+ virtual ~DevAlarmHandler();
+
+ virtual scoped_refptr<FileStream> open(
+ int fd, const std::string& pathname, int oflag, mode_t cmode) OVERRIDE;
+ virtual int stat(const std::string& pathname, struct stat* out) OVERRIDE;
+
+ private:
+ timespec boottime_origin_;
+ DISALLOW_COPY_AND_ASSIGN(DevAlarmHandler);
+};
+
+class DevAlarm : public DeviceStream {
+ public:
+ DevAlarm(const std::string& pathname, int oflag,
+ const timespec& boottime_origin);
+
+ virtual int fstat(struct stat* out) OVERRIDE;
+ virtual ssize_t read(void* buf, size_t count) OVERRIDE;
+ virtual ssize_t write(const void* buf, size_t count) OVERRIDE;
+ virtual int ioctl(int request, va_list ap) OVERRIDE;
+ virtual const char* GetStreamType() const OVERRIDE;
+
+ protected:
+ virtual ~DevAlarm();
+
+ private:
+ // Handles ANDROID_ALARM_GET_TIME request.
+ int GetTime(int alarm_type, timespec* out);
+
+ DISALLOW_COPY_AND_ASSIGN(DevAlarm);
+};
+
+} // namespace posix_translation
+#endif // POSIX_TRANSLATION_DEV_ALARM_H_
diff --git a/src/posix_translation/dev_alarm_test.cc b/src/posix_translation/dev_alarm_test.cc
new file mode 100644
index 0000000..5630561
--- /dev/null
+++ b/src/posix_translation/dev_alarm_test.cc
@@ -0,0 +1,155 @@
+// Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <sys/sysmacros.h>
+#include <linux/android_alarm.h> // Can't sort this, requirs sys/sysmacros.h.
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "gtest/gtest.h"
+#include "posix_translation/dev_alarm.h"
+#include "posix_translation/test_util/file_system_test_common.h"
+
+// We use random numbers for this test.
+const int kAlarmMajorId = 50;
+const int kAlarmMinorId = 51;
+
+namespace posix_translation {
+
+namespace {
+
+// Helper function for calling ioctl of |stream|.
+int CallIoctl(scoped_refptr<FileStream> stream, int request, ...) {
+ va_list ap;
+ va_start(ap, request);
+ int ret = stream->ioctl(request, ap);
+ va_end(ap);
+ return ret;
+}
+} // namespace
+
+class DevAlarmTest : public FileSystemTestCommon {
+ protected:
+ DevAlarmTest()
+ : handler_(new DevAlarmHandler) {
+ }
+
+ scoped_ptr<FileSystemHandler> handler_;
+
+ private:
+ virtual void SetUp() OVERRIDE {
+ FileSystemTestCommon::SetUp();
+ DeviceHandler::AddDeviceId("/dev/alarm", kAlarmMajorId, kAlarmMinorId);
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(DevAlarmTest);
+};
+
+TEST_F(DevAlarmTest, TestInit) {
+}
+
+TEST_F(DevAlarmTest, TestMkdir) {
+ EXPECT_EQ(-1, handler_->mkdir("/dev/alarm", 0700));
+ EXPECT_EQ(EEXIST, errno);
+}
+
+TEST_F(DevAlarmTest, TestRename) {
+ EXPECT_EQ(-1, handler_->rename("/dev/alarm", "/dev/foo"));
+ EXPECT_EQ(EACCES, errno);
+ EXPECT_EQ(0, handler_->rename("/dev/alarm", "/dev/alarm"));
+}
+
+TEST_F(DevAlarmTest, TestStat) {
+ struct stat st = {};
+ EXPECT_EQ(0, handler_->stat("/dev/alarm", &st));
+ EXPECT_NE(0U, st.st_ino);
+ EXPECT_EQ(S_IFCHR | 0664U, st.st_mode);
+}
+
+TEST_F(DevAlarmTest, TestStatfs) {
+ struct statfs st = {};
+ EXPECT_EQ(0, handler_->statfs("/dev/alarm", &st));
+ EXPECT_NE(0U, st.f_type); // check something is filled.
+}
+
+TEST_F(DevAlarmTest, TestTruncate) {
+ EXPECT_EQ(-1, handler_->truncate("/dev/alarm", 0));
+ EXPECT_EQ(EINVAL, errno);
+}
+
+TEST_F(DevAlarmTest, TestUnlink) {
+ EXPECT_EQ(-1, handler_->unlink("/dev/alarm"));
+ EXPECT_EQ(EACCES, errno);
+}
+
+TEST_F(DevAlarmTest, TestUtimes) {
+ struct timeval times[2] = {};
+ EXPECT_EQ(-1, handler_->utimes("/dev/alarm", times));
+ EXPECT_EQ(EPERM, errno);
+}
+
+TEST_F(DevAlarmTest, TestOpenClose) {
+ scoped_refptr<FileStream> stream =
+ handler_->open(512, "/dev/alarm", O_RDONLY, 0);
+ ASSERT_TRUE(stream != NULL);
+}
+
+TEST_F(DevAlarmTest, TestFstat) {
+ scoped_refptr<FileStream> stream =
+ handler_->open(512, "/dev/alarm", O_RDONLY, 0);
+ ASSERT_TRUE(stream != NULL);
+ struct stat st = {};
+ stream->fstat(&st);
+ EXPECT_NE(0U, st.st_ino);
+ EXPECT_EQ(S_IFCHR | 0664U, st.st_mode);
+ EXPECT_EQ(makedev(kAlarmMajorId, kAlarmMinorId), st.st_rdev);
+}
+
+TEST_F(DevAlarmTest, TestRead) {
+ scoped_refptr<FileStream> stream =
+ handler_->open(512, "/dev/alarm", O_RDONLY, 0);
+ ASSERT_TRUE(stream != NULL);
+ char buf[16] = {};
+ errno = 0;
+ EXPECT_EQ(-1, stream->read(buf, sizeof(buf)));
+ EXPECT_EQ(EINVAL, errno);
+}
+
+TEST_F(DevAlarmTest, TestWrite) {
+ scoped_refptr<FileStream> stream =
+ handler_->open(512, "/dev/alarm", O_RDONLY, 0);
+ ASSERT_TRUE(stream != NULL);
+ errno = 0;
+ EXPECT_EQ(-1, stream->write("abc", 3));
+ EXPECT_EQ(EBADF, errno);
+}
+
+TEST_F(DevAlarmTest, GET_TIME) {
+ const int requests[] = {
+ ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP),
+ ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC),
+ ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP),
+ ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME),
+ ANDROID_ALARM_GET_TIME(ANDROID_ALARM_SYSTEMTIME),
+ };
+
+ scoped_refptr<FileStream> stream =
+ handler_->open(512, "/dev/alarm", O_RDONLY, 0);
+ ASSERT_TRUE(stream != NULL);
+ for (int i = 0; i < arraysize(requests); ++i) {
+ timespec ts = {};
+ errno = 0;
+ EXPECT_EQ(0, CallIoctl(stream, requests[i], &ts));
+ EXPECT_EQ(0, errno);
+ EXPECT_FALSE(ts.tv_sec == 0 && ts.tv_nsec == 0);
+ EXPECT_LE(0, ts.tv_sec);
+ EXPECT_LE(0, ts.tv_nsec);
+
+ errno = 0;
+ ASSERT_EQ(-1, CallIoctl(stream, requests[i], NULL));
+ EXPECT_EQ(EFAULT, errno);
+ }
+}
+
+} // namespace posix_translation
diff --git a/src/posix_translation/file_wrap.cc b/src/posix_translation/file_wrap.cc
index dee49dc..68c6320 100644
--- a/src/posix_translation/file_wrap.cc
+++ b/src/posix_translation/file_wrap.cc
@@ -227,10 +227,8 @@
arc::GetAccessModeStr(mode).c_str());
int result = VirtualFileSystem::GetVirtualFileSystem()->access(
pathname, mode);
- if (result == -1 && errno != ENOENT) {
- DANGERF("path=%s mode=%d: %s",
- SAFE_CSTR(pathname), mode, safe_strerror(errno).c_str());
- }
+ if (result == -1 && errno != ENOENT)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -388,9 +386,8 @@
struct stat st;
int result = VirtualFileSystem::GetVirtualFileSystem()->lstat(path, &st);
if (result == -1) {
- if (errno != ENOENT) {
- DANGERF("path=%s: %s", SAFE_CSTR(path), safe_strerror(errno).c_str());
- }
+ if (errno != ENOENT)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
} else {
StatToNaClAbiStat(&st, buf);
ARC_STRACE_REPORT("buf=%s", arc::GetNaClAbiStatStr(buf).c_str());
@@ -401,10 +398,8 @@
IRT_WRAPPER(mkdir, const char* pathname, mode_t mode) {
ARC_STRACE_ENTER("mkdir", "\"%s\", 0%o", SAFE_CSTR(pathname), mode);
int result = VirtualFileSystem::GetVirtualFileSystem()->mkdir(pathname, mode);
- if (result == -1 && errno != EEXIST) {
- DANGERF("path=%s mode=%d: %s",
- SAFE_CSTR(pathname), mode, safe_strerror(errno).c_str());
- }
+ if (result == -1 && errno != EEXIST)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN_IRT_WRAPPER(result == 0 ? 0 : errno);
}
@@ -438,10 +433,8 @@
} else {
fd = VirtualFileSystem::GetVirtualFileSystem()->open(pathname, flags, mode);
}
- if (fd == -1 && errno != ENOENT) {
- DANGERF("pathname=%s flags=%d: %s",
- SAFE_CSTR(pathname), flags, safe_strerror(errno).c_str());
- }
+ if (fd == -1 && errno != ENOENT)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_REGISTER_FD(fd, SAFE_CSTR(pathname));
ARC_STRACE_RETURN(fd);
}
@@ -473,10 +466,8 @@
SAFE_CSTR(path), buf, bufsiz);
ssize_t result = VirtualFileSystem::GetVirtualFileSystem()->readlink(
path, buf, bufsiz);
- if (result == -1) {
- DANGERF("path=%s bufsiz=%zu: %s",
- SAFE_CSTR(path), bufsiz, safe_strerror(errno).c_str());
- }
+ if (result == -1)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -484,10 +475,8 @@
ARC_STRACE_ENTER("realpath", "\"%s\", %p", SAFE_CSTR(path), resolved_path);
char* result = VirtualFileSystem::GetVirtualFileSystem()->realpath(
path, resolved_path);
- if (!result) {
- DANGERF("path=%s resolved_path=%p: %s",
- SAFE_CSTR(path), resolved_path, safe_strerror(errno).c_str());
- }
+ if (!result)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN_PTR(result, !result);
}
@@ -495,7 +484,7 @@
ARC_STRACE_ENTER("remove", "\"%s\"", SAFE_CSTR(pathname));
int result = VirtualFileSystem::GetVirtualFileSystem()->remove(pathname);
if (result == -1 && errno != ENOENT)
- DANGERF("path=%s: %s", SAFE_CSTR(pathname), safe_strerror(errno).c_str());
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -504,11 +493,8 @@
SAFE_CSTR(oldpath), SAFE_CSTR(newpath));
int result = VirtualFileSystem::GetVirtualFileSystem()->rename(
oldpath, newpath);
- if (result == -1) {
- DANGERF("oldpath=%s newpath=%s: %s",
- SAFE_CSTR(oldpath), SAFE_CSTR(newpath),
- safe_strerror(errno).c_str());
- }
+ if (result == -1)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -535,7 +521,7 @@
int result = VirtualFileSystem::GetVirtualFileSystem()->statfs(
pathname, stat);
if (result == -1 && errno != ENOENT)
- DANGERF("path=%s: %s", SAFE_CSTR(pathname), safe_strerror(errno).c_str());
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_REPORT(
"stat={type=%lld bsize=%lld blocks=%llu bfree=%llu bavail=%llu "
"files=%llu ffree=%llu fsid=%d,%d namelen=%lld frsize=%lld "
@@ -592,11 +578,8 @@
SAFE_CSTR(pathname), static_cast<int64_t>(length));
int result = VirtualFileSystem::GetVirtualFileSystem()->truncate(
pathname, length);
- if (result == -1) {
- DANGERF("path=%s length=%lld: %s",
- SAFE_CSTR(pathname), static_cast<int64_t>(length),
- safe_strerror(errno).c_str());
- }
+ if (result == -1)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -612,7 +595,7 @@
ARC_STRACE_ENTER("unlink", "\"%s\"", SAFE_CSTR(pathname));
int result = VirtualFileSystem::GetVirtualFileSystem()->unlink(pathname);
if (result == -1 && errno != ENOENT)
- DANGERF("path=%s: %s", SAFE_CSTR(pathname), safe_strerror(errno).c_str());
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -620,10 +603,8 @@
ARC_STRACE_ENTER("utimes", "\"%s\", %p", SAFE_CSTR(filename), times);
int result = VirtualFileSystem::GetVirtualFileSystem()->utimes(
filename, times);
- if (result == -1 && errno != ENOENT) {
- DANGERF("path=%s: %s",
- SAFE_CSTR(filename), safe_strerror(errno).c_str());
- }
+ if (result == -1 && errno != ENOENT)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -632,9 +613,8 @@
struct stat st;
int result = VirtualFileSystem::GetVirtualFileSystem()->stat(pathname, &st);
if (result == -1) {
- if (errno != ENOENT) {
- DANGERF("path=%s: %s", SAFE_CSTR(pathname), safe_strerror(errno).c_str());
- }
+ if (errno != ENOENT)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
} else {
StatToNaClAbiStat(&st, buf);
ARC_STRACE_REPORT("buf=%s", arc::GetNaClAbiStatStr(buf).c_str());
@@ -659,7 +639,7 @@
// hits the case.
if (errno == EBADF)
DANGERF("Close of bad file descriptor may indicate double close");
- DANGERF("fd=%d: %s", fd, safe_strerror(errno).c_str());
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
}
ARC_STRACE_RETURN(result);
}
@@ -676,7 +656,7 @@
ARC_STRACE_ENTER_FD("dup", "%d", oldfd);
int fd = VirtualFileSystem::GetVirtualFileSystem()->dup(oldfd);
if (fd == -1)
- DANGERF("oldfd=%d: %s", oldfd, safe_strerror(errno).c_str());
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
*newfd = fd;
ARC_STRACE_RETURN_IRT_WRAPPER(fd >= 0 ? 0 : errno);
}
@@ -684,10 +664,8 @@
IRT_WRAPPER(dup2, int oldfd, int newfd) {
ARC_STRACE_ENTER_FD("dup2", "%d, %d", oldfd, newfd);
int fd = VirtualFileSystem::GetVirtualFileSystem()->dup2(oldfd, newfd);
- if (fd == -1) {
- DANGERF("oldfd=%d newfd=%d: %s",
- oldfd, newfd, safe_strerror(errno).c_str());
- }
+ if (fd == -1)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN_IRT_WRAPPER(fd >= 0 ? 0 : errno);
}
@@ -704,7 +682,7 @@
va_end(ap);
if (result == -1)
- DANGERF("fd=%d cmd=%d: %s", fd, cmd, safe_strerror(errno).c_str());
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -726,7 +704,7 @@
int result = VirtualFileSystem::GetVirtualFileSystem()->fstat(fd, &st);
if (result) {
result = errno;
- DANGERF("fd=%d: %s", fd, safe_strerror(errno).c_str());
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
} else {
StatToNaClAbiStat(&st, buf);
ARC_STRACE_REPORT("buf=%s", arc::GetNaClAbiStatStr(buf).c_str());
@@ -739,10 +717,8 @@
ARC_STRACE_ENTER_FD("ftruncate", "%d, %lld",
fd, static_cast<int64_t>(length));
int result = VirtualFileSystem::GetVirtualFileSystem()->ftruncate(fd, length);
- if (result == -1) {
- DANGERF("fd=%d length=%lld: %s", fd, static_cast<int64_t>(length),
- safe_strerror(errno).c_str());
- }
+ if (result == -1)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -764,7 +740,7 @@
fd, request, ap);
va_end(ap);
if (result == -1)
- DANGERF("fd=%d request=%d: %s", fd, request, safe_strerror(errno).c_str());
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -775,11 +751,8 @@
arc::GetLseekWhenceStr(whence).c_str());
OffsetType result = VirtualFileSystem::GetVirtualFileSystem()->lseek(
fd, offset, whence);
- if (result == -1) {
- DANGERF("fd=%d offset=%lld whence=%d: %s",
- fd, static_cast<int64_t>(offset), whence,
- safe_strerror(errno).c_str());
- }
+ if (result == -1)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -794,8 +767,7 @@
int result = VirtualFileSystem::GetVirtualFileSystem()->madvise(
addr, length, advice);
if (result != 0) {
- DANGERF("errno=%d addr=%p length=%zu advice=%d: %s",
- errno, addr, length, advice, safe_strerror(errno).c_str());
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
if (errno == ENOSYS && advice != MADV_REMOVE) {
// TODO(crbug.com/362862): Stop special-casing ENOSYS once the bug is
// fixed.
@@ -859,11 +831,8 @@
MapCurrentStackFrame(result, length);
#endif
- if (result == MAP_FAILED) {
- DANGERF("addr=%p length=%zu prot=%d flags=%d fd=%d offset=%lld: %s",
- addr, length, prot, flags, fd, static_cast<int64_t>(offset),
- safe_strerror(errno).c_str());
- }
+ if (result == MAP_FAILED)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN_PTR(result, result == MAP_FAILED);
}
@@ -953,8 +922,7 @@
int result = VirtualFileSystem::GetVirtualFileSystem()->poll(
fds, nfds, timeout);
if (result == -1) {
- DANGERF("fds=%p nfds=%u timeout=%d[ms]: %s",
- fds, nfds, timeout, safe_strerror(errno).c_str());
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
} else if (arc::StraceEnabled()) {
for (int i = 0; i < result; ++i) {
if (!fds[i].revents)
@@ -973,11 +941,8 @@
fd, buf, count, static_cast<int64_t>(offset));
ssize_t result = VirtualFileSystem::GetVirtualFileSystem()->pread(
fd, buf, count, offset);
- if (result == -1) {
- DANGERF("fd=%d buf=%p count=%zu offset=%lld: %s",
- fd, buf, count, static_cast<int64_t>(offset),
- safe_strerror(errno).c_str());
- }
+ if (result == -1)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
if (result >= 0)
ARC_STRACE_REPORT("buf=%s", arc::GetRWBufStr(buf, result).c_str());
ARC_STRACE_RETURN(result);
@@ -998,11 +963,8 @@
fd, buf, count, static_cast<int64_t>(offset));
ssize_t result = VirtualFileSystem::GetVirtualFileSystem()->pwrite(
fd, buf, count, offset);
- if (result == -1) {
- DANGERF("fd=%d buf=%p count=%zu offset=%lld: %s",
- fd, buf, count, static_cast<int64_t>(offset),
- safe_strerror(errno).c_str());
- }
+ if (result == -1)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
if (errno != EFAULT)
ARC_STRACE_REPORT("buf=%s", arc::GetRWBufStr(buf, count).c_str());
ARC_STRACE_RETURN(result);
@@ -1021,10 +983,8 @@
ARC_STRACE_ENTER_FD("read", "%d, %p, %zu", fd, buf, count);
ssize_t result = VirtualFileSystem::GetVirtualFileSystem()->read(
fd, buf, count);
- if (result == -1 && errno != EAGAIN) {
- DANGERF("fd=%d buf=%p count=%zu: %s",
- fd, buf, count, safe_strerror(errno).c_str());
- }
+ if (result == -1 && errno != EAGAIN)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
if (result >= 0)
ARC_STRACE_REPORT("buf=%s", arc::GetRWBufStr(buf, result).c_str());
ARC_STRACE_RETURN(result);
@@ -1035,10 +995,8 @@
ARC_STRACE_ENTER_FD("readv", "%d, %p, %d", fd, iov, iovcnt);
ssize_t result = VirtualFileSystem::GetVirtualFileSystem()->readv(
fd, iov, iovcnt);
- if (result == -1) {
- DANGERF("fd=%d iov=%p iovcnt=%d: %s",
- fd, iov, iovcnt, safe_strerror(errno).c_str());
- }
+ if (result == -1)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -1046,7 +1004,7 @@
ARC_STRACE_ENTER("rmdir", "\"%s\"", SAFE_CSTR(pathname));
int result = VirtualFileSystem::GetVirtualFileSystem()->rmdir(pathname);
if (result == -1 && errno != ENOENT)
- DANGERF("path=%s: %s", SAFE_CSTR(pathname), safe_strerror(errno).c_str());
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -1054,10 +1012,8 @@
ARC_STRACE_ENTER("utime", "\"%s\", %p", SAFE_CSTR(filename), times);
int result = VirtualFileSystem::GetVirtualFileSystem()->utime(
filename, times);
- if (result == -1 && errno != ENOENT) {
- DANGERF("path=%s: %s",
- SAFE_CSTR(filename), safe_strerror(errno).c_str());
- }
+ if (result == -1 && errno != ENOENT)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
@@ -1080,10 +1036,8 @@
if (errno != EFAULT)
ARC_STRACE_REPORT("buf=%s", arc::GetRWBufStr(buf, count).c_str());
g_wrap_write_nest_count.Set(wrap_write_nest_count);
- if (result == -1 && errno != EAGAIN) {
- DANGERF("fd=%d buf=%p count=%zu: %s",
- fd, buf, count, safe_strerror(errno).c_str());
- }
+ if (result == -1 && errno != EAGAIN)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
}
@@ -1094,10 +1048,8 @@
ARC_STRACE_ENTER_FD("writev", "%d, %p, %d", fd, iov, iovcnt);
ssize_t result = VirtualFileSystem::GetVirtualFileSystem()->writev(
fd, iov, iovcnt);
- if (result == -1) {
- DANGERF("fd=%d iov=%p iovcnt=%d: %s",
- fd, iov, iovcnt, safe_strerror(errno).c_str());
- }
+ if (result == -1)
+ ARC_STRACE_ALWAYS_WARN_FAILURE();
ARC_STRACE_RETURN(result);
}
diff --git a/src/posix_translation/file_wrap_stub.cc b/src/posix_translation/file_wrap_stub.cc
index 5c76f7f..e1209a7 100644
--- a/src/posix_translation/file_wrap_stub.cc
+++ b/src/posix_translation/file_wrap_stub.cc
@@ -31,7 +31,7 @@
extern "C" ARC_EXPORT int __wrap_fchdir(int fd) {
ARC_STRACE_ENTER_FD("fchdir", "%d", fd);
// TODO(crbug.com/178515): Implement this.
- DANGERF("fchdir: fd=%d", fd);
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
ALOG_ASSERT(0);
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
@@ -45,7 +45,8 @@
// at the same time.
ARC_STRACE_ENTER_FD("flock", "%d, %s",
fd, arc::GetFlockOperationStr(operation).c_str());
- ARC_STRACE_REPORT("not implemented, always succeeds");
+ // Do not call ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED() which is too noisy.
+ ARC_STRACE_REPORT("not implemented yet");
ARC_STRACE_RETURN(0);
}
@@ -53,8 +54,7 @@
const char* path, uid_t owner, gid_t group) {
ARC_STRACE_ENTER("lchown", "\"%s\", %u, %u",
SAFE_CSTR(path), owner, group);
- DANGERF("lchown: path=%s owner=%u group=%u",
- SAFE_CSTR(path), owner, group);
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
ALOG_ASSERT(0);
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
@@ -62,7 +62,7 @@
extern "C" ARC_EXPORT int __wrap_mlock(const void* addr, size_t len) {
ARC_STRACE_ENTER("mlock", "%p, %zu", addr, len);
- DANGERF("mlock: addr=%p len=%zu", addr, len);
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
}
@@ -70,7 +70,7 @@
extern "C" ARC_EXPORT int __wrap_mlockall(int flags) {
// TODO(crbug.com/241955): Stringify |flags|?
ARC_STRACE_ENTER("mlockall", "%d", flags);
- DANGERF("mlockall: flags=%d", flags);
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
ALOG_ASSERT(0);
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
@@ -84,10 +84,7 @@
ARC_STRACE_ENTER("mount", "\"%s\", \"%s\", \"%s\", %lu, %p",
SAFE_CSTR(source), SAFE_CSTR(target),
SAFE_CSTR(filesystemtype), mountflags, data);
- DANGERF("mount: source=%s target=%s "
- "filesystemtype=%s mountflags=%lu data=%p",
- SAFE_CSTR(source), SAFE_CSTR(target),
- SAFE_CSTR(filesystemtype), mountflags, data);
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
ALOG_ASSERT(0);
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
@@ -98,8 +95,7 @@
ARC_STRACE_ENTER("mremap", "%p, %zu, %zu, %s",
old_address, old_size, new_size,
arc::GetMremapFlagStr(flags).c_str());
- DANGERF("mremap: old_address=%p old_size=%zu new_size=%zu flags=%d",
- old_address, old_size, new_size, flags);
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
ALOG_ASSERT(0);
errno = ENOSYS;
ARC_STRACE_RETURN_PTR(MAP_FAILED, true);
@@ -107,14 +103,14 @@
extern "C" ARC_EXPORT int __wrap_munlock(const void* addr, size_t len) {
ARC_STRACE_ENTER("munlock", "%p, %zu", addr, len);
- DANGERF("munlock: addr=%p len=%zu", addr, len);
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
}
extern "C" ARC_EXPORT int __wrap_munlockall() {
ARC_STRACE_ENTER("munlockall", "%s", "");
- DANGERF("munlockall");
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
ALOG_ASSERT(0);
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
@@ -122,7 +118,7 @@
extern "C" ARC_EXPORT int __wrap_umount(const char* target) {
ARC_STRACE_ENTER("umount", "\"%s\"", SAFE_CSTR(target));
- DANGERF("umount: target=%s", SAFE_CSTR(target));
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
ALOG_ASSERT(0);
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
@@ -131,7 +127,7 @@
extern "C" ARC_EXPORT int __wrap_umount2(const char* target, int flags) {
// TODO(crbug.com/241955): Stringify |flags|?
ARC_STRACE_ENTER("umount2", "\"%s\", %d", SAFE_CSTR(target), flags);
- DANGERF("umount2: target=%s flags=%d", SAFE_CSTR(target), flags);
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
ALOG_ASSERT(0);
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
@@ -144,13 +140,13 @@
extern "C" ARC_EXPORT int __wrap_chmod(const char* path, mode_t mode) {
// TODO(crbug.com/242355): Implement this.
ARC_STRACE_ENTER("chmod", "\"%s\", 0%o", SAFE_CSTR(path), mode);
- ARC_STRACE_REPORT("not implemented yet");
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
ARC_STRACE_RETURN(0); // Returning -1 breaks SQLite.
}
extern "C" ARC_EXPORT int __wrap_eventfd(unsigned int initval, int flags) {
ARC_STRACE_ENTER("eventfd", "%u, %d", initval, flags);
- ARC_STRACE_REPORT("not implemented yet");
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
}
@@ -158,21 +154,21 @@
extern "C" ARC_EXPORT int __wrap_fchmod(int fd, mode_t mode) {
// TODO(crbug.com/242355): Implement this.
ARC_STRACE_ENTER_FD("fchmod", "%d, 0%o", fd, mode);
- ARC_STRACE_REPORT("not implemented yet");
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
ARC_STRACE_RETURN(0);
}
extern "C" ARC_EXPORT int __wrap_fchown(int fd, uid_t owner, gid_t group) {
// TODO(crbug.com/242355): Implement this.
ARC_STRACE_ENTER_FD("fchown", "%d, %u, %u", fd, owner, group);
- ARC_STRACE_REPORT("not implemented yet");
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
ARC_STRACE_RETURN(0);
}
extern "C" ARC_EXPORT int __wrap_futimens(
int fd, const struct timespec times[2]) {
ARC_STRACE_ENTER_FD("futimens", "%d, %p", fd, times);
- ARC_STRACE_REPORT("not implemented yet");
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
}
@@ -182,8 +178,7 @@
ARC_STRACE_ENTER_FD("inotify_add_watch", "%d, \"%s\", %u",
fd, SAFE_CSTR(pathname), mask);
// TODO(crbug.com/236903): Implement this.
- DANGERF("inotify_add_watch: fd=%d pathname=%s mask=%u",
- fd, SAFE_CSTR(pathname), mask);
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
}
@@ -191,7 +186,7 @@
extern "C" ARC_EXPORT int __wrap_inotify_init() {
ARC_STRACE_ENTER("inotify_init", "%s", "");
// TODO(crbug.com/236903): Implement this.
- DANGERF("inotify_init");
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
}
@@ -199,14 +194,14 @@
extern "C" ARC_EXPORT int __wrap_inotify_rm_watch(int fd, int wd) {
ARC_STRACE_ENTER_FD("inotify_rm_watch", "%d, %d", fd, wd);
// TODO(crbug.com/236903): Implement this.
- DANGERF("inotify_rm_watch: fd=%d wd=%d", fd, wd);
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
errno = ENOSYS;
ARC_STRACE_RETURN(-1);
}
extern "C" ARC_EXPORT int __wrap_msync(void* addr, size_t length, int flags) {
ARC_STRACE_ENTER("msync", "%p, %zu, %d", addr, length, flags);
- ARC_STRACE_REPORT("not implemented yet");
+ ARC_STRACE_ALWAYS_WARN_NOTIMPLEMENTED();
// msync is called by dexopt and some apps (crbug.com/363545). Although dexopt
// does not check the return value, the apps may. Return 0 without doing
// anything so that such apps will not fail. This should be safe as long as