@@ -144,7 +144,32 @@ static int asnprintf(char **strp, size_t size, const char *fmt, ...)
144
144
return ret ;
145
145
}
146
146
147
- static char * build_id__filename (const char * sbuild_id , char * bf , size_t size )
147
+ char * build_id_cache__kallsyms_path (const char * sbuild_id , char * bf ,
148
+ size_t size )
149
+ {
150
+ bool is_alloc = !!bf ;
151
+ bool retry_old = true;
152
+
153
+ asnprintf (& bf , size , "%s/%s/%s/kallsyms" ,
154
+ buildid_dir , DSO__NAME_KALLSYMS , sbuild_id );
155
+ retry :
156
+ if (!access (bf , F_OK ))
157
+ return bf ;
158
+ if (is_alloc )
159
+ free (bf );
160
+ if (retry_old ) {
161
+ /* Try old style kallsyms cache */
162
+ asnprintf (& bf , size , "%s/%s/%s" ,
163
+ buildid_dir , DSO__NAME_KALLSYMS , sbuild_id );
164
+ retry_old = false;
165
+ goto retry ;
166
+ }
167
+
168
+ return NULL ;
169
+ }
170
+
171
+ static char * build_id_cache__linkname (const char * sbuild_id , char * bf ,
172
+ size_t size )
148
173
{
149
174
char * tmp = bf ;
150
175
int ret = asnprintf (& bf , size , "%s/.build-id/%.2s/%s" , buildid_dir ,
@@ -154,23 +179,52 @@ static char *build_id__filename(const char *sbuild_id, char *bf, size_t size)
154
179
return bf ;
155
180
}
156
181
182
+ static const char * build_id_cache__basename (bool is_kallsyms , bool is_vdso )
183
+ {
184
+ return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf" );
185
+ }
186
+
157
187
char * dso__build_id_filename (const struct dso * dso , char * bf , size_t size )
158
188
{
159
- char build_id_hex [SBUILD_ID_SIZE ];
189
+ bool is_kallsyms = dso__is_kallsyms ((struct dso * )dso );
190
+ bool is_vdso = dso__is_vdso ((struct dso * )dso );
191
+ char sbuild_id [SBUILD_ID_SIZE ];
192
+ char * linkname ;
193
+ bool alloc = (bf == NULL );
194
+ int ret ;
160
195
161
196
if (!dso -> has_build_id )
162
197
return NULL ;
163
198
164
- build_id__sprintf (dso -> build_id , sizeof (dso -> build_id ), build_id_hex );
165
- return build_id__filename (build_id_hex , bf , size );
199
+ build_id__sprintf (dso -> build_id , sizeof (dso -> build_id ), sbuild_id );
200
+ linkname = build_id_cache__linkname (sbuild_id , NULL , 0 );
201
+ if (!linkname )
202
+ return NULL ;
203
+
204
+ /* Check if old style build_id cache */
205
+ if (is_regular_file (linkname ))
206
+ ret = asnprintf (& bf , size , "%s" , linkname );
207
+ else
208
+ ret = asnprintf (& bf , size , "%s/%s" , linkname ,
209
+ build_id_cache__basename (is_kallsyms , is_vdso ));
210
+ if (ret < 0 || (!alloc && size < (unsigned int )ret ))
211
+ bf = NULL ;
212
+ free (linkname );
213
+
214
+ return bf ;
166
215
}
167
216
168
217
bool dso__build_id_is_kmod (const struct dso * dso , char * bf , size_t size )
169
218
{
170
- char * id_name , * ch ;
219
+ char * id_name = NULL , * ch ;
171
220
struct stat sb ;
221
+ char sbuild_id [SBUILD_ID_SIZE ];
222
+
223
+ if (!dso -> has_build_id )
224
+ goto err ;
172
225
173
- id_name = dso__build_id_filename (dso , bf , size );
226
+ build_id__sprintf (dso -> build_id , sizeof (dso -> build_id ), sbuild_id );
227
+ id_name = build_id_cache__linkname (sbuild_id , NULL , 0 );
174
228
if (!id_name )
175
229
goto err ;
176
230
if (access (id_name , F_OK ))
@@ -194,18 +248,14 @@ bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size)
194
248
if (ch - 3 < bf )
195
249
goto err ;
196
250
251
+ free (id_name );
197
252
return strncmp (".ko" , ch - 3 , 3 ) == 0 ;
198
253
err :
199
- /*
200
- * If dso__build_id_filename work, get id_name again,
201
- * because id_name points to bf and is broken.
202
- */
203
- if (id_name )
204
- id_name = dso__build_id_filename (dso , bf , size );
205
254
pr_err ("Invalid build id: %s\n" , id_name ? :
206
255
dso -> long_name ? :
207
256
dso -> short_name ? :
208
257
"[unknown]" );
258
+ free (id_name );
209
259
return false;
210
260
}
211
261
@@ -341,7 +391,8 @@ void disable_buildid_cache(void)
341
391
}
342
392
343
393
static char * build_id_cache__dirname_from_path (const char * name ,
344
- bool is_kallsyms , bool is_vdso )
394
+ bool is_kallsyms , bool is_vdso ,
395
+ const char * sbuild_id )
345
396
{
346
397
char * realname = (char * )name , * filename ;
347
398
bool slash = is_kallsyms || is_vdso ;
@@ -352,8 +403,9 @@ static char *build_id_cache__dirname_from_path(const char *name,
352
403
return NULL ;
353
404
}
354
405
355
- if (asprintf (& filename , "%s%s%s" , buildid_dir , slash ? "/" : "" ,
356
- is_vdso ? DSO__NAME_VDSO : realname ) < 0 )
406
+ if (asprintf (& filename , "%s%s%s%s%s" , buildid_dir , slash ? "/" : "" ,
407
+ is_vdso ? DSO__NAME_VDSO : realname ,
408
+ sbuild_id ? "/" : "" , sbuild_id ?: "" ) < 0 )
357
409
filename = NULL ;
358
410
359
411
if (!slash )
@@ -368,7 +420,8 @@ int build_id_cache__list_build_ids(const char *pathname,
368
420
char * dir_name ;
369
421
int ret = 0 ;
370
422
371
- dir_name = build_id_cache__dirname_from_path (pathname , false, false);
423
+ dir_name = build_id_cache__dirname_from_path (pathname , false, false,
424
+ NULL );
372
425
if (!dir_name )
373
426
return - ENOMEM ;
374
427
@@ -385,7 +438,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
385
438
{
386
439
const size_t size = PATH_MAX ;
387
440
char * realname = NULL , * filename = NULL , * dir_name = NULL ,
388
- * linkname = zalloc (size ), * targetname , * tmp ;
441
+ * linkname = zalloc (size ), * tmp ;
389
442
int err = -1 ;
390
443
391
444
if (!is_kallsyms ) {
@@ -394,14 +447,22 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
394
447
goto out_free ;
395
448
}
396
449
397
- dir_name = build_id_cache__dirname_from_path (name , is_kallsyms , is_vdso );
450
+ dir_name = build_id_cache__dirname_from_path (name , is_kallsyms ,
451
+ is_vdso , sbuild_id );
398
452
if (!dir_name )
399
453
goto out_free ;
400
454
455
+ /* Remove old style build-id cache */
456
+ if (is_regular_file (dir_name ))
457
+ if (unlink (dir_name ))
458
+ goto out_free ;
459
+
401
460
if (mkdir_p (dir_name , 0755 ))
402
461
goto out_free ;
403
462
404
- if (asprintf (& filename , "%s/%s" , dir_name , sbuild_id ) < 0 ) {
463
+ /* Save the allocated buildid dirname */
464
+ if (asprintf (& filename , "%s/%s" , dir_name ,
465
+ build_id_cache__basename (is_kallsyms , is_vdso )) < 0 ) {
405
466
filename = NULL ;
406
467
goto out_free ;
407
468
}
@@ -415,7 +476,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
415
476
goto out_free ;
416
477
}
417
478
418
- if (!build_id__filename (sbuild_id , linkname , size ))
479
+ if (!build_id_cache__linkname (sbuild_id , linkname , size ))
419
480
goto out_free ;
420
481
tmp = strrchr (linkname , '/' );
421
482
* tmp = '\0' ;
@@ -424,10 +485,10 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
424
485
goto out_free ;
425
486
426
487
* tmp = '/' ;
427
- targetname = filename + strlen (buildid_dir ) - 5 ;
428
- memcpy (targetname , "../.." , 5 );
488
+ tmp = dir_name + strlen (buildid_dir ) - 5 ;
489
+ memcpy (tmp , "../.." , 5 );
429
490
430
- if (symlink (targetname , linkname ) == 0 )
491
+ if (symlink (tmp , linkname ) == 0 )
431
492
err = 0 ;
432
493
out_free :
433
494
if (!is_kallsyms )
@@ -452,7 +513,7 @@ static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size,
452
513
bool build_id_cache__cached (const char * sbuild_id )
453
514
{
454
515
bool ret = false;
455
- char * filename = build_id__filename (sbuild_id , NULL , 0 );
516
+ char * filename = build_id_cache__linkname (sbuild_id , NULL , 0 );
456
517
457
518
if (filename && !access (filename , F_OK ))
458
519
ret = true;
@@ -471,7 +532,7 @@ int build_id_cache__remove_s(const char *sbuild_id)
471
532
if (filename == NULL || linkname == NULL )
472
533
goto out_free ;
473
534
474
- if (!build_id__filename (sbuild_id , linkname , size ))
535
+ if (!build_id_cache__linkname (sbuild_id , linkname , size ))
475
536
goto out_free ;
476
537
477
538
if (access (linkname , F_OK ))
@@ -489,7 +550,7 @@ int build_id_cache__remove_s(const char *sbuild_id)
489
550
tmp = strrchr (linkname , '/' ) + 1 ;
490
551
snprintf (tmp , size - (tmp - linkname ), "%s" , filename );
491
552
492
- if (unlink (linkname ))
553
+ if (rm_rf (linkname ))
493
554
goto out_free ;
494
555
495
556
err = 0 ;
@@ -501,7 +562,7 @@ int build_id_cache__remove_s(const char *sbuild_id)
501
562
502
563
static int dso__cache_build_id (struct dso * dso , struct machine * machine )
503
564
{
504
- bool is_kallsyms = dso -> kernel && dso -> long_name [ 0 ] != '/' ;
565
+ bool is_kallsyms = dso__is_kallsyms ( dso ) ;
505
566
bool is_vdso = dso__is_vdso (dso );
506
567
const char * name = dso -> long_name ;
507
568
char nm [PATH_MAX ];
0 commit comments