예제 #1
0
파일: map.c 프로젝트: Master-Traders/linux
struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
		     u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino,
		     u64 ino_gen, char *filename,
		     enum map_type type)
{
	struct map *map = malloc(sizeof(*map));

	if (map != NULL) {
		char newfilename[PATH_MAX];
		struct dso *dso;
		int anon, no_dso, vdso;

		anon = is_anon_memory(filename);
		vdso = is_vdso_map(filename);
		no_dso = is_no_dso_memory(filename);

		map->maj = d_maj;
		map->min = d_min;
		map->ino = ino;
		map->ino_generation = ino_gen;

		if ((anon || no_dso) && type == MAP__FUNCTION) {
			snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
			filename = newfilename;
		}

		if (vdso) {
			pgoff = 0;
			dso = vdso__dso_findnew(dsos__list);
		} else
			dso = __dsos__findnew(dsos__list, filename);

		if (dso == NULL)
			goto out_delete;

		map__init(map, type, start, start + len, pgoff, dso);

		if (anon || no_dso) {
			map->map_ip = map->unmap_ip = identity__map_ip;

			/*
			 * Set memory without DSO as loaded. All map__find_*
			 * functions still return NULL, and we avoid the
			 * unnecessary map__load warning.
			 */
			if (type != MAP__FUNCTION)
				dso__set_loaded(dso, map->type);
		}
	}
	return map;
out_delete:
	free(map);
	return NULL;
}
예제 #2
0
struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
		     u64 pgoff, u32 pid, char *filename,
		     enum map_type type)
{
	struct map *self = malloc(sizeof(*self));

	if (self != NULL) {
		char newfilename[PATH_MAX];
		struct dso *dso;
		int anon, no_dso;

		anon = is_anon_memory(filename);
		no_dso = is_no_dso_memory(filename);

		if (anon) {
			snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
			filename = newfilename;
		}

		dso = __dsos__findnew(dsos__list, filename);
		if (dso == NULL)
			goto out_delete;

		map__init(self, type, start, start + len, pgoff, dso);

		if (anon || no_dso) {
			self->map_ip = self->unmap_ip = identity__map_ip;

			/*
			 * Set memory without DSO as loaded. All map__find_*
			 * functions still return NULL, and we avoid the
			 * unnecessary map__load warning.
			 */
			if (no_dso)
				dso__set_loaded(dso, self->type);
		}
	}
	return self;
out_delete:
	free(self);
	return NULL;
}
예제 #3
0
struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
		     u64 pgoff, u32 pid, char *filename,
		     enum map_type type)
{
	struct map *self = malloc(sizeof(*self));

