Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  1#include "symbol.h"
  2#include "dso.h"
  3#include "machine.h"
  4#include "util.h"
  5#include "debug.h"
  6
  7char dso__symtab_origin(const struct dso *dso)
  8{
  9	static const char origin[] = {
 10		[DSO_BINARY_TYPE__KALLSYMS]			= 'k',
 11		[DSO_BINARY_TYPE__VMLINUX]			= 'v',
 12		[DSO_BINARY_TYPE__JAVA_JIT]			= 'j',
 13		[DSO_BINARY_TYPE__DEBUGLINK]			= 'l',
 14		[DSO_BINARY_TYPE__BUILD_ID_CACHE]		= 'B',
 15		[DSO_BINARY_TYPE__FEDORA_DEBUGINFO]		= 'f',
 16		[DSO_BINARY_TYPE__UBUNTU_DEBUGINFO]		= 'u',
 17		[DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO]	= 'o',
 18		[DSO_BINARY_TYPE__BUILDID_DEBUGINFO]		= 'b',
 19		[DSO_BINARY_TYPE__SYSTEM_PATH_DSO]		= 'd',
 20		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE]		= 'K',
 21		[DSO_BINARY_TYPE__GUEST_KALLSYMS]		= 'g',
 22		[DSO_BINARY_TYPE__GUEST_KMODULE]		= 'G',
 23		[DSO_BINARY_TYPE__GUEST_VMLINUX]		= 'V',
 24	};
 25
 26	if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
 27		return '!';
 28	return origin[dso->symtab_type];
 29}
 30
 31int dso__read_binary_type_filename(const struct dso *dso,
 32				   enum dso_binary_type type,
 33				   char *root_dir, char *filename, size_t size)
 34{
 35	char build_id_hex[BUILD_ID_SIZE * 2 + 1];
 36	int ret = 0;
 37
 38	switch (type) {
 39	case DSO_BINARY_TYPE__DEBUGLINK: {
 40		char *debuglink;
 41
 42		strncpy(filename, dso->long_name, size);
 43		debuglink = filename + dso->long_name_len;
 44		while (debuglink != filename && *debuglink != '/')
 45			debuglink--;
 46		if (*debuglink == '/')
 47			debuglink++;
 48		ret = filename__read_debuglink(dso->long_name, debuglink,
 49					       size - (debuglink - filename));
 50		}
 51		break;
 52	case DSO_BINARY_TYPE__BUILD_ID_CACHE:
 53		/* skip the locally configured cache if a symfs is given */
 54		if (symbol_conf.symfs[0] ||
 55		    (dso__build_id_filename(dso, filename, size) == NULL))
 56			ret = -1;
 57		break;
 58
 59	case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
 60		snprintf(filename, size, "%s/usr/lib/debug%s.debug",
 61			 symbol_conf.symfs, dso->long_name);
 62		break;
 63
 64	case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
 65		snprintf(filename, size, "%s/usr/lib/debug%s",
 66			 symbol_conf.symfs, dso->long_name);
 67		break;
 68
 69	case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
 70	{
 71		const char *last_slash;
 72		size_t len;
 73		size_t dir_size;
 74
 75		last_slash = dso->long_name + dso->long_name_len;
 76		while (last_slash != dso->long_name && *last_slash != '/')
 77			last_slash--;
 78
 79		len = scnprintf(filename, size, "%s", symbol_conf.symfs);
 80		dir_size = last_slash - dso->long_name + 2;
 81		if (dir_size > (size - len)) {
 82			ret = -1;
 83			break;
 84		}
 85		len += scnprintf(filename + len, dir_size, "%s",  dso->long_name);
 86		len += scnprintf(filename + len , size - len, ".debug%s",
 87								last_slash);
 88		break;
 89	}
 90
 91	case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
 92		if (!dso->has_build_id) {
 93			ret = -1;
 94			break;
 95		}
 96
 97		build_id__sprintf(dso->build_id,
 98				  sizeof(dso->build_id),
 99				  build_id_hex);
100		snprintf(filename, size,
101			 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
102			 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
103		break;
104
105	case DSO_BINARY_TYPE__VMLINUX:
106	case DSO_BINARY_TYPE__GUEST_VMLINUX:
107	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
108		snprintf(filename, size, "%s%s",
109			 symbol_conf.symfs, dso->long_name);
110		break;
111
112	case DSO_BINARY_TYPE__GUEST_KMODULE:
113		snprintf(filename, size, "%s%s%s", symbol_conf.symfs,
114			 root_dir, dso->long_name);
115		break;
116
117	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
118		snprintf(filename, size, "%s%s", symbol_conf.symfs,
119			 dso->long_name);
120		break;
121
122	case DSO_BINARY_TYPE__KCORE:
123	case DSO_BINARY_TYPE__GUEST_KCORE:
124		snprintf(filename, size, "%s", dso->long_name);
125		break;
126
127	default:
128	case DSO_BINARY_TYPE__KALLSYMS:
129	case DSO_BINARY_TYPE__GUEST_KALLSYMS:
130	case DSO_BINARY_TYPE__JAVA_JIT:
131	case DSO_BINARY_TYPE__NOT_FOUND:
132		ret = -1;
133		break;
134	}
135
136	return ret;
137}
138
139static int open_dso(struct dso *dso, struct machine *machine)
140{
141	int fd;
142	char *root_dir = (char *)"";
143	char *name = malloc(PATH_MAX);
144
145	if (!name)
146		return -ENOMEM;
147
148	if (machine)
149		root_dir = machine->root_dir;
150
151	if (dso__read_binary_type_filename(dso, dso->binary_type,
152					    root_dir, name, PATH_MAX)) {
153		free(name);
154		return -EINVAL;
155	}
156
157	fd = open(name, O_RDONLY);
158	free(name);
159	return fd;
160}
161
162int dso__data_fd(struct dso *dso, struct machine *machine)
163{
164	enum dso_binary_type binary_type_data[] = {
165		DSO_BINARY_TYPE__BUILD_ID_CACHE,
166		DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
167		DSO_BINARY_TYPE__NOT_FOUND,
168	};
169	int i = 0;
170
171	if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND)
172		return open_dso(dso, machine);
173
174	do {
175		int fd;
176
177		dso->binary_type = binary_type_data[i++];
178
179		fd = open_dso(dso, machine);
180		if (fd >= 0)
181			return fd;
182
183	} while (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND);
184
185	return -EINVAL;
186}
187
188static void
189dso_cache__free(struct rb_root *root)
190{
191	struct rb_node *next = rb_first(root);
192
193	while (next) {
194		struct dso_cache *cache;
195
196		cache = rb_entry(next, struct dso_cache, rb_node);
197		next = rb_next(&cache->rb_node);
198		rb_erase(&cache->rb_node, root);
199		free(cache);
200	}
201}
202
203static struct dso_cache *dso_cache__find(const struct rb_root *root, u64 offset)
204{
205	struct rb_node * const *p = &root->rb_node;
206	const struct rb_node *parent = NULL;
207	struct dso_cache *cache;
208
209	while (*p != NULL) {
210		u64 end;
211
212		parent = *p;
213		cache = rb_entry(parent, struct dso_cache, rb_node);
214		end = cache->offset + DSO__DATA_CACHE_SIZE;
215
216		if (offset < cache->offset)
217			p = &(*p)->rb_left;
218		else if (offset >= end)
219			p = &(*p)->rb_right;
220		else
221			return cache;
222	}
223	return NULL;
224}
225
226static void
227dso_cache__insert(struct rb_root *root, struct dso_cache *new)
228{
229	struct rb_node **p = &root->rb_node;
230	struct rb_node *parent = NULL;
231	struct dso_cache *cache;
232	u64 offset = new->offset;
233
234	while (*p != NULL) {
235		u64 end;
236
237		parent = *p;
238		cache = rb_entry(parent, struct dso_cache, rb_node);
239		end = cache->offset + DSO__DATA_CACHE_SIZE;
240
241		if (offset < cache->offset)
242			p = &(*p)->rb_left;
243		else if (offset >= end)
244			p = &(*p)->rb_right;
245	}
246
247	rb_link_node(&new->rb_node, parent, p);
248	rb_insert_color(&new->rb_node, root);
249}
250
251static ssize_t
252dso_cache__memcpy(struct dso_cache *cache, u64 offset,
253		  u8 *data, u64 size)
254{
255	u64 cache_offset = offset - cache->offset;
256	u64 cache_size   = min(cache->size - cache_offset, size);
257
258	memcpy(data, cache->data + cache_offset, cache_size);
259	return cache_size;
260}
261
262static ssize_t
263dso_cache__read(struct dso *dso, struct machine *machine,
264		 u64 offset, u8 *data, ssize_t size)
265{
266	struct dso_cache *cache;
267	ssize_t ret;
268	int fd;
269
270	fd = dso__data_fd(dso, machine);
271	if (fd < 0)
272		return -1;
273
274	do {
275		u64 cache_offset;
276
277		ret = -ENOMEM;
278
279		cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
280		if (!cache)
281			break;
282
283		cache_offset = offset & DSO__DATA_CACHE_MASK;
284		ret = -EINVAL;
285
286		if (-1 == lseek(fd, cache_offset, SEEK_SET))
287			break;
288
289		ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE);
290		if (ret <= 0)
291			break;
292
293		cache->offset = cache_offset;
294		cache->size   = ret;
295		dso_cache__insert(&dso->cache, cache);
296
297		ret = dso_cache__memcpy(cache, offset, data, size);
298
299	} while (0);
300
301	if (ret <= 0)
302		free(cache);
303
304	close(fd);
305	return ret;
306}
307
308static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
309			      u64 offset, u8 *data, ssize_t size)
310{
311	struct dso_cache *cache;
312
313	cache = dso_cache__find(&dso->cache, offset);
314	if (cache)
315		return dso_cache__memcpy(cache, offset, data, size);
316	else
317		return dso_cache__read(dso, machine, offset, data, size);
318}
319
320ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
321			      u64 offset, u8 *data, ssize_t size)
322{
323	ssize_t r = 0;
324	u8 *p = data;
325
326	do {
327		ssize_t ret;
328
329		ret = dso_cache_read(dso, machine, offset, p, size);
330		if (ret < 0)
331			return ret;
332
333		/* Reached EOF, return what we have. */
334		if (!ret)
335			break;
336
337		BUG_ON(ret > size);
338
339		r      += ret;
340		p      += ret;
341		offset += ret;
342		size   -= ret;
343
344	} while (size);
345
346	return r;
347}
348
349ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
350			    struct machine *machine, u64 addr,
351			    u8 *data, ssize_t size)
352{
353	u64 offset = map->map_ip(map, addr);
354	return dso__data_read_offset(dso, machine, offset, data, size);
355}
356
357struct map *dso__new_map(const char *name)
358{
359	struct map *map = NULL;
360	struct dso *dso = dso__new(name);
361
362	if (dso)
363		map = map__new2(0, dso, MAP__FUNCTION);
364
365	return map;
366}
367
368struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
369		    const char *short_name, int dso_type)
370{
371	/*
372	 * The kernel dso could be created by build_id processing.
373	 */
374	struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name);
375
376	/*
377	 * We need to run this in all cases, since during the build_id
378	 * processing we had no idea this was the kernel dso.
379	 */
380	if (dso != NULL) {
381		dso__set_short_name(dso, short_name, false);
382		dso->kernel = dso_type;
383	}
384
385	return dso;
386}
387
388void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
389{
390	if (name == NULL)
391		return;
392
393	if (dso->long_name_allocated)
394		free((char *)dso->long_name);
395
396	dso->long_name		 = name;
397	dso->long_name_len	 = strlen(name);
398	dso->long_name_allocated = name_allocated;
399}
400
401void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
402{
403	if (name == NULL)
404		return;
405
406	if (dso->short_name_allocated)
407		free((char *)dso->short_name);
408
409	dso->short_name		  = name;
410	dso->short_name_len	  = strlen(name);
411	dso->short_name_allocated = name_allocated;
412}
413
414static void dso__set_basename(struct dso *dso)
415{
416       /*
417        * basename() may modify path buffer, so we must pass
418        * a copy.
419        */
420       char *base, *lname = strdup(dso->long_name);
421
422       if (!lname)
423               return;
424
425       /*
426        * basename() may return a pointer to internal
427        * storage which is reused in subsequent calls
428        * so copy the result.
429        */
430       base = strdup(basename(lname));
431
432       free(lname);
433
434       if (!base)
435               return;
436
437       dso__set_short_name(dso, base, true);
438}
439
440int dso__name_len(const struct dso *dso)
441{
442	if (!dso)
443		return strlen("[unknown]");
444	if (verbose)
445		return dso->long_name_len;
446
447	return dso->short_name_len;
448}
449
450bool dso__loaded(const struct dso *dso, enum map_type type)
451{
452	return dso->loaded & (1 << type);
453}
454
455bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
456{
457	return dso->sorted_by_name & (1 << type);
458}
459
460void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
461{
462	dso->sorted_by_name |= (1 << type);
463}
464
465struct dso *dso__new(const char *name)
466{
467	struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
468
469	if (dso != NULL) {
470		int i;
471		strcpy(dso->name, name);
472		dso__set_long_name(dso, dso->name, false);
473		dso__set_short_name(dso, dso->name, false);
474		for (i = 0; i < MAP__NR_TYPES; ++i)
475			dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
476		dso->cache = RB_ROOT;
477		dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
478		dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND;
479		dso->loaded = 0;
480		dso->rel = 0;
481		dso->sorted_by_name = 0;
482		dso->has_build_id = 0;
483		dso->has_srcline = 1;
484		dso->a2l_fails = 1;
485		dso->kernel = DSO_TYPE_USER;
486		dso->needs_swap = DSO_SWAP__UNSET;
487		INIT_LIST_HEAD(&dso->node);
488	}
489
490	return dso;
491}
492
493void dso__delete(struct dso *dso)
494{
495	int i;
496	for (i = 0; i < MAP__NR_TYPES; ++i)
497		symbols__delete(&dso->symbols[i]);
498
499	if (dso->short_name_allocated) {
500		zfree((char **)&dso->short_name);
501		dso->short_name_allocated = false;
502	}
503
504	if (dso->long_name_allocated) {
505		zfree((char **)&dso->long_name);
506		dso->long_name_allocated = false;
507	}
508
509	dso_cache__free(&dso->cache);
510	dso__free_a2l(dso);
511	zfree(&dso->symsrc_filename);
512	free(dso);
513}
514
515void dso__set_build_id(struct dso *dso, void *build_id)
516{
517	memcpy(dso->build_id, build_id, sizeof(dso->build_id));
518	dso->has_build_id = 1;
519}
520
521bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
522{
523	return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
524}
525
526void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
527{
528	char path[PATH_MAX];
529
530	if (machine__is_default_guest(machine))
531		return;
532	sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
533	if (sysfs__read_build_id(path, dso->build_id,
534				 sizeof(dso->build_id)) == 0)
535		dso->has_build_id = true;
536}
537
538int dso__kernel_module_get_build_id(struct dso *dso,
539				    const char *root_dir)
540{
541	char filename[PATH_MAX];
542	/*
543	 * kernel module short names are of the form "[module]" and
544	 * we need just "module" here.
545	 */
546	const char *name = dso->short_name + 1;
547
548	snprintf(filename, sizeof(filename),
549		 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
550		 root_dir, (int)strlen(name) - 1, name);
551
552	if (sysfs__read_build_id(filename, dso->build_id,
553				 sizeof(dso->build_id)) == 0)
554		dso->has_build_id = true;
555
556	return 0;
557}
558
559bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
560{
561	bool have_build_id = false;
562	struct dso *pos;
563
564	list_for_each_entry(pos, head, node) {
565		if (with_hits && !pos->hit)
566			continue;
567		if (pos->has_build_id) {
568			have_build_id = true;
569			continue;
570		}
571		if (filename__read_build_id(pos->long_name, pos->build_id,
572					    sizeof(pos->build_id)) > 0) {
573			have_build_id	  = true;
574			pos->has_build_id = true;
575		}
576	}
577
578	return have_build_id;
579}
580
581void dsos__add(struct list_head *head, struct dso *dso)
582{
583	list_add_tail(&dso->node, head);
584}
585
586struct dso *dsos__find(const struct list_head *head, const char *name, bool cmp_short)
587{
588	struct dso *pos;
589
590	if (cmp_short) {
591		list_for_each_entry(pos, head, node)
592			if (strcmp(pos->short_name, name) == 0)
593				return pos;
594		return NULL;
595	}
596	list_for_each_entry(pos, head, node)
597		if (strcmp(pos->long_name, name) == 0)
598			return pos;
599	return NULL;
600}
601
602struct dso *__dsos__findnew(struct list_head *head, const char *name)
603{
604	struct dso *dso = dsos__find(head, name, false);
605
606	if (!dso) {
607		dso = dso__new(name);
608		if (dso != NULL) {
609			dsos__add(head, dso);
610			dso__set_basename(dso);
611		}
612	}
613
614	return dso;
615}
616
617size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
618			       bool (skip)(struct dso *dso, int parm), int parm)
619{
620	struct dso *pos;
621	size_t ret = 0;
622
623	list_for_each_entry(pos, head, node) {
624		if (skip && skip(pos, parm))
625			continue;
626		ret += dso__fprintf_buildid(pos, fp);
627		ret += fprintf(fp, " %s\n", pos->long_name);
628	}
629	return ret;
630}
631
632size_t __dsos__fprintf(struct list_head *head, FILE *fp)
633{
634	struct dso *pos;
635	size_t ret = 0;
636
637	list_for_each_entry(pos, head, node) {
638		int i;
639		for (i = 0; i < MAP__NR_TYPES; ++i)
640			ret += dso__fprintf(pos, i, fp);
641	}
642
643	return ret;
644}
645
646size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
647{
648	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
649
650	build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
651	return fprintf(fp, "%s", sbuild_id);
652}
653
654size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
655{
656	struct rb_node *nd;
657	size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
658
659	if (dso->short_name != dso->long_name)
660		ret += fprintf(fp, "%s, ", dso->long_name);
661	ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
662		       dso__loaded(dso, type) ? "" : "NOT ");
663	ret += dso__fprintf_buildid(dso, fp);
664	ret += fprintf(fp, ")\n");
665	for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
666		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
667		ret += symbol__fprintf(pos, fp);
668	}
669
670	return ret;
671}