~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/dsos.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /tools/perf/util/dsos.c (Version linux-6.11-rc3) and /tools/perf/util/dsos.c (Version linux-2.4.37.11)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 #include "debug.h"                                
  3 #include "dsos.h"                                 
  4 #include "dso.h"                                  
  5 #include "util.h"                                 
  6 #include "vdso.h"                                 
  7 #include "namespaces.h"                           
  8 #include <errno.h>                                
  9 #include <libgen.h>                               
 10 #include <stdlib.h>                               
 11 #include <string.h>                               
 12 #include <symbol.h> // filename__read_build_id    
 13 #include <unistd.h>                               
 14                                                   
 15 void dsos__init(struct dsos *dsos)                
 16 {                                                 
 17         init_rwsem(&dsos->lock);                  
 18                                                   
 19         dsos->cnt = 0;                            
 20         dsos->allocated = 0;                      
 21         dsos->dsos = NULL;                        
 22         dsos->sorted = true;                      
 23 }                                                 
 24                                                   
 25 static void dsos__purge(struct dsos *dsos)        
 26 {                                                 
 27         down_write(&dsos->lock);                  
 28                                                   
 29         for (unsigned int i = 0; i < dsos->cnt    
 30                 struct dso *dso = dsos->dsos[i    
 31                                                   
 32                 dso__set_dsos(dso, NULL);         
 33                 dso__put(dso);                    
 34         }                                         
 35                                                   
 36         zfree(&dsos->dsos);                       
 37         dsos->cnt = 0;                            
 38         dsos->allocated = 0;                      
 39         dsos->sorted = true;                      
 40                                                   
 41         up_write(&dsos->lock);                    
 42 }                                                 
 43                                                   
 44 void dsos__exit(struct dsos *dsos)                
 45 {                                                 
 46         dsos__purge(dsos);                        
 47         exit_rwsem(&dsos->lock);                  
 48 }                                                 
 49                                                   
 50                                                   
 51 static int __dsos__for_each_dso(struct dsos *d    
 52                                 int (*cb)(stru    
 53                                 void *data)       
 54 {                                                 
 55         for (unsigned int i = 0; i < dsos->cnt    
 56                 struct dso *dso = dsos->dsos[i    
 57                 int err;                          
 58                                                   
 59                 err = cb(dso, data);              
 60                 if (err)                          
 61                         return err;               
 62         }                                         
 63         return 0;                                 
 64 }                                                 
 65                                                   
 66 struct dsos__read_build_ids_cb_args {             
 67         bool with_hits;                           
 68         bool have_build_id;                       
 69 };                                                
 70                                                   
 71 static int dsos__read_build_ids_cb(struct dso     
 72 {                                                 
 73         struct dsos__read_build_ids_cb_args *a    
 74         struct nscookie nsc;                      
 75                                                   
 76         if (args->with_hits && !dso__hit(dso)     
 77                 return 0;                         
 78         if (dso__has_build_id(dso)) {             
 79                 args->have_build_id = true;       
 80                 return 0;                         
 81         }                                         
 82         nsinfo__mountns_enter(dso__nsinfo(dso)    
 83         if (filename__read_build_id(dso__long_    
 84                 args->have_build_id = true;       
 85                 dso__set_has_build_id(dso);       
 86         } else if (errno == ENOENT && dso__nsi    
 87                 char *new_name = dso__filename    
 88                                                   
 89                 if (new_name && filename__read    
 90                         args->have_build_id =     
 91                         dso__set_has_build_id(    
 92                 }                                 
 93                 free(new_name);                   
 94         }                                         
 95         nsinfo__mountns_exit(&nsc);               
 96         return 0;                                 
 97 }                                                 
 98                                                   
 99 bool dsos__read_build_ids(struct dsos *dsos, b    
100 {                                                 
101         struct dsos__read_build_ids_cb_args ar    
102                 .with_hits = with_hits,           
103                 .have_build_id = false,           
104         };                                        
105                                                   
106         dsos__for_each_dso(dsos, dsos__read_bu    
107         return args.have_build_id;                
108 }                                                 
109                                                   
110 static int __dso__cmp_long_name(const char *lo    
111                                 const struct d    
112 {                                                 
113         int rc = strcmp(long_name, dso__long_n    
114         return rc ?: dso_id__cmp(id, dso__id_c    
115 }                                                 
116                                                   
117 static int __dso__cmp_short_name(const char *s    
118                                  const struct     
119 {                                                 
120         int rc = strcmp(short_name, dso__short    
121         return rc ?: dso_id__cmp(id, dso__id_c    
122 }                                                 
123                                                   
124 static int dsos__cmp_long_name_id_short_name(c    
125 {                                                 
126         const struct dso *a = *((const struct     
127         const struct dso *b = *((const struct     
128         int rc = strcmp(dso__long_name(a), dso    
129                                                   
130         if (!rc) {                                
131                 rc = dso_id__cmp(dso__id_const    
132                 if (!rc)                          
133                         rc = strcmp(dso__short    
134         }                                         
135         return rc;                                
136 }                                                 
137                                                   
138 struct dsos__key {                                
139         const char *long_name;                    
140         const struct dso_id *id;                  
141 };                                                
142                                                   
143 static int dsos__cmp_key_long_name_id(const vo    
144 {                                                 
145         const struct dsos__key *key = vkey;       
146         const struct dso *dso = *((const struc    
147                                                   
148         return __dso__cmp_long_name(key->long_    
149 }                                                 
150                                                   
151 /*                                                
152  * Find a matching entry and/or link current e    
153  * Either one of the dso or name parameter mus    
154  * function will not work.                        
155  */                                               
156 static struct dso *__dsos__find_by_longname_id    
157                                                   
158                                                   
159                                                   
160 {                                                 
161         struct dsos__key key = {                  
162                 .long_name = name,                
163                 .id = id,                         
164         };                                        
165         struct dso **res;                         
166                                                   
167         if (dsos->dsos == NULL)                   
168                 return NULL;                      
169                                                   
170         if (!dsos->sorted) {                      
171                 if (!write_locked) {              
172                         struct dso *dso;          
173                                                   
174                         up_read(&dsos->lock);     
175                         down_write(&dsos->lock    
176                         dso = __dsos__find_by_    
177                                                   
178                         up_write(&dsos->lock);    
179                         down_read(&dsos->lock)    
180                         return dso;               
181                 }                                 
182                 qsort(dsos->dsos, dsos->cnt, s    
183                       dsos__cmp_long_name_id_s    
184                 dsos->sorted = true;              
185         }                                         
186                                                   
187         res = bsearch(&key, dsos->dsos, dsos->    
188                       dsos__cmp_key_long_name_    
189         if (!res)                                 
190                 return NULL;                      
191                                                   
192         return dso__get(*res);                    
193 }                                                 
194                                                   
195 int __dsos__add(struct dsos *dsos, struct dso     
196 {                                                 
197         if (dsos->cnt == dsos->allocated) {       
198                 unsigned int to_allocate = 2;     
199                 struct dso **temp;                
200                                                   
201                 if (dsos->allocated > 0)          
202                         to_allocate = dsos->al    
203                 temp = realloc(dsos->dsos, siz    
204                 if (!temp)                        
205                         return -ENOMEM;           
206                 dsos->dsos = temp;                
207                 dsos->allocated = to_allocate;    
208         }                                         
209         if (!dsos->sorted) {                      
210                 dsos->dsos[dsos->cnt++] = dso_    
211         } else {                                  
212                 int low = 0, high = dsos->cnt     
213                 int insert = dsos->cnt; /* Def    
214                                                   
215                 while (low <= high) {             
216                         int mid = low + (high     
217                         int cmp = dsos__cmp_lo    
218                                                   
219                         if (cmp < 0) {            
220                                 low = mid + 1;    
221                         } else {                  
222                                 high = mid - 1    
223                                 insert = mid;     
224                         }                         
225                 }                                 
226                 memmove(&dsos->dsos[insert + 1    
227                         (dsos->cnt - insert) *    
228                 dsos->cnt++;                      
229                 dsos->dsos[insert] = dso__get(    
230         }                                         
231         dso__set_dsos(dso, dsos);                 
232         return 0;                                 
233 }                                                 
234                                                   
235 int dsos__add(struct dsos *dsos, struct dso *d    
236 {                                                 
237         int ret;                                  
238                                                   
239         down_write(&dsos->lock);                  
240         ret = __dsos__add(dsos, dso);             
241         up_write(&dsos->lock);                    
242         return ret;                               
243 }                                                 
244                                                   
245 struct dsos__find_id_cb_args {                    
246         const char *name;                         
247         struct dso_id *id;                        
248         struct dso *res;                          
249 };                                                
250                                                   
251 static int dsos__find_id_cb(struct dso *dso, v    
252 {                                                 
253         struct dsos__find_id_cb_args *args = d    
254                                                   
255         if (__dso__cmp_short_name(args->name,     
256                 args->res = dso__get(dso);        
257                 return 1;                         
258         }                                         
259         return 0;                                 
260                                                   
261 }                                                 
262                                                   
263 static struct dso *__dsos__find_id(struct dsos    
264                                    bool cmp_sh    
265 {                                                 
266         struct dso *res;                          
267                                                   
268         if (cmp_short) {                          
269                 struct dsos__find_id_cb_args a    
270                         .name = name,             
271                         .id = id,                 
272                         .res = NULL,              
273                 };                                
274                                                   
275                 __dsos__for_each_dso(dsos, dso    
276                 return args.res;                  
277         }                                         
278         res = __dsos__find_by_longname_id(dsos    
279         return res;                               
280 }                                                 
281                                                   
282 struct dso *dsos__find(struct dsos *dsos, cons    
283 {                                                 
284         struct dso *res;                          
285                                                   
286         down_read(&dsos->lock);                   
287         res = __dsos__find_id(dsos, name, NULL    
288         up_read(&dsos->lock);                     
289         return res;                               
290 }                                                 
291                                                   
292 static void dso__set_basename(struct dso *dso)    
293 {                                                 
294         char *base, *lname;                       
295         int tid;                                  
296                                                   
297         if (perf_pid_map_tid(dso__long_name(ds    
298                 if (asprintf(&base, "[JIT] tid    
299                         return;                   
300         } else {                                  
301               /*                                  
302                * basename() may modify path bu    
303                * a copy.                          
304                */                                 
305                 lname = strdup(dso__long_name(    
306                 if (!lname)                       
307                         return;                   
308                                                   
309                 /*                                
310                  * basename() may return a poi    
311                  * storage which is reused in     
312                  * so copy the result.            
313                  */                               
314                 base = strdup(basename(lname))    
315                                                   
316                 free(lname);                      
317                                                   
318                 if (!base)                        
319                         return;                   
320         }                                         
321         dso__set_short_name(dso, base, true);     
322 }                                                 
323                                                   
324 static struct dso *__dsos__addnew_id(struct ds    
325 {                                                 
326         struct dso *dso = dso__new_id(name, id    
327                                                   
328         if (dso != NULL) {                        
329                 /*                                
330                  * The dsos lock is held on en    
331                  * adding it to avoid needing     
332                  * the array isn't sorted.        
333                  */                               
334                 dso__set_basename(dso);           
335                 __dsos__add(dsos, dso);           
336         }                                         
337         return dso;                               
338 }                                                 
339                                                   
340 static struct dso *__dsos__findnew_id(struct d    
341 {                                                 
342         struct dso *dso = __dsos__find_id(dsos    
343                                                   
344         if (dso && dso_id__empty(dso__id(dso))    
345                 __dso__inject_id(dso, id);        
346                                                   
347         return dso ? dso : __dsos__addnew_id(d    
348 }                                                 
349                                                   
350 struct dso *dsos__findnew_id(struct dsos *dsos    
351 {                                                 
352         struct dso *dso;                          
353         down_write(&dsos->lock);                  
354         dso = __dsos__findnew_id(dsos, name, i    
355         up_write(&dsos->lock);                    
356         return dso;                               
357 }                                                 
358                                                   
359 struct dsos__fprintf_buildid_cb_args {            
360         FILE *fp;                                 
361         bool (*skip)(struct dso *dso, int parm    
362         int parm;                                 
363         size_t ret;                               
364 };                                                
365                                                   
366 static int dsos__fprintf_buildid_cb(struct dso    
367 {                                                 
368         struct dsos__fprintf_buildid_cb_args *    
369         char sbuild_id[SBUILD_ID_SIZE];           
370                                                   
371         if (args->skip && args->skip(dso, args    
372                 return 0;                         
373         build_id__sprintf(dso__bid(dso), sbuil    
374         args->ret += fprintf(args->fp, "%-40s     
375         return 0;                                 
376 }                                                 
377                                                   
378 size_t dsos__fprintf_buildid(struct dsos *dsos    
379                                bool (*skip)(st    
380 {                                                 
381         struct dsos__fprintf_buildid_cb_args a    
382                 .fp = fp,                         
383                 .skip = skip,                     
384                 .parm = parm,                     
385                 .ret = 0,                         
386         };                                        
387                                                   
388         dsos__for_each_dso(dsos, dsos__fprintf    
389         return args.ret;                          
390 }                                                 
391                                                   
392 struct dsos__fprintf_cb_args {                    
393         FILE *fp;                                 
394         size_t ret;                               
395 };                                                
396                                                   
397 static int dsos__fprintf_cb(struct dso *dso, v    
398 {                                                 
399         struct dsos__fprintf_cb_args *args = d    
400                                                   
401         args->ret += dso__fprintf(dso, args->f    
402         return 0;                                 
403 }                                                 
404                                                   
405 size_t dsos__fprintf(struct dsos *dsos, FILE *    
406 {                                                 
407         struct dsos__fprintf_cb_args args = {     
408                 .fp = fp,                         
409                 .ret = 0,                         
410         };                                        
411                                                   
412         dsos__for_each_dso(dsos, dsos__fprintf    
413         return args.ret;                          
414 }                                                 
415                                                   
416 static int dsos__hit_all_cb(struct dso *dso, v    
417 {                                                 
418         dso__set_hit(dso);                        
419         return 0;                                 
420 }                                                 
421                                                   
422 int dsos__hit_all(struct dsos *dsos)              
423 {                                                 
424         return dsos__for_each_dso(dsos, dsos__    
425 }                                                 
426                                                   
427 struct dso *dsos__findnew_module_dso(struct ds    
428                                      struct ma    
429                                      struct km    
430                                      const cha    
431 {                                                 
432         struct dso *dso;                          
433                                                   
434         down_write(&dsos->lock);                  
435                                                   
436         dso = __dsos__find_id(dsos, m->name, N    
437         if (dso) {                                
438                 up_write(&dsos->lock);            
439                 return dso;                       
440         }                                         
441         /*                                        
442          * Failed to find the dso so create it    
443          * to the array, to avoid unnecessary     
444          * issues.                                
445          */                                       
446         dso = dso__new_id(m->name, /*id=*/NULL    
447         if (!dso) {                               
448                 up_write(&dsos->lock);            
449                 return NULL;                      
450         }                                         
451         dso__set_basename(dso);                   
452         dso__set_module_info(dso, m, machine);    
453         dso__set_long_name(dso, strdup(filenam    
454         dso__set_kernel(dso, DSO_SPACE__KERNEL    
455         __dsos__add(dsos, dso);                   
456                                                   
457         up_write(&dsos->lock);                    
458         return dso;                               
459 }                                                 
460                                                   
461 static int dsos__find_kernel_dso_cb(struct dso    
462 {                                                 
463         struct dso **res = data;                  
464         /*                                        
465          * The cpumode passed to is_kernel_mod    
466          * event. If we insist on passing corr    
467          * we should record the cpumode when w    
468          * list.                                  
469          *                                        
470          * However we don't really need passin    
471          * correct cpumode must be kernel mode    
472          * onto kernel_dsos list).                
473          *                                        
474          * Therefore, we pass PERF_RECORD_MISC    
475          * is_kernel_module() treats it as a k    
476          */                                       
477         if (!dso__kernel(dso) ||                  
478             is_kernel_module(dso__long_name(ds    
479                 return 0;                         
480                                                   
481         *res = dso__get(dso);                     
482         return 1;                                 
483 }                                                 
484                                                   
485 struct dso *dsos__find_kernel_dso(struct dsos     
486 {                                                 
487         struct dso *res = NULL;                   
488                                                   
489         dsos__for_each_dso(dsos, dsos__find_ke    
490         return res;                               
491 }                                                 
492                                                   
493 int dsos__for_each_dso(struct dsos *dsos, int     
494 {                                                 
495         int err;                                  
496                                                   
497         down_read(&dsos->lock);                   
498         err = __dsos__for_each_dso(dsos, cb, d    
499         up_read(&dsos->lock);                     
500         return err;                               
501 }                                                 
502                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php