fixes some sanitizers on ppc64le
From 95fa3d049e35b141f0c2c3b3b0abb6c1b3702e46 Mon Sep 17 00:00:00 2001
From: Daniel Kolesa <daniel@octaforge.org>
Date: Wed, 6 Apr 2022 00:54:03 +0200
Subject: [PATCH 07/19] compiler-rt: ppc sanitizer fixes

---
 .../lib/sanitizer_common/sanitizer_linux.cpp  |  4 ++
 .../sanitizer_platform_limits_posix.cpp       |  2 +-
 .../sanitizer_stoptheworld_linux_libcdep.cpp  |  2 +-
 compiler-rt/lib/xray/xray_powerpc64.inc       | 37 ++++++++++++++++++-
 4 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 24c6acaa9..5d79dea48 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -74,6 +74,10 @@
 #include <sys/utsname.h>
 #endif
 
+#if SANITIZER_LINUX && defined(__powerpc__)
+#include <asm/ptrace.h>
+#endif
+
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
 #include <sys/personality.h>
 #endif
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
index fc01498aa..2fd663d88 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
@@ -94,7 +94,7 @@
 # include <utime.h>
 # include <sys/ptrace.h>
 #    if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \
-        defined(__hexagon__) || defined(__loongarch__) ||SANITIZER_RISCV64
+        defined(__hexagon__) || defined(__loongarch__) || defined(__powerpc__) || SANITIZER_RISCV64
 #      include <asm/ptrace.h>
 #      ifdef __arm__
 typedef struct user_fpregs elf_fpregset_t;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
index 13b90ce9b..f8702753e 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
@@ -31,7 +31,7 @@
 #include <sys/types.h> // for pid_t
 #include <sys/uio.h> // for iovec
 #include <elf.h> // for NT_PRSTATUS
-#if (defined(__aarch64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) && \
+#if (defined(__aarch64__) || defined(__powerpc__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) && \
      !SANITIZER_ANDROID
 // GLIBC 2.20+ sys/user does not include asm/ptrace.h
 # include <asm/ptrace.h>
diff --git a/compiler-rt/lib/xray/xray_powerpc64.inc b/compiler-rt/lib/xray/xray_powerpc64.inc
index 7e872b5b4..9616a09d8 100644
--- a/compiler-rt/lib/xray/xray_powerpc64.inc
+++ b/compiler-rt/lib/xray/xray_powerpc64.inc
@@ -12,7 +12,7 @@
 
 #include <cstdint>
 #include <mutex>
-#ifdef __linux__
+#ifdef __GLIBC__
 #include <sys/platform/ppc.h>
 #elif defined(__FreeBSD__)
 #include <sys/types.h>
@@ -27,6 +27,14 @@ uint64_t __ppc_get_timebase_freq (void)
   sysctlbyname("kern.timecounter.tc.timebase.frequency", &tb_freq, &length, nullptr, 0);
   return tb_freq;
 }
+#else
+#include <cctype>
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+
+#define __ppc_get_timebase __builtin_ppc_get_timebase
+
 #endif
 
 #include "xray_defs.h"
@@ -41,7 +48,35 @@ ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
 inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT {
   static std::mutex M;
   std::lock_guard<std::mutex> Guard(M);
+#ifdef __GLIBC__
   return __ppc_get_timebase_freq();
+#else
+  /* FIXME: a less dirty implementation? */
+  static uint64_t base;
+  if (!base) {
+    FILE *f = fopen("/proc/cpuinfo", "rb");
+    if (f) {
+      ssize_t nr;
+      /* virtually always big enough to hold the line */
+      char buf[512];
+      while (fgets(buf, sizeof(buf), f)) {
+        char *ret = strstr(buf, "timebase");
+        if (!ret) {
+          continue;
+        }
+        ret += sizeof("timebase") - 1;
+        ret = strchr(ret, ':');
+        if (!ret) {
+          continue;
+        }
+        base = strtoul(ret + 1, nullptr, 10);
+        break;
+      }
+      fclose(f);
+    }
+  }
+  return base;
+#endif
 }
 
 inline bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT {
