Repository: DynamoRIO/dynamorio (2026-07-20T21:36:18Z)

Issue:
Change `noinline` attributes to the double-underscore variant to avoid conflicts with the Linux kernel
Currently there are several `noinline` attributes used in the code base, like
https://github.com/DynamoRIO/dynamorio/blob/25ad71237ceab5f536518ecdcca51b0ed077e914/core/lib/globals_api.h#L172

However, in the linux kernel it defines `noinline` as a macro:
https://github.com/torvalds/linux/blob/b95f03f04d475aa6719d15a636ddf32222d55657/include/linux/compiler_attributes.h#L231

This means when building DR with kernel headers, if the preprocessor sees `noinline` it will be expanded to something like
```
// Preprocessor output:
#define NOINLINE __attribute__((__attribute__((__noinline__))))
```

GCC and Clang specifically support double-underscores around attribute names (i.e., `__attribute__((__noinline__))` for this kind of issue. The double underscore variant behaves exactly the same, but can prevent naming collisions.


Discussion:

Patch:
diff --git a/api/docs/annotations.dox b/api/docs/annotations.dox
index ba83f2ab7d..8bf8922036 100644
--- a/api/docs/annotations.dox
+++ b/api/docs/annotations.dox
@@ -67,7 +67,7 @@ invoked anyway.
 #define ANNOTATION_FUNCTION_CLOBBER_LIST "%rax","%rcx","%rdx","%rsi","%rdi","%r8","%r9"
 #define _CALL_TYPE
 #define DR_ANNOTATION_ATTRIBUTES \
-    __attribute__((noinline, visibility("hidden") _CALL_TYPE))
+    __attribute__((__noinline__, visibility("hidden") _CALL_TYPE))
 #define DR_DEFINE_ANNOTATION(return_type, annotation, parameters, body) \
     const char *annotation##_label = "dynamorio-annotation:"#annotation; \
     DR_ANNOTATION_ATTRIBUTES return_type annotation parameters \
diff --git a/core/io.c b/core/io.c
index 5c2eacb8eb..579ebec8a2 100644
--- a/core/io.c
+++ b/core/io.c
@@ -922,13 +922,13 @@ typedef void (*memset_t)(void *dst, int src, size_t n);
 
 /* Force compiler to not optimize away our own memcpy and memset.
  */
-__attribute__((noinline)) static void *
+static NOINLINE void *
 our_memcpy(void *dst, const void *src, size_t n)
 {
     return memcpy(dst, src, n);
 }
 
-__attribute__((noinline)) static void *
+static NOINLINE void *
 our_memset(void *dst, int src, size_t n)
 {
     return memset(dst, src, n);
diff --git a/core/lib/dr_annotations_asm.h b/core/lib/dr_annotations_asm.h
index 2feb06487a..e860eea2ed 100644
--- a/core/lib/dr_annotations_asm.h
+++ b/core/lib/dr_annotations_asm.h
@@ -242,7 +242,7 @@
 #        define ANNOT_LBL(annot, base) #annot "_label@GOT(%" base ")"
 #    endif
 #    define DR_ANNOTATION_ATTRIBUTES \
-        __attribute__((noinline, visibility("hidden") _CALL_TYPE))
+        __attribute__((__noinline__, visibility("hidden") _CALL_TYPE))
 #    define DR_WEAK_DECLARATION __attribute__((weak))
 /* GCC extension "__label__" confines the named label to the block scope. */
 #    define DR_ANNOTATION_OR_NATIVE(annotation, native_version, ...) \
diff --git a/core/lib/globals_api.h b/core/lib/globals_api.h
index a1f90a6509..65992a06e8 100644
--- a/core/lib/globals_api.h
+++ b/core/lib/globals_api.h
@@ -169,7 +169,7 @@ typedef _Bool bool;
 #    define ALIGN_VAR(x) __attribute__((aligned(x)))
 #    define INLINE_FORCED inline
 #    define WEAK __attribute__((weak))
-#    define NOINLINE __attribute__((noinline))
+#    define NOINLINE __attribute__((__noinline__))
 #endif
 
 /* Annotates intentional switch case fallthroughs to satisfy


Test patch:
diff --git a/suite/tests/client-interface/drcallstack-test.c b/suite/tests/client-interface/drcallstack-test.c
index 13b54d8fee..328458b0bd 100644
--- a/suite/tests/client-interface/drcallstack-test.c
+++ b/suite/tests/client-interface/drcallstack-test.c
@@ -33,7 +33,7 @@
 #include "tools.h"
 
 #ifdef LINUX
-#    define NOINLINE __attribute__((noinline))
+#    define NOINLINE __attribute__((__noinline__))
 #else
 #    error NYI
 #endif
diff --git a/suite/tests/tools.h b/suite/tests/tools.h
index a26f491d79..846099f3d5 100644
--- a/suite/tests/tools.h
+++ b/suite/tests/tools.h
@@ -291,7 +291,7 @@ page_size(void)
 #else /* UNIX */
 #    define EXPORT __attribute__((visibility("default")))
 #    define IMPORT extern
-#    define NOINLINE __attribute__((noinline))
+#    define NOINLINE __attribute__((__noinline__))
 #endif
 
 /* convenience macros for secure string buffer operations */