blob: b0444b326bcbf514aa99cfc97f5f2d53c5be45ea [file] [log] [blame]
// Copyright 2014 The Chromium 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 "common/ndk_support/arm_syscall.h"
#include <errno.h>
#include <stdarg.h>
#include <stdint.h>
#include <unistd.h>
#include "common/alog.h"
#include "common/arc_strace.h"
namespace arc {
namespace {
#if defined(USE_NDK_DIRECT_EXECUTION)
void RunCacheFlush(va_list ap) {
int32_t start = va_arg(ap, int32_t);
int32_t end = va_arg(ap, int32_t);
uint32_t op = va_arg(ap, uint32_t);
switch (op) {
// Invalidate i-cache.
case 0:
ALOGI("icache flush: %p-%p",
reinterpret_cast<void*>(start), reinterpret_cast<void*>(end));
if (cacheflush(start, end, 0) != 0)
ALOGE("cacheflush failed.");
break;
default:
LOG_ALWAYS_FATAL("CacheFlush op 0x%x not supported\n", op);
}
}
#endif
int RunArmKernelSyscallImpl(int sysno, va_list ap) {
int result = -1;
switch (sysno) {
case 178: // rt_sigqueueinfo
ALOGE("rt_sigqueueinfo is not supported, returning ENOSYS");
return -ENOSYS;
case 186: // sigaltstack
ALOGE("sigaltstack is not supported, returning ENOSYS");
return -ENOSYS;
case 224: // gettid
result = gettid();
break;
case 241: // sched_setaffinity
ALOGI("sched_setaffinity is not supported, returning 0");
return 0; // pretend to succeed.
case 307: // shmget
ALOGE("shmget is not supported, returning ENOSYS");
return -ENOSYS;
case kCacheFlushSysno: // cacheflush
#if defined(USE_NDK_DIRECT_EXECUTION)
RunCacheFlush(ap);
#else
LOG_ALWAYS_FATAL("cacheflush must be handled in NDK translation");
#endif
return 0;
default:
LOG_ALWAYS_FATAL("ARM syscall 0x%x not supported\n", sysno);
}
if (result < 0)
result = -errno;
return result;
}
} // namespace
int RunArmKernelSyscall(int sysno, ...) {
// TODO(crbug.com/241955): Stringify |number|.
ARC_STRACE_ENTER("syscall_ndk", "%d, ...", sysno);
va_list ap;
va_start(ap, sysno);
int result = RunArmKernelSyscallImpl(sysno, ap);
va_end(ap);
ARC_STRACE_RETURN_INT(result, false);
}
#if defined(USE_NDK_DIRECT_EXECUTION)
int RunArmLibcSyscall(int sysno, ...) {
// TODO(crbug.com/241955): Stringify |number|.
ARC_STRACE_ENTER("syscall_libc", "%d, ...", sysno);
va_list ap;
va_start(ap, sysno);
int result = RunArmKernelSyscallImpl(sysno, ap);
va_end(ap);
// This matches with the behavior of Bionic. See
// third_party/android/bionic/libc/arch-arm/bionic/syscall.S.
if (-4096 < result && result < 0) {
errno = -result;
result = -1;
}
ARC_STRACE_RETURN(result);
}
#endif
} // namespace arc