@@ -173,11 +173,36 @@ int bpf_create_map_in_map(enum bpf_map_type map_type, const char *name,
173
173
-1 );
174
174
}
175
175
176
+ static void *
177
+ alloc_zero_tailing_info (const void * orecord , __u32 cnt ,
178
+ __u32 actual_rec_size , __u32 expected_rec_size )
179
+ {
180
+ __u64 info_len = actual_rec_size * cnt ;
181
+ void * info , * nrecord ;
182
+ int i ;
183
+
184
+ info = malloc (info_len );
185
+ if (!info )
186
+ return NULL ;
187
+
188
+ /* zero out bytes kernel does not understand */
189
+ nrecord = info ;
190
+ for (i = 0 ; i < cnt ; i ++ ) {
191
+ memcpy (nrecord , orecord , expected_rec_size );
192
+ memset (nrecord + expected_rec_size , 0 ,
193
+ actual_rec_size - expected_rec_size );
194
+ orecord += actual_rec_size ;
195
+ nrecord += actual_rec_size ;
196
+ }
197
+
198
+ return info ;
199
+ }
200
+
176
201
int bpf_load_program_xattr (const struct bpf_load_program_attr * load_attr ,
177
202
char * log_buf , size_t log_buf_sz )
178
203
{
204
+ void * finfo = NULL , * linfo = NULL ;
179
205
union bpf_attr attr ;
180
- void * finfo = NULL ;
181
206
__u32 name_len ;
182
207
int fd ;
183
208
@@ -201,6 +226,9 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
201
226
attr .func_info_rec_size = load_attr -> func_info_rec_size ;
202
227
attr .func_info_cnt = load_attr -> func_info_cnt ;
203
228
attr .func_info = ptr_to_u64 (load_attr -> func_info );
229
+ attr .line_info_rec_size = load_attr -> line_info_rec_size ;
230
+ attr .line_info_cnt = load_attr -> line_info_cnt ;
231
+ attr .line_info = ptr_to_u64 (load_attr -> line_info );
204
232
memcpy (attr .prog_name , load_attr -> name ,
205
233
min (name_len , BPF_OBJ_NAME_LEN - 1 ));
206
234
@@ -212,36 +240,35 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
212
240
* to give user space a hint how to deal with loading failure.
213
241
* Check to see whether we can make some changes and load again.
214
242
*/
215
- if (errno == E2BIG && attr .func_info_cnt &&
216
- attr .func_info_rec_size < load_attr -> func_info_rec_size ) {
217
- __u32 actual_rec_size = load_attr -> func_info_rec_size ;
218
- __u32 expected_rec_size = attr .func_info_rec_size ;
219
- __u32 finfo_cnt = load_attr -> func_info_cnt ;
220
- __u64 finfo_len = actual_rec_size * finfo_cnt ;
221
- const void * orecord ;
222
- void * nrecord ;
223
- int i ;
224
-
225
- finfo = malloc (finfo_len );
226
- if (!finfo )
227
- /* further try with log buffer won't help */
228
- return fd ;
229
-
230
- /* zero out bytes kernel does not understand */
231
- orecord = load_attr -> func_info ;
232
- nrecord = finfo ;
233
- for (i = 0 ; i < load_attr -> func_info_cnt ; i ++ ) {
234
- memcpy (nrecord , orecord , expected_rec_size );
235
- memset (nrecord + expected_rec_size , 0 ,
236
- actual_rec_size - expected_rec_size );
237
- orecord += actual_rec_size ;
238
- nrecord += actual_rec_size ;
243
+ while (errno == E2BIG && (!finfo || !linfo )) {
244
+ if (!finfo && attr .func_info_cnt &&
245
+ attr .func_info_rec_size < load_attr -> func_info_rec_size ) {
246
+ /* try with corrected func info records */
247
+ finfo = alloc_zero_tailing_info (load_attr -> func_info ,
248
+ load_attr -> func_info_cnt ,
249
+ load_attr -> func_info_rec_size ,
250
+ attr .func_info_rec_size );
251
+ if (!finfo )
252
+ goto done ;
253
+
254
+ attr .func_info = ptr_to_u64 (finfo );
255
+ attr .func_info_rec_size = load_attr -> func_info_rec_size ;
256
+ } else if (!linfo && attr .line_info_cnt &&
257
+ attr .line_info_rec_size <
258
+ load_attr -> line_info_rec_size ) {
259
+ linfo = alloc_zero_tailing_info (load_attr -> line_info ,
260
+ load_attr -> line_info_cnt ,
261
+ load_attr -> line_info_rec_size ,
262
+ attr .line_info_rec_size );
263
+ if (!linfo )
264
+ goto done ;
265
+
266
+ attr .line_info = ptr_to_u64 (linfo );
267
+ attr .line_info_rec_size = load_attr -> line_info_rec_size ;
268
+ } else {
269
+ break ;
239
270
}
240
271
241
- /* try with corrected func info records */
242
- attr .func_info = ptr_to_u64 (finfo );
243
- attr .func_info_rec_size = load_attr -> func_info_rec_size ;
244
-
245
272
fd = sys_bpf (BPF_PROG_LOAD , & attr , sizeof (attr ));
246
273
247
274
if (fd >= 0 )
@@ -259,6 +286,7 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
259
286
fd = sys_bpf (BPF_PROG_LOAD , & attr , sizeof (attr ));
260
287
done :
261
288
free (finfo );
289
+ free (linfo );
262
290
return fd ;
263
291
}
264
292
0 commit comments