	if (self != NULL) {
		char newfilename[PATH_MAX];
		struct dso *dso;
		int anon;

		anon = is_anon_memory(filename);

		if (anon) {
			snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
			filename = newfilename;
		}

		dso = __dsos__findnew(dsos__list, filename);
		if (dso == NULL)
			goto out_delete;

		map__init(self, type, start, start + len, pgoff, dso);

		if (anon) {
set_identity:
			self->map_ip = self->unmap_ip = identity__map_ip;
		} else if (strcmp(filename, "[vdso]") == 0) {
			dso__set_loaded(dso, self->type);
			goto set_identity;
		}
	}
	return self;
out_delete:
	free(self);
	return NULL;
}
예제 #4
0
int event__process_mmap(event_t *self, struct perf_session *session)
{
    struct thread *thread;
    struct map *map;

    dump_printf(" %d/%d: [%#Lx(%#Lx) @ %#Lx]: %s\n",
                self->mmap.pid, self->mmap.tid, self->mmap.start,
                self->mmap.len, self->mmap.pgoff, self->mmap.filename);

    if (self->mmap.pid == 0) {
        static const char kmmap_prefix[] = "[kernel.kallsyms.";

        if (self->mmap.filename[0] == '/') {
            char short_module_name[1024];
            char *name = strrchr(self->mmap.filename, '/'), *dot;

            if (name == NULL)
                goto out_problem;

            ++name; /* skip / */
            dot = strrchr(name, '.');
            if (dot == NULL)
                goto out_problem;

            snprintf(short_module_name, sizeof(short_module_name),
                     "[%.*s]", (int)(dot - name), name);
            strxfrchar(short_module_name, '-', '_');

            map = perf_session__new_module_map(session,
                                               self->mmap.start,
                                               self->mmap.filename);
            if (map == NULL)
                goto out_problem;

            name = strdup(short_module_name);
            if (name == NULL)
                goto out_problem;

            map->dso->short_name = name;
            map->end = map->start + self->mmap.len;
        } else if (memcmp(self->mmap.filename, kmmap_prefix,
                          sizeof(kmmap_prefix) - 1) == 0) {
            const char *symbol_name = (self->mmap.filename +
                                       sizeof(kmmap_prefix) - 1);
            /*
             * Should be there already, from the build-id table in
             * the header.
             */
            struct dso *kernel = __dsos__findnew(&dsos__kernel,
                                                 "[kernel.kallsyms]");
            if (kernel == NULL)
                goto out_problem;

            kernel->kernel = 1;
            if (__perf_session__create_kernel_maps(session, kernel) < 0)
                goto out_problem;

            session->vmlinux_maps[MAP__FUNCTION]->start = self->mmap.start;
            session->vmlinux_maps[MAP__FUNCTION]->end   = self->mmap.start + self->mmap.len;
            /*
             * Be a bit paranoid here, some perf.data file came with
             * a zero sized synthesized MMAP event for the kernel.
             */
            if (session->vmlinux_maps[MAP__FUNCTION]->end == 0)
                session->vmlinux_maps[MAP__FUNCTION]->end = ~0UL;

            perf_session__set_kallsyms_ref_reloc_sym(session, symbol_name,
                    self->mmap.pgoff);
        }
        return 0;
    }

    thread = perf_session__findnew(session, self->mmap.pid);
    map = map__new(&self->mmap, MAP__FUNCTION,
                   session->cwd, session->cwdlen);

    if (thread == NULL || map == NULL)
        goto out_problem;

    thread__insert_map(thread, map);
    return 0;

out_problem:
    dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
    return 0;
}
예제 #5
0
static int event__process_kernel_mmap(event_t *self,
			struct perf_session *session)
{
	struct map *map;
	char kmmap_prefix[PATH_MAX];
	struct machine *machine;
	enum dso_kernel_type kernel_type;
	bool is_kernel_mmap;

	machine = perf_session__findnew_machine(session, self->mmap.pid);
	if (!machine) {
		pr_err("Can't find id %d's machine\n", self->mmap.pid);
		goto out_problem;
	}

	machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix));
	if (machine__is_host(machine))
		kernel_type = DSO_TYPE_KERNEL;
	else
		kernel_type = DSO_TYPE_GUEST_KERNEL;

	is_kernel_mmap = memcmp(self->mmap.filename,
				kmmap_prefix,
				strlen(kmmap_prefix)) == 0;
	if (self->mmap.filename[0] == '/' ||
	    (!is_kernel_mmap && self->mmap.filename[0] == '[')) {

		char short_module_name[1024];
		char *name, *dot;

		if (self->mmap.filename[0] == '/') {
			name = strrchr(self->mmap.filename, '/');
			if (name == NULL)
				goto out_problem;

			++name; /* skip / */
			dot = strrchr(name, '.');
			if (dot == NULL)
				goto out_problem;
			snprintf(short_module_name, sizeof(short_module_name),
					"[%.*s]", (int)(dot - name), name);
			strxfrchar(short_module_name, '-', '_');
		} else
			strcpy(short_module_name, self->mmap.filename);

		map = machine__new_module(machine, self->mmap.start,
					  self->mmap.filename);
		if (map == NULL)
			goto out_problem;

		name = strdup(short_module_name);
		if (name == NULL)
			goto out_problem;

		map->dso->short_name = name;
		map->end = map->start + self->mmap.len;
	} else if (is_kernel_mmap) {
		const char *symbol_name = (self->mmap.filename +
				strlen(kmmap_prefix));
		/*
		 * Should be there already, from the build-id table in
		 * the header.
		 */
		struct dso *kernel = __dsos__findnew(&machine->kernel_dsos,
						     kmmap_prefix);
		if (kernel == NULL)
			goto out_problem;

		kernel->kernel = kernel_type;
		if (__machine__create_kernel_maps(machine, kernel) < 0)
			goto out_problem;

		event_set_kernel_mmap_len(machine->vmlinux_maps, self);
		perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
							 symbol_name,
							 self->mmap.pgoff);
		if (machine__is_default_guest(machine)) {
			/*
			 * preload dso of guest kernel and modules
			 */
			dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION],
				  NULL);
		}
	}
	return 0;
out_problem:
	return -1;
}