xref: /openbmc/linux/tools/perf/util/dsos.c (revision 7031edac)
14a3cec84SArnaldo Carvalho de Melo // SPDX-License-Identifier: GPL-2.0
24a3cec84SArnaldo Carvalho de Melo #include "debug.h"
34a3cec84SArnaldo Carvalho de Melo #include "dsos.h"
44a3cec84SArnaldo Carvalho de Melo #include "dso.h"
567fd1892SNamhyung Kim #include "util.h"
64a3cec84SArnaldo Carvalho de Melo #include "vdso.h"
74a3cec84SArnaldo Carvalho de Melo #include "namespaces.h"
867fd1892SNamhyung Kim #include <errno.h>
94a3cec84SArnaldo Carvalho de Melo #include <libgen.h>
104a3cec84SArnaldo Carvalho de Melo #include <stdlib.h>
114a3cec84SArnaldo Carvalho de Melo #include <string.h>
124a3cec84SArnaldo Carvalho de Melo #include <symbol.h> // filename__read_build_id
1367fd1892SNamhyung Kim #include <unistd.h>
144a3cec84SArnaldo Carvalho de Melo 
__dso_id__cmp(struct dso_id * a,struct dso_id * b)150e3149f8SArnaldo Carvalho de Melo static int __dso_id__cmp(struct dso_id *a, struct dso_id *b)
167b59a824SArnaldo Carvalho de Melo {
177b59a824SArnaldo Carvalho de Melo 	if (a->maj > b->maj) return -1;
187b59a824SArnaldo Carvalho de Melo 	if (a->maj < b->maj) return 1;
197b59a824SArnaldo Carvalho de Melo 
207b59a824SArnaldo Carvalho de Melo 	if (a->min > b->min) return -1;
217b59a824SArnaldo Carvalho de Melo 	if (a->min < b->min) return 1;
227b59a824SArnaldo Carvalho de Melo 
237b59a824SArnaldo Carvalho de Melo 	if (a->ino > b->ino) return -1;
247b59a824SArnaldo Carvalho de Melo 	if (a->ino < b->ino) return 1;
257b59a824SArnaldo Carvalho de Melo 
2668566a7cSAdrian Hunter 	/*
2768566a7cSAdrian Hunter 	 * Synthesized MMAP events have zero ino_generation, avoid comparing
2868566a7cSAdrian Hunter 	 * them with MMAP events with actual ino_generation.
2968566a7cSAdrian Hunter 	 *
3068566a7cSAdrian Hunter 	 * I found it harmful because the mismatch resulted in a new
3168566a7cSAdrian Hunter 	 * dso that did not have a build ID whereas the original dso did have a
3268566a7cSAdrian Hunter 	 * build ID. The build ID was essential because the object was not found
3368566a7cSAdrian Hunter 	 * otherwise. - Adrian
3468566a7cSAdrian Hunter 	 */
3568566a7cSAdrian Hunter 	if (a->ino_generation && b->ino_generation) {
367b59a824SArnaldo Carvalho de Melo 		if (a->ino_generation > b->ino_generation) return -1;
377b59a824SArnaldo Carvalho de Melo 		if (a->ino_generation < b->ino_generation) return 1;
3868566a7cSAdrian Hunter 	}
397b59a824SArnaldo Carvalho de Melo 
407b59a824SArnaldo Carvalho de Melo 	return 0;
417b59a824SArnaldo Carvalho de Melo }
427b59a824SArnaldo Carvalho de Melo 
dso_id__empty(struct dso_id * id)430d33b343SRavi Bangoria static bool dso_id__empty(struct dso_id *id)
440d33b343SRavi Bangoria {
450d33b343SRavi Bangoria 	if (!id)
460d33b343SRavi Bangoria 		return true;
470d33b343SRavi Bangoria 
480d33b343SRavi Bangoria 	return !id->maj && !id->min && !id->ino && !id->ino_generation;
490d33b343SRavi Bangoria }
500d33b343SRavi Bangoria 
dso__inject_id(struct dso * dso,struct dso_id * id)510d33b343SRavi Bangoria static void dso__inject_id(struct dso *dso, struct dso_id *id)
520d33b343SRavi Bangoria {
530d33b343SRavi Bangoria 	dso->id.maj = id->maj;
540d33b343SRavi Bangoria 	dso->id.min = id->min;
550d33b343SRavi Bangoria 	dso->id.ino = id->ino;
560d33b343SRavi Bangoria 	dso->id.ino_generation = id->ino_generation;
570d33b343SRavi Bangoria }
580d33b343SRavi Bangoria 
dso_id__cmp(struct dso_id * a,struct dso_id * b)590e3149f8SArnaldo Carvalho de Melo static int dso_id__cmp(struct dso_id *a, struct dso_id *b)
600e3149f8SArnaldo Carvalho de Melo {
610e3149f8SArnaldo Carvalho de Melo 	/*
620e3149f8SArnaldo Carvalho de Melo 	 * The second is always dso->id, so zeroes if not set, assume passing
630e3149f8SArnaldo Carvalho de Melo 	 * NULL for a means a zeroed id
640e3149f8SArnaldo Carvalho de Melo 	 */
650d33b343SRavi Bangoria 	if (dso_id__empty(a) || dso_id__empty(b))
660e3149f8SArnaldo Carvalho de Melo 		return 0;
670e3149f8SArnaldo Carvalho de Melo 
680e3149f8SArnaldo Carvalho de Melo 	return __dso_id__cmp(a, b);
690e3149f8SArnaldo Carvalho de Melo }
700e3149f8SArnaldo Carvalho de Melo 
dso__cmp_id(struct dso * a,struct dso * b)710e3149f8SArnaldo Carvalho de Melo int dso__cmp_id(struct dso *a, struct dso *b)
720e3149f8SArnaldo Carvalho de Melo {
730e3149f8SArnaldo Carvalho de Melo 	return __dso_id__cmp(&a->id, &b->id);
740e3149f8SArnaldo Carvalho de Melo }
750e3149f8SArnaldo Carvalho de Melo 
__dsos__read_build_ids(struct list_head * head,bool with_hits)764a3cec84SArnaldo Carvalho de Melo bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
774a3cec84SArnaldo Carvalho de Melo {
784a3cec84SArnaldo Carvalho de Melo 	bool have_build_id = false;
794a3cec84SArnaldo Carvalho de Melo 	struct dso *pos;
804a3cec84SArnaldo Carvalho de Melo 	struct nscookie nsc;
814a3cec84SArnaldo Carvalho de Melo 
824a3cec84SArnaldo Carvalho de Melo 	list_for_each_entry(pos, head, node) {
834a3cec84SArnaldo Carvalho de Melo 		if (with_hits && !pos->hit && !dso__is_vdso(pos))
844a3cec84SArnaldo Carvalho de Melo 			continue;
854a3cec84SArnaldo Carvalho de Melo 		if (pos->has_build_id) {
864a3cec84SArnaldo Carvalho de Melo 			have_build_id = true;
874a3cec84SArnaldo Carvalho de Melo 			continue;
884a3cec84SArnaldo Carvalho de Melo 		}
894a3cec84SArnaldo Carvalho de Melo 		nsinfo__mountns_enter(pos->nsinfo, &nsc);
90f766819cSJiri Olsa 		if (filename__read_build_id(pos->long_name, &pos->bid) > 0) {
914a3cec84SArnaldo Carvalho de Melo 			have_build_id	  = true;
924a3cec84SArnaldo Carvalho de Melo 			pos->has_build_id = true;
9367fd1892SNamhyung Kim 		} else if (errno == ENOENT && pos->nsinfo) {
94*7031edacSArnaldo Carvalho de Melo 			char *new_name = dso__filename_with_chroot(pos, pos->long_name);
9567fd1892SNamhyung Kim 
9667fd1892SNamhyung Kim 			if (new_name && filename__read_build_id(new_name,
9767fd1892SNamhyung Kim 								&pos->bid) > 0) {
9867fd1892SNamhyung Kim 				have_build_id = true;
9967fd1892SNamhyung Kim 				pos->has_build_id = true;
10067fd1892SNamhyung Kim 			}
10167fd1892SNamhyung Kim 			free(new_name);
1024a3cec84SArnaldo Carvalho de Melo 		}
1034a3cec84SArnaldo Carvalho de Melo 		nsinfo__mountns_exit(&nsc);
1044a3cec84SArnaldo Carvalho de Melo 	}
1054a3cec84SArnaldo Carvalho de Melo 
1064a3cec84SArnaldo Carvalho de Melo 	return have_build_id;
1074a3cec84SArnaldo Carvalho de Melo }
1084a3cec84SArnaldo Carvalho de Melo 
__dso__cmp_long_name(const char * long_name,struct dso_id * id,struct dso * b)1090e3149f8SArnaldo Carvalho de Melo static int __dso__cmp_long_name(const char *long_name, struct dso_id *id, struct dso *b)
1100e3149f8SArnaldo Carvalho de Melo {
1110e3149f8SArnaldo Carvalho de Melo 	int rc = strcmp(long_name, b->long_name);
1120e3149f8SArnaldo Carvalho de Melo 	return rc ?: dso_id__cmp(id, &b->id);
1130e3149f8SArnaldo Carvalho de Melo }
1140e3149f8SArnaldo Carvalho de Melo 
__dso__cmp_short_name(const char * short_name,struct dso_id * id,struct dso * b)1150e3149f8SArnaldo Carvalho de Melo static int __dso__cmp_short_name(const char *short_name, struct dso_id *id, struct dso *b)
1160e3149f8SArnaldo Carvalho de Melo {
1170e3149f8SArnaldo Carvalho de Melo 	int rc = strcmp(short_name, b->short_name);
1180e3149f8SArnaldo Carvalho de Melo 	return rc ?: dso_id__cmp(id, &b->id);
1190e3149f8SArnaldo Carvalho de Melo }
1200e3149f8SArnaldo Carvalho de Melo 
dso__cmp_short_name(struct dso * a,struct dso * b)1210e3149f8SArnaldo Carvalho de Melo static int dso__cmp_short_name(struct dso *a, struct dso *b)
1220e3149f8SArnaldo Carvalho de Melo {
1230e3149f8SArnaldo Carvalho de Melo 	return __dso__cmp_short_name(a->short_name, &a->id, b);
1240e3149f8SArnaldo Carvalho de Melo }
1250e3149f8SArnaldo Carvalho de Melo 
1264a3cec84SArnaldo Carvalho de Melo /*
1274a3cec84SArnaldo Carvalho de Melo  * Find a matching entry and/or link current entry to RB tree.
1284a3cec84SArnaldo Carvalho de Melo  * Either one of the dso or name parameter must be non-NULL or the
1294a3cec84SArnaldo Carvalho de Melo  * function will not work.
1304a3cec84SArnaldo Carvalho de Melo  */
__dsos__findnew_link_by_longname_id(struct rb_root * root,struct dso * dso,const char * name,struct dso_id * id)1310e3149f8SArnaldo Carvalho de Melo struct dso *__dsos__findnew_link_by_longname_id(struct rb_root *root, struct dso *dso,
1320e3149f8SArnaldo Carvalho de Melo 						const char *name, struct dso_id *id)
1334a3cec84SArnaldo Carvalho de Melo {
1344a3cec84SArnaldo Carvalho de Melo 	struct rb_node **p = &root->rb_node;
1354a3cec84SArnaldo Carvalho de Melo 	struct rb_node  *parent = NULL;
1364a3cec84SArnaldo Carvalho de Melo 
1374a3cec84SArnaldo Carvalho de Melo 	if (!name)
1384a3cec84SArnaldo Carvalho de Melo 		name = dso->long_name;
1394a3cec84SArnaldo Carvalho de Melo 	/*
1404a3cec84SArnaldo Carvalho de Melo 	 * Find node with the matching name
1414a3cec84SArnaldo Carvalho de Melo 	 */
1424a3cec84SArnaldo Carvalho de Melo 	while (*p) {
1434a3cec84SArnaldo Carvalho de Melo 		struct dso *this = rb_entry(*p, struct dso, rb_node);
1440e3149f8SArnaldo Carvalho de Melo 		int rc = __dso__cmp_long_name(name, id, this);
1454a3cec84SArnaldo Carvalho de Melo 
1464a3cec84SArnaldo Carvalho de Melo 		parent = *p;
1474a3cec84SArnaldo Carvalho de Melo 		if (rc == 0) {
1484a3cec84SArnaldo Carvalho de Melo 			/*
1494a3cec84SArnaldo Carvalho de Melo 			 * In case the new DSO is a duplicate of an existing
1504a3cec84SArnaldo Carvalho de Melo 			 * one, print a one-time warning & put the new entry
1514a3cec84SArnaldo Carvalho de Melo 			 * at the end of the list of duplicates.
1524a3cec84SArnaldo Carvalho de Melo 			 */
1534a3cec84SArnaldo Carvalho de Melo 			if (!dso || (dso == this))
1544a3cec84SArnaldo Carvalho de Melo 				return this;	/* Find matching dso */
1554a3cec84SArnaldo Carvalho de Melo 			/*
1564a3cec84SArnaldo Carvalho de Melo 			 * The core kernel DSOs may have duplicated long name.
1574a3cec84SArnaldo Carvalho de Melo 			 * In this case, the short name should be different.
1584a3cec84SArnaldo Carvalho de Melo 			 * Comparing the short names to differentiate the DSOs.
1594a3cec84SArnaldo Carvalho de Melo 			 */
1600e3149f8SArnaldo Carvalho de Melo 			rc = dso__cmp_short_name(dso, this);
1614a3cec84SArnaldo Carvalho de Melo 			if (rc == 0) {
1624a3cec84SArnaldo Carvalho de Melo 				pr_err("Duplicated dso name: %s\n", name);
1634a3cec84SArnaldo Carvalho de Melo 				return NULL;
1644a3cec84SArnaldo Carvalho de Melo 			}
1654a3cec84SArnaldo Carvalho de Melo 		}
1664a3cec84SArnaldo Carvalho de Melo 		if (rc < 0)
1674a3cec84SArnaldo Carvalho de Melo 			p = &parent->rb_left;
1684a3cec84SArnaldo Carvalho de Melo 		else
1694a3cec84SArnaldo Carvalho de Melo 			p = &parent->rb_right;
1704a3cec84SArnaldo Carvalho de Melo 	}
1714a3cec84SArnaldo Carvalho de Melo 	if (dso) {
1724a3cec84SArnaldo Carvalho de Melo 		/* Add new node and rebalance tree */
1734a3cec84SArnaldo Carvalho de Melo 		rb_link_node(&dso->rb_node, parent, p);
1744a3cec84SArnaldo Carvalho de Melo 		rb_insert_color(&dso->rb_node, root);
1754a3cec84SArnaldo Carvalho de Melo 		dso->root = root;
1764a3cec84SArnaldo Carvalho de Melo 	}
1774a3cec84SArnaldo Carvalho de Melo 	return NULL;
1784a3cec84SArnaldo Carvalho de Melo }
1794a3cec84SArnaldo Carvalho de Melo 
__dsos__add(struct dsos * dsos,struct dso * dso)1804a3cec84SArnaldo Carvalho de Melo void __dsos__add(struct dsos *dsos, struct dso *dso)
1814a3cec84SArnaldo Carvalho de Melo {
1824a3cec84SArnaldo Carvalho de Melo 	list_add_tail(&dso->node, &dsos->head);
1830e3149f8SArnaldo Carvalho de Melo 	__dsos__findnew_link_by_longname_id(&dsos->root, dso, NULL, &dso->id);
1844a3cec84SArnaldo Carvalho de Melo 	/*
1854a3cec84SArnaldo Carvalho de Melo 	 * It is now in the linked list, grab a reference, then garbage collect
1864a3cec84SArnaldo Carvalho de Melo 	 * this when needing memory, by looking at LRU dso instances in the
1874a3cec84SArnaldo Carvalho de Melo 	 * list with atomic_read(&dso->refcnt) == 1, i.e. no references
1884a3cec84SArnaldo Carvalho de Melo 	 * anywhere besides the one for the list, do, under a lock for the
1894a3cec84SArnaldo Carvalho de Melo 	 * list: remove it from the list, then a dso__put(), that probably will
1904a3cec84SArnaldo Carvalho de Melo 	 * be the last and will then call dso__delete(), end of life.
1914a3cec84SArnaldo Carvalho de Melo 	 *
1924a3cec84SArnaldo Carvalho de Melo 	 * That, or at the end of the 'struct machine' lifetime, when all
1934a3cec84SArnaldo Carvalho de Melo 	 * 'struct dso' instances will be removed from the list, in
1944a3cec84SArnaldo Carvalho de Melo 	 * dsos__exit(), if they have no other reference from some other data
1954a3cec84SArnaldo Carvalho de Melo 	 * structure.
1964a3cec84SArnaldo Carvalho de Melo 	 *
1974a3cec84SArnaldo Carvalho de Melo 	 * E.g.: after processing a 'perf.data' file and storing references
1984a3cec84SArnaldo Carvalho de Melo 	 * to objects instantiated while processing events, we will have
1994a3cec84SArnaldo Carvalho de Melo 	 * references to the 'thread', 'map', 'dso' structs all from 'struct
2004a3cec84SArnaldo Carvalho de Melo 	 * hist_entry' instances, but we may not need anything not referenced,
2014a3cec84SArnaldo Carvalho de Melo 	 * so we might as well call machines__exit()/machines__delete() and
2024a3cec84SArnaldo Carvalho de Melo 	 * garbage collect it.
2034a3cec84SArnaldo Carvalho de Melo 	 */
2044a3cec84SArnaldo Carvalho de Melo 	dso__get(dso);
2054a3cec84SArnaldo Carvalho de Melo }
2064a3cec84SArnaldo Carvalho de Melo 
dsos__add(struct dsos * dsos,struct dso * dso)2074a3cec84SArnaldo Carvalho de Melo void dsos__add(struct dsos *dsos, struct dso *dso)
2084a3cec84SArnaldo Carvalho de Melo {
2094a3cec84SArnaldo Carvalho de Melo 	down_write(&dsos->lock);
2104a3cec84SArnaldo Carvalho de Melo 	__dsos__add(dsos, dso);
2114a3cec84SArnaldo Carvalho de Melo 	up_write(&dsos->lock);
2124a3cec84SArnaldo Carvalho de Melo }
2134a3cec84SArnaldo Carvalho de Melo 
__dsos__findnew_by_longname_id(struct rb_root * root,const char * name,struct dso_id * id)2140e3149f8SArnaldo Carvalho de Melo static struct dso *__dsos__findnew_by_longname_id(struct rb_root *root, const char *name, struct dso_id *id)
2150e3149f8SArnaldo Carvalho de Melo {
2160e3149f8SArnaldo Carvalho de Melo 	return __dsos__findnew_link_by_longname_id(root, NULL, name, id);
2170e3149f8SArnaldo Carvalho de Melo }
2180e3149f8SArnaldo Carvalho de Melo 
__dsos__find_id(struct dsos * dsos,const char * name,struct dso_id * id,bool cmp_short)2190e3149f8SArnaldo Carvalho de Melo static struct dso *__dsos__find_id(struct dsos *dsos, const char *name, struct dso_id *id, bool cmp_short)
2204a3cec84SArnaldo Carvalho de Melo {
2214a3cec84SArnaldo Carvalho de Melo 	struct dso *pos;
2224a3cec84SArnaldo Carvalho de Melo 
2234a3cec84SArnaldo Carvalho de Melo 	if (cmp_short) {
2244a3cec84SArnaldo Carvalho de Melo 		list_for_each_entry(pos, &dsos->head, node)
2250e3149f8SArnaldo Carvalho de Melo 			if (__dso__cmp_short_name(name, id, pos) == 0)
2264a3cec84SArnaldo Carvalho de Melo 				return pos;
2274a3cec84SArnaldo Carvalho de Melo 		return NULL;
2284a3cec84SArnaldo Carvalho de Melo 	}
2290e3149f8SArnaldo Carvalho de Melo 	return __dsos__findnew_by_longname_id(&dsos->root, name, id);
2300e3149f8SArnaldo Carvalho de Melo }
2310e3149f8SArnaldo Carvalho de Melo 
__dsos__find(struct dsos * dsos,const char * name,bool cmp_short)2320e3149f8SArnaldo Carvalho de Melo struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
2330e3149f8SArnaldo Carvalho de Melo {
2340e3149f8SArnaldo Carvalho de Melo 	return __dsos__find_id(dsos, name, NULL, cmp_short);
2354a3cec84SArnaldo Carvalho de Melo }
2364a3cec84SArnaldo Carvalho de Melo 
dso__set_basename(struct dso * dso)2374a3cec84SArnaldo Carvalho de Melo static void dso__set_basename(struct dso *dso)
2384a3cec84SArnaldo Carvalho de Melo {
2394a3cec84SArnaldo Carvalho de Melo 	char *base, *lname;
2404a3cec84SArnaldo Carvalho de Melo 	int tid;
2414a3cec84SArnaldo Carvalho de Melo 
2424a3cec84SArnaldo Carvalho de Melo 	if (sscanf(dso->long_name, "/tmp/perf-%d.map", &tid) == 1) {
2434a3cec84SArnaldo Carvalho de Melo 		if (asprintf(&base, "[JIT] tid %d", tid) < 0)
2444a3cec84SArnaldo Carvalho de Melo 			return;
2454a3cec84SArnaldo Carvalho de Melo 	} else {
2464a3cec84SArnaldo Carvalho de Melo 	      /*
2474a3cec84SArnaldo Carvalho de Melo 	       * basename() may modify path buffer, so we must pass
2484a3cec84SArnaldo Carvalho de Melo                * a copy.
2494a3cec84SArnaldo Carvalho de Melo                */
2504a3cec84SArnaldo Carvalho de Melo 		lname = strdup(dso->long_name);
2514a3cec84SArnaldo Carvalho de Melo 		if (!lname)
2524a3cec84SArnaldo Carvalho de Melo 			return;
2534a3cec84SArnaldo Carvalho de Melo 
2544a3cec84SArnaldo Carvalho de Melo 		/*
2554a3cec84SArnaldo Carvalho de Melo 		 * basename() may return a pointer to internal
2564a3cec84SArnaldo Carvalho de Melo 		 * storage which is reused in subsequent calls
2574a3cec84SArnaldo Carvalho de Melo 		 * so copy the result.
2584a3cec84SArnaldo Carvalho de Melo 		 */
2594a3cec84SArnaldo Carvalho de Melo 		base = strdup(basename(lname));
2604a3cec84SArnaldo Carvalho de Melo 
2614a3cec84SArnaldo Carvalho de Melo 		free(lname);
2624a3cec84SArnaldo Carvalho de Melo 
2634a3cec84SArnaldo Carvalho de Melo 		if (!base)
2644a3cec84SArnaldo Carvalho de Melo 			return;
2654a3cec84SArnaldo Carvalho de Melo 	}
2664a3cec84SArnaldo Carvalho de Melo 	dso__set_short_name(dso, base, true);
2674a3cec84SArnaldo Carvalho de Melo }
2684a3cec84SArnaldo Carvalho de Melo 
__dsos__addnew_id(struct dsos * dsos,const char * name,struct dso_id * id)2690e3149f8SArnaldo Carvalho de Melo static struct dso *__dsos__addnew_id(struct dsos *dsos, const char *name, struct dso_id *id)
2704a3cec84SArnaldo Carvalho de Melo {
2710e3149f8SArnaldo Carvalho de Melo 	struct dso *dso = dso__new_id(name, id);
2724a3cec84SArnaldo Carvalho de Melo 
2734a3cec84SArnaldo Carvalho de Melo 	if (dso != NULL) {
2744a3cec84SArnaldo Carvalho de Melo 		__dsos__add(dsos, dso);
2754a3cec84SArnaldo Carvalho de Melo 		dso__set_basename(dso);
2764a3cec84SArnaldo Carvalho de Melo 		/* Put dso here because __dsos_add already got it */
2774a3cec84SArnaldo Carvalho de Melo 		dso__put(dso);
2784a3cec84SArnaldo Carvalho de Melo 	}
2794a3cec84SArnaldo Carvalho de Melo 	return dso;
2804a3cec84SArnaldo Carvalho de Melo }
2814a3cec84SArnaldo Carvalho de Melo 
__dsos__addnew(struct dsos * dsos,const char * name)2820e3149f8SArnaldo Carvalho de Melo struct dso *__dsos__addnew(struct dsos *dsos, const char *name)
2834a3cec84SArnaldo Carvalho de Melo {
2840e3149f8SArnaldo Carvalho de Melo 	return __dsos__addnew_id(dsos, name, NULL);
2854a3cec84SArnaldo Carvalho de Melo }
2864a3cec84SArnaldo Carvalho de Melo 
__dsos__findnew_id(struct dsos * dsos,const char * name,struct dso_id * id)2870e3149f8SArnaldo Carvalho de Melo static struct dso *__dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id *id)
2880e3149f8SArnaldo Carvalho de Melo {
2890e3149f8SArnaldo Carvalho de Melo 	struct dso *dso = __dsos__find_id(dsos, name, id, false);
2900d33b343SRavi Bangoria 
2910d33b343SRavi Bangoria 	if (dso && dso_id__empty(&dso->id) && !dso_id__empty(id))
2920d33b343SRavi Bangoria 		dso__inject_id(dso, id);
2930d33b343SRavi Bangoria 
2940e3149f8SArnaldo Carvalho de Melo 	return dso ? dso : __dsos__addnew_id(dsos, name, id);
2950e3149f8SArnaldo Carvalho de Melo }
2960e3149f8SArnaldo Carvalho de Melo 
dsos__findnew_id(struct dsos * dsos,const char * name,struct dso_id * id)2970e3149f8SArnaldo Carvalho de Melo struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id *id)
2984a3cec84SArnaldo Carvalho de Melo {
2994a3cec84SArnaldo Carvalho de Melo 	struct dso *dso;
3004a3cec84SArnaldo Carvalho de Melo 	down_write(&dsos->lock);
3010e3149f8SArnaldo Carvalho de Melo 	dso = dso__get(__dsos__findnew_id(dsos, name, id));
3024a3cec84SArnaldo Carvalho de Melo 	up_write(&dsos->lock);
3034a3cec84SArnaldo Carvalho de Melo 	return dso;
3044a3cec84SArnaldo Carvalho de Melo }
3054a3cec84SArnaldo Carvalho de Melo 
__dsos__fprintf_buildid(struct list_head * head,FILE * fp,bool (skip)(struct dso * dso,int parm),int parm)3064a3cec84SArnaldo Carvalho de Melo size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
3074a3cec84SArnaldo Carvalho de Melo 			       bool (skip)(struct dso *dso, int parm), int parm)
3084a3cec84SArnaldo Carvalho de Melo {
3094a3cec84SArnaldo Carvalho de Melo 	struct dso *pos;
3104a3cec84SArnaldo Carvalho de Melo 	size_t ret = 0;
3114a3cec84SArnaldo Carvalho de Melo 
3124a3cec84SArnaldo Carvalho de Melo 	list_for_each_entry(pos, head, node) {
313e9ad9438SJiri Olsa 		char sbuild_id[SBUILD_ID_SIZE];
314e9ad9438SJiri Olsa 
3154a3cec84SArnaldo Carvalho de Melo 		if (skip && skip(pos, parm))
3164a3cec84SArnaldo Carvalho de Melo 			continue;
317e9ad9438SJiri Olsa 		build_id__sprintf(&pos->bid, sbuild_id);
318e9ad9438SJiri Olsa 		ret += fprintf(fp, "%-40s %s\n", sbuild_id, pos->long_name);
3194a3cec84SArnaldo Carvalho de Melo 	}
3204a3cec84SArnaldo Carvalho de Melo 	return ret;
3214a3cec84SArnaldo Carvalho de Melo }
3224a3cec84SArnaldo Carvalho de Melo 
__dsos__fprintf(struct list_head * head,FILE * fp)3234a3cec84SArnaldo Carvalho de Melo size_t __dsos__fprintf(struct list_head *head, FILE *fp)
3244a3cec84SArnaldo Carvalho de Melo {
3254a3cec84SArnaldo Carvalho de Melo 	struct dso *pos;
3264a3cec84SArnaldo Carvalho de Melo 	size_t ret = 0;
3274a3cec84SArnaldo Carvalho de Melo 
3284a3cec84SArnaldo Carvalho de Melo 	list_for_each_entry(pos, head, node) {
3294a3cec84SArnaldo Carvalho de Melo 		ret += dso__fprintf(pos, fp);
3304a3cec84SArnaldo Carvalho de Melo 	}
3314a3cec84SArnaldo Carvalho de Melo 
3324a3cec84SArnaldo Carvalho de Melo 	return ret;
3334a3cec84SArnaldo Carvalho de Melo }
334