diff options
Diffstat (limited to 'tools/perf/util/session.c')
| -rw-r--r-- | tools/perf/util/session.c | 119 | 
1 files changed, 69 insertions, 50 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 061bb4d6a3f5..d0d7d25b23e3 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -227,9 +227,13 @@ struct perf_session *perf_session__new(struct perf_data *data,  			/* Open the directory data. */  			if (data->is_dir) {  				ret = perf_data__open_dir(data); -			if (ret) -				goto out_delete; +				if (ret) +					goto out_delete;  			} + +			if (!symbol_conf.kallsyms_name && +			    !symbol_conf.vmlinux_name) +				symbol_conf.kallsyms_name = perf_data__kallsyms_name(data);  		}  	} else  {  		session->machines.host.env = &perf_env; @@ -748,6 +752,7 @@ do { 						\  	bswap_field_32(sample_stack_user);  	bswap_field_32(aux_watermark);  	bswap_field_16(sample_max_stack); +	bswap_field_32(aux_sample_size);  	/*  	 * After read_format are bitfields. Check read_format because @@ -1491,8 +1496,13 @@ static int perf_session__deliver_event(struct perf_session *session,  	if (ret > 0)  		return 0; -	return machines__deliver_event(&session->machines, session->evlist, -				       event, &sample, tool, file_offset); +	ret = machines__deliver_event(&session->machines, session->evlist, +				      event, &sample, tool, file_offset); + +	if (dump_trace && sample.aux_sample.size) +		auxtrace__dump_auxtrace_sample(session, &sample); + +	return ret;  }  static s64 perf_session__process_user_event(struct perf_session *session, @@ -1649,6 +1659,34 @@ out_parse_sample:  	return 0;  } +int perf_session__peek_events(struct perf_session *session, u64 offset, +			      u64 size, peek_events_cb_t cb, void *data) +{ +	u64 max_offset = offset + size; +	char buf[PERF_SAMPLE_MAX_SIZE]; +	union perf_event *event; +	int err; + +	do { +		err = perf_session__peek_event(session, offset, buf, +					       PERF_SAMPLE_MAX_SIZE, &event, +					       NULL); +		if (err) +			return err; + +		err = cb(session, event, offset, data); +		if (err) +			return err; + +		offset += event->header.size; +		if (event->header.type == PERF_RECORD_AUXTRACE) +			offset += event->auxtrace.size; + +	} while (offset < max_offset); + +	return err; +} +  static s64 perf_session__process_event(struct perf_session *session,  				       union perf_event *event, u64 file_offset)  { @@ -1954,8 +1992,8 @@ out_err:  }  static union perf_event * -fetch_mmaped_event(struct perf_session *session, -		   u64 head, size_t mmap_size, char *buf) +prefetch_event(char *buf, u64 head, size_t mmap_size, +	       bool needs_swap, union perf_event *error)  {  	union perf_event *event; @@ -1967,20 +2005,32 @@ fetch_mmaped_event(struct perf_session *session,  		return NULL;  	event = (union perf_event *)(buf + head); +	if (needs_swap) +		perf_event_header__bswap(&event->header); -	if (session->header.needs_swap) +	if (head + event->header.size <= mmap_size) +		return event; + +	/* We're not fetching the event so swap back again */ +	if (needs_swap)  		perf_event_header__bswap(&event->header); -	if (head + event->header.size > mmap_size) { -		/* We're not fetching the event so swap back again */ -		if (session->header.needs_swap) -			perf_event_header__bswap(&event->header); -		pr_debug("%s: head=%#" PRIx64 " event->header_size=%#x, mmap_size=%#zx: fuzzed perf.data?\n", -			 __func__, head, event->header.size, mmap_size); -		return ERR_PTR(-EINVAL); -	} +	pr_debug("%s: head=%#" PRIx64 " event->header_size=%#x, mmap_size=%#zx:" +		 " fuzzed or compressed perf.data?\n",__func__, head, event->header.size, mmap_size); + +	return error; +} + +static union perf_event * +fetch_mmaped_event(u64 head, size_t mmap_size, char *buf, bool needs_swap) +{ +	return prefetch_event(buf, head, mmap_size, needs_swap, ERR_PTR(-EINVAL)); +} -	return event; +static union perf_event * +fetch_decomp_event(u64 head, size_t mmap_size, char *buf, bool needs_swap) +{ +	return prefetch_event(buf, head, mmap_size, needs_swap, NULL);  }  static int __perf_session__process_decomp_events(struct perf_session *session) @@ -1993,10 +2043,8 @@ static int __perf_session__process_decomp_events(struct perf_session *session)  		return 0;  	while (decomp->head < decomp->size && !session_done()) { -		union perf_event *event = fetch_mmaped_event(session, decomp->head, decomp->size, decomp->data); - -		if (IS_ERR(event)) -			return PTR_ERR(event); +		union perf_event *event = fetch_decomp_event(decomp->head, decomp->size, decomp->data, +							     session->header.needs_swap);  		if (!event)  			break; @@ -2096,7 +2144,7 @@ remap:  	}  more: -	event = fetch_mmaped_event(session, head, mmap_size, buf); +	event = fetch_mmaped_event(head, mmap_size, buf, session->header.needs_swap);  	if (IS_ERR(event))  		return PTR_ERR(event); @@ -2355,35 +2403,6 @@ void perf_session__fprintf_info(struct perf_session *session, FILE *fp,  	fprintf(fp, "# ========\n#\n");  } - -int __perf_session__set_tracepoints_handlers(struct perf_session *session, -					     const struct evsel_str_handler *assocs, -					     size_t nr_assocs) -{ -	struct evsel *evsel; -	size_t i; -	int err; - -	for (i = 0; i < nr_assocs; i++) { -		/* -		 * Adding a handler for an event not in the session, -		 * just ignore it. -		 */ -		evsel = perf_evlist__find_tracepoint_by_name(session->evlist, assocs[i].name); -		if (evsel == NULL) -			continue; - -		err = -EEXIST; -		if (evsel->handler != NULL) -			goto out; -		evsel->handler = assocs[i].handler; -	} - -	err = 0; -out: -	return err; -} -  int perf_event__process_id_index(struct perf_session *session,  				 union perf_event *event)  {  | 
