summaryrefslogtreecommitdiff
path: root/gnu/llvm/compiler-rt/lib/scudo/standalone/linux.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/compiler-rt/lib/scudo/standalone/linux.cpp')
-rw-r--r--gnu/llvm/compiler-rt/lib/scudo/standalone/linux.cpp51
1 files changed, 47 insertions, 4 deletions
diff --git a/gnu/llvm/compiler-rt/lib/scudo/standalone/linux.cpp b/gnu/llvm/compiler-rt/lib/scudo/standalone/linux.cpp
index 8266a528f42..69ffdd9a165 100644
--- a/gnu/llvm/compiler-rt/lib/scudo/standalone/linux.cpp
+++ b/gnu/llvm/compiler-rt/lib/scudo/standalone/linux.cpp
@@ -35,6 +35,10 @@
#define ANDROID_PR_SET_VMA_ANON_NAME 0
#endif
+#ifdef ANDROID_EXPERIMENTAL_MTE
+#include <bionic/mte_kernel.h>
+#endif
+
namespace scudo {
uptr getPageSize() { return static_cast<uptr>(sysconf(_SC_PAGESIZE)); }
@@ -50,6 +54,10 @@ void *map(void *Addr, uptr Size, UNUSED const char *Name, uptr Flags,
MmapProt = PROT_NONE;
} else {
MmapProt = PROT_READ | PROT_WRITE;
+#if defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
+ if (Flags & MAP_MEMTAG)
+ MmapProt |= PROT_MTE;
+#endif
}
if (Addr) {
// Currently no scenario for a noaccess mapping with a fixed address.
@@ -124,10 +132,21 @@ u64 getMonotonicTime() {
u32 getNumberOfCPUs() {
cpu_set_t CPUs;
- CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0);
+ // sched_getaffinity can fail for a variety of legitimate reasons (lack of
+ // CAP_SYS_NICE, syscall filtering, etc), in which case we shall return 0.
+ if (sched_getaffinity(0, sizeof(cpu_set_t), &CPUs) != 0)
+ return 0;
return static_cast<u32>(CPU_COUNT(&CPUs));
}
+u32 getThreadID() {
+#if SCUDO_ANDROID
+ return static_cast<u32>(gettid());
+#else
+ return static_cast<u32>(syscall(SYS_gettid));
+#endif
+}
+
// Blocking is possibly unused if the getrandom block is not compiled in.
bool getRandom(void *Buffer, uptr Length, UNUSED bool Blocking) {
if (!Buffer || !Length || Length > MaxRandomLength)
@@ -153,10 +172,34 @@ bool getRandom(void *Buffer, uptr Length, UNUSED bool Blocking) {
return (ReadBytes == static_cast<ssize_t>(Length));
}
+// Allocation free syslog-like API.
+extern "C" WEAK int async_safe_write_log(int pri, const char *tag,
+ const char *msg);
+
void outputRaw(const char *Buffer) {
- static HybridMutex Mutex;
- ScopedLock L(Mutex);
- write(2, Buffer, strlen(Buffer));
+ if (&async_safe_write_log) {
+ constexpr s32 AndroidLogInfo = 4;
+ constexpr uptr MaxLength = 1024U;
+ char LocalBuffer[MaxLength];
+ while (strlen(Buffer) > MaxLength) {
+ uptr P;
+ for (P = MaxLength - 1; P > 0; P--) {
+ if (Buffer[P] == '\n') {
+ memcpy(LocalBuffer, Buffer, P);
+ LocalBuffer[P] = '\0';
+ async_safe_write_log(AndroidLogInfo, "scudo", LocalBuffer);
+ Buffer = &Buffer[P + 1];
+ break;
+ }
+ }
+ // If no newline was found, just log the buffer.
+ if (P == 0)
+ break;
+ }
+ async_safe_write_log(AndroidLogInfo, "scudo", Buffer);
+ } else {
+ write(2, Buffer, strlen(Buffer));
+ }
}
extern "C" WEAK void android_set_abort_message(const char *);