[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