Skip to content

Commit 80da58d

Browse files
authored
[compiler-rt][XRay] Make xray_interface.h C compliant (#140068)
The XRay interface header uses no C++ specific features aside from using the `std` namespace and including the C++ variant of C headers. Yet, these changes prevent using `xray_interface.h` in external tools relying on C for different reasons. Make this header C compliant by using C headers, removing the `std` namespace from `std::size_t` and guard `extern "C"`. To make sure that further changes to not break the interface accidentally, port one test from C++ to C. This requires the C23 standard to officially support the attribute syntax used in this test case. Note that this only resolves this issue for `xray_interface.h`. `xray_records.h` is also not C compliant, but requires more work to port. Fixes #139902 Signed-off-by: Jan André Reuter <[email protected]>
1 parent 1d5bf04 commit 80da58d

File tree

2 files changed

+74
-14
lines changed

2 files changed

+74
-14
lines changed

compiler-rt/include/xray/xray_interface.h

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===- xray_interface.h -----------------------------------------*- C++ -*-===//
1+
//===- xray_interface.h ---------------------------------------------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
@@ -14,10 +14,17 @@
1414
#ifndef XRAY_XRAY_INTERFACE_H
1515
#define XRAY_XRAY_INTERFACE_H
1616

17+
#ifdef __cplusplus
1718
#include <cstddef>
1819
#include <cstdint>
20+
#else
21+
#include <stddef.h>
22+
#include <stdint.h>
23+
#endif
1924

25+
#ifdef __cplusplus
2026
extern "C" {
27+
#endif
2128

2229
/// Synchronize this with AsmPrinter::SledKind in LLVM.
2330
enum XRayEntryType {
@@ -49,7 +56,7 @@ enum XRayEntryType {
4956
/// achieved by marking them all with: __attribute__((xray_never_instrument))
5057
///
5158
/// Returns 1 on success, 0 on error.
52-
extern int __xray_set_handler(void (*entry)(int32_t, XRayEntryType));
59+
extern int __xray_set_handler(void (*entry)(int32_t, enum XRayEntryType));
5360

5461
/// This removes whatever the currently provided handler is. Returns 1 on
5562
/// success, 0 on error.
@@ -60,15 +67,15 @@ extern int __xray_remove_handler();
6067
/// start logging their subsequent affected function calls (if patched).
6168
///
6269
/// Returns 1 on success, 0 on error.
63-
extern int __xray_set_handler_arg1(void (*entry)(int32_t, XRayEntryType,
70+
extern int __xray_set_handler_arg1(void (*entry)(int32_t, enum XRayEntryType,
6471
uint64_t));
6572

6673
/// Disables the XRay handler used to log first arguments of function calls.
6774
/// Returns 1 on success, 0 on error.
6875
extern int __xray_remove_handler_arg1();
6976

7077
/// Provide a function to invoke when XRay encounters a custom event.
71-
extern int __xray_set_customevent_handler(void (*entry)(void *, std::size_t));
78+
extern int __xray_set_customevent_handler(void (*entry)(void *, size_t));
7279

7380
/// This removes whatever the currently provided custom event handler is.
7481
/// Returns 1 on success, 0 on error.
@@ -95,39 +102,39 @@ enum XRayPatchingStatus {
95102

96103
/// This tells XRay to patch the instrumentation points in all currently loaded
97104
/// objects. See XRayPatchingStatus for possible result values.
98-
extern XRayPatchingStatus __xray_patch();
105+
extern enum XRayPatchingStatus __xray_patch();
99106

100107
/// This tells XRay to patch the instrumentation points in the given object.
101108
/// See XRayPatchingStatus for possible result values.
102-
extern XRayPatchingStatus __xray_patch_object(int32_t ObjId);
109+
extern enum XRayPatchingStatus __xray_patch_object(int32_t ObjId);
103110

104111
/// Reverses the effect of __xray_patch(). See XRayPatchingStatus for possible
105112
/// result values.
106-
extern XRayPatchingStatus __xray_unpatch();
113+
extern enum XRayPatchingStatus __xray_unpatch();
107114

108115
/// Reverses the effect of __xray_patch_object. See XRayPatchingStatus for
109116
/// possible result values.
110-
extern XRayPatchingStatus __xray_unpatch_object(int32_t ObjId);
117+
extern enum XRayPatchingStatus __xray_unpatch_object(int32_t ObjId);
111118

112119
/// This unpacks the given (packed) function id and patches
113120
/// the corresponding function. See XRayPatchingStatus for possible
114121
/// result values.
115-
extern XRayPatchingStatus __xray_patch_function(int32_t FuncId);
122+
extern enum XRayPatchingStatus __xray_patch_function(int32_t FuncId);
116123

117124
/// This patches a specific function in the given object. See XRayPatchingStatus
118125
/// for possible result values.
119-
extern XRayPatchingStatus __xray_patch_function_in_object(int32_t FuncId,
120-
int32_t ObjId);
126+
extern enum XRayPatchingStatus __xray_patch_function_in_object(int32_t FuncId,
127+
int32_t ObjId);
121128

122129
/// This unpacks the given (packed) function id and unpatches
123130
/// the corresponding function. See XRayPatchingStatus for possible
124131
/// result values.
125-
extern XRayPatchingStatus __xray_unpatch_function(int32_t FuncId);
132+
extern enum XRayPatchingStatus __xray_unpatch_function(int32_t FuncId);
126133

127134
/// This unpatches a specific function in the given object.
128135
/// See XRayPatchingStatus for possible result values.
129-
extern XRayPatchingStatus __xray_unpatch_function_in_object(int32_t FuncId,
130-
int32_t ObjId);
136+
extern enum XRayPatchingStatus __xray_unpatch_function_in_object(int32_t FuncId,
137+
int32_t ObjId);
131138

132139
/// This function unpacks the given (packed) function id and returns the address
133140
/// of the corresponding function. We return 0 if we encounter any error, even
@@ -173,6 +180,8 @@ extern int32_t __xray_pack_id(int32_t FuncId, int32_t ObjId);
173180
/// Calling __xray_init() more than once is safe across multiple threads.
174181
extern void __xray_init();
175182

183+
#ifdef __cplusplus
176184
} // end extern "C"
185+
#endif
177186

178187
#endif // XRAY_XRAY_INTERFACE_H
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Check that we can patch and un-patch on demand, and that logging gets invoked
2+
// appropriately.
3+
//
4+
// RUN: %clang_xray -fxray-instrument -std=c23 %s -o %t
5+
// RUN: env XRAY_OPTIONS="patch_premain=false" %run %t 2>&1 | FileCheck %s
6+
// RUN: %clang_xray -fxray-instrument -fno-xray-function-index -std=c23 %s -o %t
7+
// RUN: env XRAY_OPTIONS="patch_premain=false" %run %t 2>&1 | FileCheck %s
8+
9+
// UNSUPPORTED: target-is-mips64,target-is-mips64el
10+
11+
#include "xray/xray_interface.h"
12+
13+
#include <stdio.h>
14+
15+
bool called = false;
16+
17+
void test_handler(int32_t fid, enum XRayEntryType type) {
18+
printf("called: %d, type=%d\n", fid, (int32_t)(type));
19+
called = true;
20+
}
21+
22+
[[clang::xray_always_instrument]] void always_instrument() {
23+
printf("always instrumented called\n");
24+
}
25+
26+
int main() {
27+
__xray_set_handler(test_handler);
28+
always_instrument();
29+
// CHECK: always instrumented called
30+
auto status = __xray_patch();
31+
printf("patching status: %d\n", (int32_t)status);
32+
// CHECK-NEXT: patching status: 1
33+
always_instrument();
34+
// CHECK-NEXT: called: {{.*}}, type=0
35+
// CHECK-NEXT: always instrumented called
36+
// CHECK-NEXT: called: {{.*}}, type=1
37+
status = __xray_unpatch();
38+
printf("patching status: %d\n", (int32_t)status);
39+
// CHECK-NEXT: patching status: 1
40+
always_instrument();
41+
// CHECK-NEXT: always instrumented called
42+
status = __xray_patch();
43+
printf("patching status: %d\n", (int32_t)status);
44+
// CHECK-NEXT: patching status: 1
45+
__xray_remove_handler();
46+
always_instrument();
47+
// CHECK-NEXT: always instrumented called
48+
status = __xray_unpatch();
49+
printf("patching status: %d\n", (int32_t)status);
50+
// CHECK-NEXT: patching status: 1
51+
}

0 commit comments

Comments
 (0)