Пример #1
0
int event__synthesize_kernel_mmap(event__handler_t process,
                                  struct perf_session *session,
                                  const char *symbol_name)
{
    size_t size;
    event_t ev = {
        .header = {
            .type = PERF_RECORD_MMAP,
            .misc = 1, /* kernel uses 0 for user space maps, see kernel/perf_event.c __perf_event_mmap */
        },
    };
    /*
     * We should get this from /sys/kernel/sections/.text, but till that is
     * available use this, and after it is use this as a fallback for older
     * kernels.
     */
    struct process_symbol_args args = { .name = symbol_name, };

    if (kallsyms__parse("/proc/kallsyms", &args, find_symbol_cb) <= 0)
        return -ENOENT;

    size = snprintf(ev.mmap.filename, sizeof(ev.mmap.filename),
                    "[kernel.kallsyms.%s]", symbol_name) + 1;
    size = ALIGN(size, sizeof(u64));
    ev.mmap.header.size = (sizeof(ev.mmap) - (sizeof(ev.mmap.filename) - size));
    ev.mmap.pgoff = args.start;
    ev.mmap.start = session->vmlinux_maps[MAP__FUNCTION]->start;
    ev.mmap.len   = session->vmlinux_maps[MAP__FUNCTION]->end - ev.mmap.start ;

    return process(&ev, session);
}
Пример #2
0
int event__synthesize_kernel_mmap(event__handler_t process,
				  struct perf_session *session,
				  struct machine *machine,
				  const char *symbol_name)
{
	size_t size;
	const char *filename, *mmap_name;
	char path[PATH_MAX];
	char name_buff[PATH_MAX];
	struct map *map;

	event_t ev = {
		.header = {
			.type = PERF_RECORD_MMAP,
		},
	};
	/*
	 * We should get this from /sys/kernel/sections/.text, but till that is
	 * available use this, and after it is use this as a fallback for older
	 * kernels.
	 */
	struct process_symbol_args args = { .name = symbol_name, };

	mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff));
	if (machine__is_host(machine)) {
		/*
		 * kernel uses PERF_RECORD_MISC_USER for user space maps,
		 * see kernel/perf_event.c __perf_event_mmap
		 */
		ev.header.misc = PERF_RECORD_MISC_KERNEL;
		filename = "/proc/kallsyms";
	} else {
		ev.header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
		if (machine__is_default_guest(machine))
			filename = (char *) symbol_conf.default_guest_kallsyms;
		else {
			sprintf(path, "%s/proc/kallsyms", machine->root_dir);
			filename = path;
		}
	}

	if (kallsyms__parse(filename, &args, find_symbol_cb) <= 0)
		return -ENOENT;

	map = machine->vmlinux_maps[MAP__FUNCTION];
	size = snprintf(ev.mmap.filename, sizeof(ev.mmap.filename),
			"%s%s", mmap_name, symbol_name) + 1;
	size = ALIGN(size, sizeof(u64));
	ev.mmap.header.size = (sizeof(ev.mmap) -
			(sizeof(ev.mmap.filename) - size));
	ev.mmap.pgoff = args.start;
	ev.mmap.start = map->start;
	ev.mmap.len   = map->end - ev.mmap.start;
	ev.mmap.pid   = machine->pid;

	return process(&ev, session);
}
Пример #3
0
u64 kallsyms__get_function_start(const char *kallsyms_filename,
				 const char *symbol_name)
{
	struct process_symbol_args args = { .name = symbol_name, };

	if (kallsyms__parse(kallsyms_filename, &args, find_symbol_cb) <= 0)
		return 0;

	return args.start;
}
Пример #4
0
int perf_event__synthesize_kernel_mmap(perf_event__handler_t process,
                                       struct perf_session *session,
                                       struct machine *machine,
                                       const char *symbol_name)
{
    size_t size;
    const char *filename, *mmap_name;
    char path[PATH_MAX];
    char name_buff[PATH_MAX];
    struct map *map;
    int err;
    /*
     * We should get this from /sys/kernel/sections/.text, but till that is
     * available use this, and after it is use this as a fallback for older
     * kernels.
     */
    struct process_symbol_args args = { .name = symbol_name, };
    union perf_event *event = zalloc((sizeof(event->mmap) +
                                          session->id_hdr_size));
    if (event == NULL) {
        pr_debug("Not enough memory synthesizing mmap event "
                 "for kernel modules\n");
        return -1;
    }

    mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff));
    if (machine__is_host(machine)) {
        /*
         * kernel uses PERF_RECORD_MISC_USER for user space maps,
         * see kernel/perf_event.c __perf_event_mmap
         */
        event->header.misc = PERF_RECORD_MISC_KERNEL;
        filename = "/proc/kallsyms";
    } else {
        event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
        if (machine__is_default_guest(machine))
            filename = (char *) symbol_conf.default_guest_kallsyms;
        else {
            sprintf(path, "%s/proc/kallsyms", machine->root_dir);
            filename = path;
        }
    }

    if (kallsyms__parse(filename, &args, find_symbol_cb) <= 0)
        return -ENOENT;

    map = machine->vmlinux_maps[MAP__FUNCTION];
    size = snprintf(event->mmap.filename, sizeof(event->mmap.filename),
                    "%s%s", mmap_name, symbol_name) + 1;
    size = ALIGN(size, sizeof(u64));
    event->mmap.header.type = PERF_RECORD_MMAP;
    event->mmap.header.size = (sizeof(event->mmap) -
                               (sizeof(event->mmap.filename) - size) + session->id_hdr_size);
    event->mmap.pgoff = args.start;
    event->mmap.start = map->start;
    event->mmap.len   = map->end - event->mmap.start;
    event->mmap.pid   = machine->pid;

    err = process(event, &synth_sample, session);
    free(event);

    return err;
}