[compiler-rt] [compiler-rt][memprof] memccpy interception (PR #155101)

David CARLIER via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 23 06:42:39 PDT 2025


https://github.com/devnexen created https://github.com/llvm/llvm-project/pull/155101

None

>From 92f2fea8cbdb181d76fee3564d412574686bc153 Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Sat, 23 Aug 2025 14:37:51 +0100
Subject: [PATCH] [compiler-rt][memprof] memccpy interception

---
 .../lib/memprof/memprof_interceptors.cpp      | 20 +++++++++++++++++++
 .../lib/sanitizer_common/sanitizer_libc.cpp   | 11 ++++++++++
 .../lib/sanitizer_common/sanitizer_libc.h     |  1 +
 .../sanitizer_platform_interceptors.h         |  1 +
 .../memprof/TestCases/memprof_memccpy.cpp     | 15 ++++++++++++++
 5 files changed, 48 insertions(+)
 create mode 100644 compiler-rt/test/memprof/TestCases/memprof_memccpy.cpp

diff --git a/compiler-rt/lib/memprof/memprof_interceptors.cpp b/compiler-rt/lib/memprof/memprof_interceptors.cpp
index f4d7fd46e6198..25bff22179cad 100644
--- a/compiler-rt/lib/memprof/memprof_interceptors.cpp
+++ b/compiler-rt/lib/memprof/memprof_interceptors.cpp
@@ -306,6 +306,22 @@ INTERCEPTOR(long long, atoll, const char *nptr) {
   return result;
 }
 
+#if SANITIZER_INTERCEPT_MEMCCPY
+INTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, usize size) {
+  void *ctx;
+  MEMPROF_INTERCEPTOR_ENTER(ctx, strdup);
+  if (UNLIKELY(!memprof_inited))
+    return internal_memccpy(dest, src, c, size);
+  ENSURE_MEMPROF_INITED();
+  void *res = REAL(memccpy)(dest, src, c, size);
+  if (res != nullptr)
+      size = static_cast<char *>(res) - static_cast<char *>(dest);
+  MEMPROF_READ_RANGE(src, size);
+  MEMPROF_WRITE_RANGE(dest, size);
+
+}
+#endif
+
 // ---------------------- InitializeMemprofInterceptors ---------------- {{{1
 namespace __memprof {
 void InitializeMemprofInterceptors() {
@@ -333,6 +349,10 @@ void InitializeMemprofInterceptors() {
   MEMPROF_INTERCEPT_FUNC(pthread_create);
   MEMPROF_INTERCEPT_FUNC(pthread_join);
 
+#if SANITIZER_INTERCEPT_MEMCCPY
+  MEMPROF_INTERCEPT_FUNC(memccpy);
+#endif
+
   InitializePlatformInterceptors();
 
   VReport(1, "MemProfiler: libc interceptors initialized\n");
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libc.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_libc.cpp
index 9318066afed20..e3b3f8b660187 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libc.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libc.cpp
@@ -49,6 +49,17 @@ int internal_memcmp(const void* s1, const void* s2, uptr n) {
   return 0;
 }
 
+void *internal_memccpy(void *dest, const void *src, int c, uptr n) {
+  char *d = (char*)dest;
+  const char *s = (const char *)src;
+  uptr i = 0;
+  for (; i < n && s[i] != c; ++i)
+    d[i] = s[i];
+  if (i < n - 1)
+    return d + i + 1;
+  return nullptr;
+}
+
 extern "C" {
 SANITIZER_INTERFACE_ATTRIBUTE void *__sanitizer_internal_memcpy(void *dest,
                                                                 const void *src,
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libc.h b/compiler-rt/lib/sanitizer_common/sanitizer_libc.h
index 1906569e2a5fc..aa0a9788e084e 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libc.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libc.h
@@ -41,6 +41,7 @@ s64 internal_atoll(const char *nptr);
 void *internal_memchr(const void *s, int c, uptr n);
 void *internal_memrchr(const void *s, int c, uptr n);
 int internal_memcmp(const void* s1, const void* s2, uptr n);
+void *internal_memccpy(void *d, const void *s, int c, uptr n);
 ALWAYS_INLINE void *internal_memcpy(void *dest, const void *src, uptr n) {
   return __sanitizer_internal_memcpy(dest, src, n);
 }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 29987decdff45..5d0f871d4bfc8 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -198,6 +198,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_MEMMEM (SI_POSIX && !SI_MAC_DEPLOYMENT_BELOW_10_7)
 #define SANITIZER_INTERCEPT_MEMCHR SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_MEMRCHR (SI_FREEBSD || SI_LINUX || SI_NETBSD)
+#define SANITIZER_INTERCEPT_MEMCCPY (SI_FREEBSD || SI_LINUX || SI_NETBSD)
 
 #define SANITIZER_INTERCEPT_READ SI_POSIX
 #define SANITIZER_INTERCEPT_PREAD SI_POSIX
diff --git a/compiler-rt/test/memprof/TestCases/memprof_memccpy.cpp b/compiler-rt/test/memprof/TestCases/memprof_memccpy.cpp
new file mode 100644
index 0000000000000..7603417dbcd82
--- /dev/null
+++ b/compiler-rt/test/memprof/TestCases/memprof_memccpy.cpp
@@ -0,0 +1,15 @@
+// RUN: %clangxx_memprof -O0 %s -o %t && %env_memprof_opts=print_text=true:log_path=stderr %run %t 2>&1 | FileCheck %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main() {
+    char *p = strdup("memccpy");
+    char *d = malloc(4);
+    void *r = memccpy(d, p, 'c', 8);
+    int cmp = memcmp(r, "mem", 3);
+    free(d);
+    free(p);
+    return cmp;
+}



More information about the llvm-commits mailing list