@@ -44,11 +44,6 @@ COMPILER_RT_VISIBILITY unsigned lprofRuntimeCounterRelocation(void) {
44
44
}
45
45
COMPILER_RT_VISIBILITY void lprofSetRuntimeCounterRelocation (unsigned Value ) {}
46
46
47
- /* VMO that contains the profile data for this module. */
48
- static zx_handle_t __llvm_profile_vmo ;
49
- /* Current offset within the VMO where data should be written next. */
50
- static uint64_t __llvm_profile_offset ;
51
-
52
47
static const char ProfileSinkName [] = "llvm-profile" ;
53
48
54
49
static inline void lprofWrite (const char * fmt , ...) {
@@ -62,50 +57,65 @@ static inline void lprofWrite(const char *fmt, ...) {
62
57
__sanitizer_log_write (s , ret + 1 );
63
58
}
64
59
60
+ struct lprofVMOWriterCtx {
61
+ /* VMO that contains the profile data for this module. */
62
+ zx_handle_t Vmo ;
63
+ /* Current offset within the VMO where data should be written next. */
64
+ uint64_t Offset ;
65
+ };
66
+
65
67
static uint32_t lprofVMOWriter (ProfDataWriter * This , ProfDataIOVec * IOVecs ,
66
68
uint32_t NumIOVecs ) {
69
+ struct lprofVMOWriterCtx * Ctx = (struct lprofVMOWriterCtx * )This -> WriterCtx ;
70
+
67
71
/* Compute the total length of data to be written. */
68
72
size_t Length = 0 ;
69
73
for (uint32_t I = 0 ; I < NumIOVecs ; I ++ )
70
74
Length += IOVecs [I ].ElmSize * IOVecs [I ].NumElm ;
71
75
72
76
/* Resize the VMO to ensure there's sufficient space for the data. */
73
- zx_status_t Status =
74
- _zx_vmo_set_size (__llvm_profile_vmo , __llvm_profile_offset + Length );
77
+ zx_status_t Status = _zx_vmo_set_size (Ctx -> Vmo , Ctx -> Offset + Length );
75
78
if (Status != ZX_OK )
76
79
return -1 ;
77
80
78
81
/* Copy the data into VMO. */
79
82
for (uint32_t I = 0 ; I < NumIOVecs ; I ++ ) {
80
83
size_t Length = IOVecs [I ].ElmSize * IOVecs [I ].NumElm ;
81
84
if (IOVecs [I ].Data ) {
82
- Status = _zx_vmo_write (__llvm_profile_vmo , IOVecs [I ].Data ,
83
- __llvm_profile_offset , Length );
85
+ Status = _zx_vmo_write (Ctx -> Vmo , IOVecs [I ].Data , Ctx -> Offset , Length );
84
86
if (Status != ZX_OK )
85
87
return -1 ;
86
88
} else if (IOVecs [I ].UseZeroPadding ) {
87
89
/* Resizing the VMO should zero fill. */
88
90
}
89
- __llvm_profile_offset += Length ;
91
+ Ctx -> Offset += Length ;
90
92
}
91
93
92
94
/* Record the profile size as a property of the VMO. */
93
- _zx_object_set_property (__llvm_profile_vmo , ZX_PROP_VMO_CONTENT_SIZE ,
94
- & __llvm_profile_offset ,
95
- sizeof (__llvm_profile_offset ));
95
+ _zx_object_set_property (Ctx -> Vmo , ZX_PROP_VMO_CONTENT_SIZE , & Ctx -> Offset ,
96
+ sizeof (Ctx -> Offset ));
96
97
97
98
return 0 ;
98
99
}
99
100
100
- static void initVMOWriter (ProfDataWriter * This ) {
101
+ static void initVMOWriter (ProfDataWriter * This , struct lprofVMOWriterCtx * Ctx ) {
101
102
This -> Write = lprofVMOWriter ;
102
- This -> WriterCtx = NULL ;
103
+ This -> WriterCtx = Ctx ;
103
104
}
104
105
105
106
/* This method is invoked by the runtime initialization hook
106
107
* InstrProfilingRuntime.o if it is linked in. */
107
108
COMPILER_RT_VISIBILITY
108
109
void __llvm_profile_initialize (void ) {
110
+ /* Check if there is llvm/runtime version mismatch. */
111
+ if (GET_VERSION (__llvm_profile_get_version ()) != INSTR_PROF_RAW_VERSION ) {
112
+ lprofWrite ("LLVM Profile: runtime and instrumentation version mismatch: "
113
+ "expected %d, but got %d\n" ,
114
+ INSTR_PROF_RAW_VERSION ,
115
+ (int )GET_VERSION (__llvm_profile_get_version ()));
116
+ return ;
117
+ }
118
+
109
119
/* This symbol is defined as weak and initialized to -1 by the runtimer, but
110
120
* compiler will generate a strong definition initialized to 0 when runtime
111
121
* counter relocation is used. */
@@ -114,22 +124,17 @@ void __llvm_profile_initialize(void) {
114
124
return ;
115
125
}
116
126
117
- /* Don't create VMO if it has been alread created. */
118
- if (__llvm_profile_vmo != ZX_HANDLE_INVALID ) {
119
- lprofWrite ("LLVM Profile: VMO has already been created\n" );
120
- return ;
121
- }
122
-
123
127
const __llvm_profile_data * DataBegin = __llvm_profile_begin_data ();
124
128
const __llvm_profile_data * DataEnd = __llvm_profile_end_data ();
125
129
const uint64_t DataSize = __llvm_profile_get_data_size (DataBegin , DataEnd );
126
- const uint64_t CountersOffset = sizeof ( __llvm_profile_header ) +
127
- (DataSize * sizeof (__llvm_profile_data ));
130
+ const uint64_t CountersOffset =
131
+ sizeof ( __llvm_profile_header ) + (DataSize * sizeof (__llvm_profile_data ));
128
132
129
133
zx_status_t Status ;
130
134
131
135
/* Create VMO to hold the profile data. */
132
- Status = _zx_vmo_create (0 , ZX_VMO_RESIZABLE , & __llvm_profile_vmo );
136
+ zx_handle_t Vmo = ZX_HANDLE_INVALID ;
137
+ Status = _zx_vmo_create (0 , ZX_VMO_RESIZABLE , & Vmo );
133
138
if (Status != ZX_OK ) {
134
139
lprofWrite ("LLVM Profile: cannot create VMO: %s\n" ,
135
140
_zx_status_get_string (Status ));
@@ -140,65 +145,49 @@ void __llvm_profile_initialize(void) {
140
145
char VmoName [ZX_MAX_NAME_LEN ];
141
146
snprintf (VmoName , sizeof (VmoName ), "%" PRIu64 ".profraw" ,
142
147
lprofGetLoadModuleSignature ());
143
- _zx_object_set_property (__llvm_profile_vmo , ZX_PROP_NAME , VmoName ,
144
- strlen (VmoName ));
145
-
146
- /* Duplicate the handle since __sanitizer_publish_data consumes it. */
147
- zx_handle_t Handle ;
148
- Status =
149
- _zx_handle_duplicate (__llvm_profile_vmo , ZX_RIGHT_SAME_RIGHTS , & Handle );
150
- if (Status != ZX_OK ) {
151
- lprofWrite ("LLVM Profile: cannot duplicate VMO handle: %s\n" ,
152
- _zx_status_get_string (Status ));
153
- _zx_handle_close (__llvm_profile_vmo );
154
- __llvm_profile_vmo = ZX_HANDLE_INVALID ;
155
- return ;
156
- }
157
-
158
- /* Publish the VMO which contains profile data to the system. */
159
- __sanitizer_publish_data (ProfileSinkName , Handle );
160
-
161
- /* Use the dumpfile symbolizer markup element to write the name of VMO. */
162
- lprofWrite ("LLVM Profile: {{{dumpfile:%s:%s}}}\n" , ProfileSinkName , VmoName );
163
-
164
- /* Check if there is llvm/runtime version mismatch. */
165
- if (GET_VERSION (__llvm_profile_get_version ()) != INSTR_PROF_RAW_VERSION ) {
166
- lprofWrite ("LLVM Profile: runtime and instrumentation version mismatch: "
167
- "expected %d, but got %d\n" ,
168
- INSTR_PROF_RAW_VERSION ,
169
- (int )GET_VERSION (__llvm_profile_get_version ()));
170
- return ;
171
- }
148
+ _zx_object_set_property (Vmo , ZX_PROP_NAME , VmoName , strlen (VmoName ));
172
149
173
150
/* Write the profile data into the mapped region. */
174
151
ProfDataWriter VMOWriter ;
175
- initVMOWriter (& VMOWriter );
152
+ struct lprofVMOWriterCtx Ctx = {.Vmo = Vmo , .Offset = 0 };
153
+ initVMOWriter (& VMOWriter , & Ctx );
176
154
if (lprofWriteData (& VMOWriter , 0 , 0 ) != 0 ) {
177
155
lprofWrite ("LLVM Profile: failed to write data\n" );
156
+ _zx_handle_close (Vmo );
178
157
return ;
179
158
}
180
159
181
160
uint64_t Len = 0 ;
182
- Status = _zx_vmo_get_size (__llvm_profile_vmo , & Len );
161
+ Status = _zx_vmo_get_size (Vmo , & Len );
183
162
if (Status != ZX_OK ) {
184
163
lprofWrite ("LLVM Profile: failed to get the VMO size: %s\n" ,
185
164
_zx_status_get_string (Status ));
165
+ _zx_handle_close (Vmo );
186
166
return ;
187
167
}
188
168
189
169
uintptr_t Mapping ;
190
170
Status =
191
- _zx_vmar_map (_zx_vmar_root_self (), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE ,
192
- 0 , __llvm_profile_vmo , 0 , Len , & Mapping );
171
+ _zx_vmar_map (_zx_vmar_root_self (), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE , 0 ,
172
+ Vmo , 0 , Len , & Mapping );
193
173
if (Status != ZX_OK ) {
194
174
lprofWrite ("LLVM Profile: failed to map the VMO: %s\n" ,
195
175
_zx_status_get_string (Status ));
176
+ _zx_handle_close (Vmo );
196
177
return ;
197
178
}
198
179
180
+ /* Publish the VMO which contains profile data to the system. Note that this
181
+ * also consumes the VMO handle. */
182
+ __sanitizer_publish_data (ProfileSinkName , Vmo );
183
+
184
+ /* Use the dumpfile symbolizer markup element to write the name of VMO. */
185
+ lprofWrite ("LLVM Profile: {{{dumpfile:%s:%s}}}\n" , ProfileSinkName , VmoName );
186
+
199
187
/* Update the profile fields based on the current mapping. */
200
188
__llvm_profile_counter_bias = (intptr_t )Mapping -
201
- (uintptr_t )__llvm_profile_begin_counters () + CountersOffset ;
189
+ (uintptr_t )__llvm_profile_begin_counters () +
190
+ CountersOffset ;
202
191
}
203
192
204
193
#endif
0 commit comments