Home | History | Annotate | Download | only in util
      1 /*
      2  * build-id.c
      3  *
      4  * build-id support
      5  *
      6  * Copyright (C) 2009, 2010 Red Hat Inc.
      7  * Copyright (C) 2009, 2010 Arnaldo Carvalho de Melo <acme (at) redhat.com>
      8  */
      9 #include "util.h"
     10 #include <stdio.h>
     11 #include "build-id.h"
     12 #include "event.h"
     13 #include "symbol.h"
     14 /* ANDROID_CHANGE_BEGIN */
     15 #ifdef __APPLE__
     16 #include "include/linux/kernel.h"
     17 #endif
     18 /* ANDROID_CHANGE_END */
     19 #include "debug.h"
     20 
     21 static int build_id__mark_dso_hit(union perf_event *event,
     22 				  struct perf_sample *sample __used,
     23 				  struct perf_evsel *evsel __used,
     24 				  struct perf_session *session)
     25 {
     26 	struct addr_location al;
     27 	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
     28 	struct thread *thread = perf_session__findnew(session, event->ip.pid);
     29 
     30 	if (thread == NULL) {
     31 		pr_err("problem processing %d event, skipping it.\n",
     32 			event->header.type);
     33 		return -1;
     34 	}
     35 
     36 	thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
     37 			      event->ip.pid, event->ip.ip, &al);
     38 
     39 	if (al.map != NULL)
     40 		al.map->dso->hit = 1;
     41 
     42 	return 0;
     43 }
     44 
     45 static int perf_event__exit_del_thread(union perf_event *event,
     46 				       struct perf_sample *sample __used,
     47 				       struct perf_session *session)
     48 {
     49 	struct thread *thread = perf_session__findnew(session, event->fork.tid);
     50 
     51 	dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid,
     52 		    event->fork.ppid, event->fork.ptid);
     53 
     54 	if (thread) {
     55 		rb_erase(&thread->rb_node, &session->threads);
     56 		session->last_match = NULL;
     57 		thread__delete(thread);
     58 	}
     59 
     60 	return 0;
     61 }
     62 
     63 struct perf_event_ops build_id__mark_dso_hit_ops = {
     64 	.sample	= build_id__mark_dso_hit,
     65 	.mmap	= perf_event__process_mmap,
     66 	.fork	= perf_event__process_task,
     67 	.exit	= perf_event__exit_del_thread,
     68 };
     69 
     70 char *dso__build_id_filename(struct dso *self, char *bf, size_t size)
     71 {
     72 	char build_id_hex[BUILD_ID_SIZE * 2 + 1];
     73 
     74 	if (!self->has_build_id)
     75 		return NULL;
     76 
     77 	build_id__sprintf(self->build_id, sizeof(self->build_id), build_id_hex);
     78 	if (bf == NULL) {
     79 		if (asprintf(&bf, "%s/.build-id/%.2s/%s", buildid_dir,
     80 			     build_id_hex, build_id_hex + 2) < 0)
     81 			return NULL;
     82 	} else
     83 		snprintf(bf, size, "%s/.build-id/%.2s/%s", buildid_dir,
     84 			 build_id_hex, build_id_hex + 2);
     85 	return bf;
     86 }
     87