perf symbols: Unify symbol maps

Remove the split of symbol tables for data (MAP__VARIABLE) and for
functions (MAP__FUNCTION), its unneeded and there were various places
doing two lookups to find a symbol, so simplify this.

We still will consider only the symbols that matched the filters in
place, i.e. see the (elf_(sec,sym)|symbol_type)__filter() routines in
the patch, just so that we consider only the same symbols as before,
to reduce the possibility of regressions.

All the tests on 50-something build environments, in varios versions
of lots of distros and cross build environments were performed without
build regressions, as usual with all pull requests the other tests were
also performed: 'perf test' and 'make -C tools/perf build-test'.

Also this was done at a great granularity so that regressions can be
bisected more easily.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: https://lkml.kernel.org/n/tip-hiq0fy2rsleupnqqwuojo1ne@git.kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent e9814df8
...@@ -228,7 +228,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, ...@@ -228,7 +228,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
*/ */
if (al->sym != NULL) { if (al->sym != NULL) {
rb_erase(&al->sym->rb_node, rb_erase(&al->sym->rb_node,
&al->map->dso->symbols[al->map->type]); &al->map->dso->symbols);
symbol__delete(al->sym); symbol__delete(al->sym);
dso__reset_find_symbol_cache(al->map->dso); dso__reset_find_symbol_cache(al->map->dso);
} }
......
...@@ -715,10 +715,7 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp) ...@@ -715,10 +715,7 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
static int map_groups__fprintf_task(struct map_groups *mg, int indent, FILE *fp) static int map_groups__fprintf_task(struct map_groups *mg, int indent, FILE *fp)
{ {
int printed = 0, i; return maps__fprintf_task(&mg->maps, indent, fp);
for (i = 0; i < MAP__NR_TYPES; ++i)
printed += maps__fprintf_task(&mg->maps[i], indent, fp);
return printed;
} }
static void task__print_level(struct task *task, FILE *fp, int level) static void task__print_level(struct task *task, FILE *fp, int level)
......
...@@ -131,7 +131,7 @@ struct machine *setup_fake_machine(struct machines *machines) ...@@ -131,7 +131,7 @@ struct machine *setup_fake_machine(struct machines *machines)
goto out; goto out;
/* emulate dso__load() */ /* emulate dso__load() */
dso__set_loaded(dso, MAP__FUNCTION); dso__set_loaded(dso);
for (k = 0; k < fake_symbols[i].nr_syms; k++) { for (k = 0; k < fake_symbols[i].nr_syms; k++) {
struct symbol *sym; struct symbol *sym;
...@@ -144,7 +144,7 @@ struct machine *setup_fake_machine(struct machines *machines) ...@@ -144,7 +144,7 @@ struct machine *setup_fake_machine(struct machines *machines)
goto out; goto out;
} }
symbols__insert(&dso->symbols[MAP__FUNCTION], sym); symbols__insert(&dso->symbols, sym);
} }
dso__put(dso); dso__put(dso);
......
...@@ -104,7 +104,7 @@ int map__browse(struct map *map) ...@@ -104,7 +104,7 @@ int map__browse(struct map *map)
{ {
struct map_browser mb = { struct map_browser mb = {
.b = { .b = {
.entries = &map->dso->symbols[map->type], .entries = &map->dso->symbols,
.refresh = ui_browser__rb_tree_refresh, .refresh = ui_browser__rb_tree_refresh,
.seek = ui_browser__rb_tree_seek, .seek = ui_browser__rb_tree_seek,
.write = map_browser__write, .write = map_browser__write,
......
...@@ -249,7 +249,7 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al, ...@@ -249,7 +249,7 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al,
if (!al->sym) { if (!al->sym) {
al->sym = symbol__new(al->addr, 0, 0, 0, "unknown"); al->sym = symbol__new(al->addr, 0, 0, 0, "unknown");
if (al->sym) if (al->sym)
dso__insert_symbol(dso, al->map->type, al->sym); dso__insert_symbol(dso, al->sym);
} }
if (al->sym) { if (al->sym) {
......
...@@ -1014,7 +1014,7 @@ struct map *dso__new_map(const char *name) ...@@ -1014,7 +1014,7 @@ struct map *dso__new_map(const char *name)
struct dso *dso = dso__new(name); struct dso *dso = dso__new(name);
if (dso) if (dso)
map = map__new2(0, dso, MAP__FUNCTION); map = map__new2(0, dso);
return map; return map;
} }
...@@ -1176,19 +1176,19 @@ int dso__name_len(const struct dso *dso) ...@@ -1176,19 +1176,19 @@ int dso__name_len(const struct dso *dso)
return dso->short_name_len; return dso->short_name_len;
} }
bool dso__loaded(const struct dso *dso, enum map_type type) bool dso__loaded(const struct dso *dso)
{ {
return dso->loaded & (1 << type); return dso->loaded;
} }
bool dso__sorted_by_name(const struct dso *dso, enum map_type type) bool dso__sorted_by_name(const struct dso *dso)
{ {
return dso->sorted_by_name & (1 << type); return dso->sorted_by_name;
} }
void dso__set_sorted_by_name(struct dso *dso, enum map_type type) void dso__set_sorted_by_name(struct dso *dso)
{ {
dso->sorted_by_name |= (1 << type); dso->sorted_by_name = true;
} }
struct dso *dso__new(const char *name) struct dso *dso__new(const char *name)
...@@ -1196,12 +1196,10 @@ struct dso *dso__new(const char *name) ...@@ -1196,12 +1196,10 @@ struct dso *dso__new(const char *name)
struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1); struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
if (dso != NULL) { if (dso != NULL) {
int i;
strcpy(dso->name, name); strcpy(dso->name, name);
dso__set_long_name(dso, dso->name, false); dso__set_long_name(dso, dso->name, false);
dso__set_short_name(dso, dso->name, false); dso__set_short_name(dso, dso->name, false);
for (i = 0; i < MAP__NR_TYPES; ++i) dso->symbols = dso->symbol_names = RB_ROOT;
dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
dso->data.cache = RB_ROOT; dso->data.cache = RB_ROOT;
dso->inlined_nodes = RB_ROOT; dso->inlined_nodes = RB_ROOT;
dso->srclines = RB_ROOT; dso->srclines = RB_ROOT;
...@@ -1231,8 +1229,6 @@ struct dso *dso__new(const char *name) ...@@ -1231,8 +1229,6 @@ struct dso *dso__new(const char *name)
void dso__delete(struct dso *dso) void dso__delete(struct dso *dso)
{ {
int i;
if (!RB_EMPTY_NODE(&dso->rb_node)) if (!RB_EMPTY_NODE(&dso->rb_node))
pr_err("DSO %s is still in rbtree when being deleted!\n", pr_err("DSO %s is still in rbtree when being deleted!\n",
dso->long_name); dso->long_name);
...@@ -1240,8 +1236,7 @@ void dso__delete(struct dso *dso) ...@@ -1240,8 +1236,7 @@ void dso__delete(struct dso *dso)
/* free inlines first, as they reference symbols */ /* free inlines first, as they reference symbols */
inlines__tree_delete(&dso->inlined_nodes); inlines__tree_delete(&dso->inlined_nodes);
srcline__tree_delete(&dso->srclines); srcline__tree_delete(&dso->srclines);
for (i = 0; i < MAP__NR_TYPES; ++i) symbols__delete(&dso->symbols);
symbols__delete(&dso->symbols[i]);
if (dso->short_name_allocated) { if (dso->short_name_allocated) {
zfree((char **)&dso->short_name); zfree((char **)&dso->short_name);
...@@ -1451,9 +1446,7 @@ size_t __dsos__fprintf(struct list_head *head, FILE *fp) ...@@ -1451,9 +1446,7 @@ size_t __dsos__fprintf(struct list_head *head, FILE *fp)
size_t ret = 0; size_t ret = 0;
list_for_each_entry(pos, head, node) { list_for_each_entry(pos, head, node) {
int i; ret += dso__fprintf(pos, fp);
for (i = 0; i < MAP__NR_TYPES; ++i)
ret += dso__fprintf(pos, i, fp);
} }
return ret; return ret;
...@@ -1467,18 +1460,17 @@ size_t dso__fprintf_buildid(struct dso *dso, FILE *fp) ...@@ -1467,18 +1460,17 @@ size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
return fprintf(fp, "%s", sbuild_id); return fprintf(fp, "%s", sbuild_id);
} }
size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp) size_t dso__fprintf(struct dso *dso, FILE *fp)
{ {
struct rb_node *nd; struct rb_node *nd;
size_t ret = fprintf(fp, "dso: %s (", dso->short_name); size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
if (dso->short_name != dso->long_name) if (dso->short_name != dso->long_name)
ret += fprintf(fp, "%s, ", dso->long_name); ret += fprintf(fp, "%s, ", dso->long_name);
ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type], ret += fprintf(fp, "%sloaded, ", dso__loaded(dso) ? "" : "NOT ");
dso__loaded(dso, type) ? "" : "NOT ");
ret += dso__fprintf_buildid(dso, fp); ret += dso__fprintf_buildid(dso, fp);
ret += fprintf(fp, ")\n"); ret += fprintf(fp, ")\n");
for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) { for (nd = rb_first(&dso->symbols); nd; nd = rb_next(nd)) {
struct symbol *pos = rb_entry(nd, struct symbol, rb_node); struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
ret += symbol__fprintf(pos, fp); ret += symbol__fprintf(pos, fp);
} }
......
...@@ -140,14 +140,14 @@ struct dso { ...@@ -140,14 +140,14 @@ struct dso {
struct list_head node; struct list_head node;
struct rb_node rb_node; /* rbtree node sorted by long name */ struct rb_node rb_node; /* rbtree node sorted by long name */
struct rb_root *root; /* root of rbtree that rb_node is in */ struct rb_root *root; /* root of rbtree that rb_node is in */
struct rb_root symbols[MAP__NR_TYPES]; struct rb_root symbols;
struct rb_root symbol_names[MAP__NR_TYPES]; struct rb_root symbol_names;
struct rb_root inlined_nodes; struct rb_root inlined_nodes;
struct rb_root srclines; struct rb_root srclines;
struct { struct {
u64 addr; u64 addr;
struct symbol *symbol; struct symbol *symbol;
} last_find_result[MAP__NR_TYPES]; } last_find_result;
void *a2l; void *a2l;
char *symsrc_filename; char *symsrc_filename;
unsigned int a2l_fails; unsigned int a2l_fails;
...@@ -164,8 +164,8 @@ struct dso { ...@@ -164,8 +164,8 @@ struct dso {
u8 short_name_allocated:1; u8 short_name_allocated:1;
u8 long_name_allocated:1; u8 long_name_allocated:1;
u8 is_64_bit:1; u8 is_64_bit:1;
u8 sorted_by_name; bool sorted_by_name;
u8 loaded; bool loaded;
u8 rel; u8 rel;
u8 build_id[BUILD_ID_SIZE]; u8 build_id[BUILD_ID_SIZE];
u64 text_offset; u64 text_offset;
...@@ -202,14 +202,13 @@ struct dso { ...@@ -202,14 +202,13 @@ struct dso {
* @dso: the 'struct dso *' in which symbols itereated * @dso: the 'struct dso *' in which symbols itereated
* @pos: the 'struct symbol *' to use as a loop cursor * @pos: the 'struct symbol *' to use as a loop cursor
* @n: the 'struct rb_node *' to use as a temporary storage * @n: the 'struct rb_node *' to use as a temporary storage
* @type: the 'enum map_type' type of symbols
*/ */
#define dso__for_each_symbol(dso, pos, n, type) \ #define dso__for_each_symbol(dso, pos, n) \
symbols__for_each_entry(&(dso)->symbols[(type)], pos, n) symbols__for_each_entry(&(dso)->symbols, pos, n)
static inline void dso__set_loaded(struct dso *dso, enum map_type type) static inline void dso__set_loaded(struct dso *dso)
{ {
dso->loaded |= (1 << type); dso->loaded = true;
} }
struct dso *dso__new(const char *name); struct dso *dso__new(const char *name);
...@@ -231,16 +230,16 @@ static inline void __dso__zput(struct dso **dso) ...@@ -231,16 +230,16 @@ static inline void __dso__zput(struct dso **dso)
#define dso__zput(dso) __dso__zput(&dso) #define dso__zput(dso) __dso__zput(&dso)
bool dso__loaded(const struct dso *dso, enum map_type type); bool dso__loaded(const struct dso *dso);
static inline bool dso__has_symbols(const struct dso *dso, enum map_type type) static inline bool dso__has_symbols(const struct dso *dso)
{ {
return !RB_EMPTY_ROOT(&dso->symbols[type]); return !RB_EMPTY_ROOT(&dso->symbols);
} }
bool dso__sorted_by_name(const struct dso *dso, enum map_type type); bool dso__sorted_by_name(const struct dso *dso);
void dso__set_sorted_by_name(struct dso *dso, enum map_type type); void dso__set_sorted_by_name(struct dso *dso);
void dso__sort_by_name(struct dso *dso, enum map_type type); void dso__sort_by_name(struct dso *dso);
void dso__set_build_id(struct dso *dso, void *build_id); void dso__set_build_id(struct dso *dso, void *build_id);
bool dso__build_id_equal(const struct dso *dso, u8 *build_id); bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
...@@ -354,9 +353,8 @@ size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, ...@@ -354,9 +353,8 @@ size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
size_t __dsos__fprintf(struct list_head *head, FILE *fp); size_t __dsos__fprintf(struct list_head *head, FILE *fp);
size_t dso__fprintf_buildid(struct dso *dso, FILE *fp); size_t dso__fprintf_buildid(struct dso *dso, FILE *fp);
size_t dso__fprintf_symbols_by_name(struct dso *dso, size_t dso__fprintf_symbols_by_name(struct dso *dso, FILE *fp);
enum map_type type, FILE *fp); size_t dso__fprintf(struct dso *dso, FILE *fp);
size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);
static inline bool dso__is_vmlinux(struct dso *dso) static inline bool dso__is_vmlinux(struct dso *dso)
{ {
......
...@@ -1488,8 +1488,8 @@ int perf_event__process(struct perf_tool *tool __maybe_unused, ...@@ -1488,8 +1488,8 @@ int perf_event__process(struct perf_tool *tool __maybe_unused,
return machine__process_event(machine, event, sample); return machine__process_event(machine, event, sample);
} }
static struct map *__thread__find_map(struct thread *thread, u8 cpumode, enum map_type type, struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
u64 addr, struct addr_location *al) struct addr_location *al)
{ {
struct map_groups *mg = thread->mg; struct map_groups *mg = thread->mg;
struct machine *machine = mg->machine; struct machine *machine = mg->machine;
...@@ -1534,7 +1534,7 @@ static struct map *__thread__find_map(struct thread *thread, u8 cpumode, enum ma ...@@ -1534,7 +1534,7 @@ static struct map *__thread__find_map(struct thread *thread, u8 cpumode, enum ma
return NULL; return NULL;
} }
try_again: try_again:
al->map = __map_groups__find(mg, type, al->addr); al->map = map_groups__find(mg, al->addr);
if (al->map == NULL) { if (al->map == NULL) {
/* /*
* If this is outside of all known maps, and is a negative * If this is outside of all known maps, and is a negative
...@@ -1565,13 +1565,6 @@ static struct map *__thread__find_map(struct thread *thread, u8 cpumode, enum ma ...@@ -1565,13 +1565,6 @@ static struct map *__thread__find_map(struct thread *thread, u8 cpumode, enum ma
return al->map; return al->map;
} }
struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
struct addr_location *al)
{
struct map *map = __thread__find_map(thread, cpumode, MAP__FUNCTION, addr, al);
return map ?: __thread__find_map(thread, cpumode, MAP__VARIABLE, addr, al);
}
struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
u64 addr, struct addr_location *al) u64 addr, struct addr_location *al)
{ {
......
...@@ -82,8 +82,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) ...@@ -82,8 +82,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
machine->kptr_restrict_warned = false; machine->kptr_restrict_warned = false;
machine->comm_exec = false; machine->comm_exec = false;
machine->kernel_start = 0; machine->kernel_start = 0;
machine->vmlinux_map = NULL;
memset(machine->vmlinux_maps, 0, sizeof(machine->vmlinux_maps));
machine->root_dir = strdup(root_dir); machine->root_dir = strdup(root_dir);
if (machine->root_dir == NULL) if (machine->root_dir == NULL)
...@@ -687,7 +686,7 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start, ...@@ -687,7 +686,7 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start,
if (dso == NULL) if (dso == NULL)
goto out; goto out;
map = map__new2(start, dso, MAP__FUNCTION); map = map__new2(start, dso);
if (map == NULL) if (map == NULL)
goto out; goto out;
...@@ -855,62 +854,44 @@ static int machine__get_running_kernel_start(struct machine *machine, ...@@ -855,62 +854,44 @@ static int machine__get_running_kernel_start(struct machine *machine,
static int static int
__machine__create_kernel_maps(struct machine *machine, struct dso *kernel) __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
{ {
int type; struct kmap *kmap;
struct map *map;
/* In case of renewal the kernel map, destroy previous one */ /* In case of renewal the kernel map, destroy previous one */
machine__destroy_kernel_maps(machine); machine__destroy_kernel_maps(machine);
for (type = 0; type < MAP__NR_TYPES; ++type) { machine->vmlinux_map = map__new2(0, kernel);
struct kmap *kmap; if (machine->vmlinux_map == NULL)
struct map *map; return -1;
machine->vmlinux_maps[type] = map__new2(0, kernel, type);
if (machine->vmlinux_maps[type] == NULL)
return -1;
machine->vmlinux_maps[type]->map_ip = machine->vmlinux_map->map_ip = machine->vmlinux_map->unmap_ip = identity__map_ip;
machine->vmlinux_maps[type]->unmap_ip = map = machine__kernel_map(machine);
identity__map_ip; kmap = map__kmap(map);
map = __machine__kernel_map(machine, type); if (!kmap)
kmap = map__kmap(map); return -1;
if (!kmap)
return -1;
kmap->kmaps = &machine->kmaps; kmap->kmaps = &machine->kmaps;
map_groups__insert(&machine->kmaps, map); map_groups__insert(&machine->kmaps, map);
}
return 0; return 0;
} }
void machine__destroy_kernel_maps(struct machine *machine) void machine__destroy_kernel_maps(struct machine *machine)
{ {
int type; struct kmap *kmap;
struct map *map = machine__kernel_map(machine);
for (type = 0; type < MAP__NR_TYPES; ++type) {
struct kmap *kmap;
struct map *map = __machine__kernel_map(machine, type);
if (map == NULL)
continue;
kmap = map__kmap(map); if (map == NULL)
map_groups__remove(&machine->kmaps, map); return;
if (kmap && kmap->ref_reloc_sym) {
/*
* ref_reloc_sym is shared among all maps, so free just
* on one of them.
*/
if (type == MAP__FUNCTION) {
zfree((char **)&kmap->ref_reloc_sym->name);
zfree(&kmap->ref_reloc_sym);
} else
kmap->ref_reloc_sym = NULL;
}
map__put(machine->vmlinux_maps[type]); kmap = map__kmap(map);
machine->vmlinux_maps[type] = NULL; map_groups__remove(&machine->kmaps, map);
if (kmap && kmap->ref_reloc_sym) {
zfree((char **)&kmap->ref_reloc_sym->name);
zfree(&kmap->ref_reloc_sym);
} }
map__zput(machine->vmlinux_map);
} }
int machines__create_guest_kernel_maps(struct machines *machines) int machines__create_guest_kernel_maps(struct machines *machines)
...@@ -987,20 +968,19 @@ int machines__create_kernel_maps(struct machines *machines, pid_t pid) ...@@ -987,20 +968,19 @@ int machines__create_kernel_maps(struct machines *machines, pid_t pid)
return machine__create_kernel_maps(machine); return machine__create_kernel_maps(machine);
} }
int __machine__load_kallsyms(struct machine *machine, const char *filename, int machine__load_kallsyms(struct machine *machine, const char *filename)
enum map_type type)
{ {
struct map *map = machine__kernel_map(machine); struct map *map = machine__kernel_map(machine);
int ret = __dso__load_kallsyms(map->dso, filename, map, true); int ret = __dso__load_kallsyms(map->dso, filename, map, true);
if (ret > 0) { if (ret > 0) {
dso__set_loaded(map->dso, type); dso__set_loaded(map->dso);
/* /*
* Since /proc/kallsyms will have multiple sessions for the * Since /proc/kallsyms will have multiple sessions for the
* kernel, with modules between them, fixup the end of all * kernel, with modules between them, fixup the end of all
* sections. * sections.
*/ */
__map_groups__fixup_end(&machine->kmaps, type); map_groups__fixup_end(&machine->kmaps);
} }
return ret; return ret;
...@@ -1012,7 +992,7 @@ int machine__load_vmlinux_path(struct machine *machine) ...@@ -1012,7 +992,7 @@ int machine__load_vmlinux_path(struct machine *machine)
int ret = dso__load_vmlinux_path(map->dso, map); int ret = dso__load_vmlinux_path(map->dso, map);
if (ret > 0) if (ret > 0)
dso__set_loaded(map->dso, map->type); dso__set_loaded(map->dso);
return ret; return ret;
} }
...@@ -1204,19 +1184,14 @@ static int machine__create_modules(struct machine *machine) ...@@ -1204,19 +1184,14 @@ static int machine__create_modules(struct machine *machine)
static void machine__set_kernel_mmap(struct machine *machine, static void machine__set_kernel_mmap(struct machine *machine,
u64 start, u64 end) u64 start, u64 end)
{ {
int i; machine->vmlinux_map->start = start;
machine->vmlinux_map->end = end;
for (i = 0; i < MAP__NR_TYPES; i++) { /*
machine->vmlinux_maps[i]->start = start; * Be a bit paranoid here, some perf.data file came with
machine->vmlinux_maps[i]->end = end; * a zero sized synthesized MMAP event for the kernel.
*/
/* if (start == 0 && end == 0)
* Be a bit paranoid here, some perf.data file came with machine->vmlinux_map->end = ~0ULL;
* a zero sized synthesized MMAP event for the kernel.
*/
if (start == 0 && end == 0)
machine->vmlinux_maps[i]->end = ~0ULL;
}
} }
int machine__create_kernel_maps(struct machine *machine) int machine__create_kernel_maps(struct machine *machine)
...@@ -1246,7 +1221,7 @@ int machine__create_kernel_maps(struct machine *machine) ...@@ -1246,7 +1221,7 @@ int machine__create_kernel_maps(struct machine *machine)
if (!machine__get_running_kernel_start(machine, &name, &addr)) { if (!machine__get_running_kernel_start(machine, &name, &addr)) {
if (name && if (name &&
maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, addr)) { map__set_kallsyms_ref_reloc_sym(machine->vmlinux_map, name, addr)) {
machine__destroy_kernel_maps(machine); machine__destroy_kernel_maps(machine);
return -1; return -1;
} }
...@@ -1376,9 +1351,9 @@ static int machine__process_kernel_mmap_event(struct machine *machine, ...@@ -1376,9 +1351,9 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
* time /proc/sys/kernel/kptr_restrict was non zero. * time /proc/sys/kernel/kptr_restrict was non zero.
*/ */
if (event->mmap.pgoff != 0) { if (event->mmap.pgoff != 0) {
maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, map__set_kallsyms_ref_reloc_sym(machine->vmlinux_map,
symbol_name, symbol_name,
event->mmap.pgoff); event->mmap.pgoff);
} }
if (machine__is_default_guest(machine)) { if (machine__is_default_guest(machine)) {
...@@ -1399,7 +1374,6 @@ int machine__process_mmap2_event(struct machine *machine, ...@@ -1399,7 +1374,6 @@ int machine__process_mmap2_event(struct machine *machine,
{ {
struct thread *thread; struct thread *thread;
struct map *map; struct map *map;
enum map_type type;
int ret = 0; int ret = 0;
if (dump_trace) if (dump_trace)
...@@ -1418,11 +1392,6 @@ int machine__process_mmap2_event(struct machine *machine, ...@@ -1418,11 +1392,6 @@ int machine__process_mmap2_event(struct machine *machine,
if (thread == NULL) if (thread == NULL)
goto out_problem; goto out_problem;
if (event->header.misc & PERF_RECORD_MISC_MMAP_DATA)
type = MAP__VARIABLE;
else
type = MAP__FUNCTION;
map = map__new(machine, event->mmap2.start, map = map__new(machine, event->mmap2.start,
event->mmap2.len, event->mmap2.pgoff, event->mmap2.len, event->mmap2.pgoff,
event->mmap2.maj, event->mmap2.maj,
...@@ -1430,7 +1399,7 @@ int machine__process_mmap2_event(struct machine *machine, ...@@ -1430,7 +1399,7 @@ int machine__process_mmap2_event(struct machine *machine,
event->mmap2.ino_generation, event->mmap2.ino_generation,
event->mmap2.prot, event->mmap2.prot,
event->mmap2.flags, event->mmap2.flags,
event->mmap2.filename, type, thread); event->mmap2.filename, thread);
if (map == NULL) if (map == NULL)
goto out_problem_map; goto out_problem_map;
...@@ -1457,7 +1426,6 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event ...@@ -1457,7 +1426,6 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
{ {
struct thread *thread; struct thread *thread;
struct map *map; struct map *map;
enum map_type type;
u32 prot = 0; u32 prot = 0;
int ret = 0; int ret = 0;
...@@ -1477,18 +1445,14 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event ...@@ -1477,18 +1445,14 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
if (thread == NULL) if (thread == NULL)
goto out_problem; goto out_problem;
if (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) if (!(event->header.misc & PERF_RECORD_MISC_MMAP_DATA))
type = MAP__VARIABLE;
else {
type = MAP__FUNCTION;
prot = PROT_EXEC; prot = PROT_EXEC;
}
map = map__new(machine, event->mmap.start, map = map__new(machine, event->mmap.start,
event->mmap.len, event->mmap.pgoff, event->mmap.len, event->mmap.pgoff,
0, 0, 0, 0, prot, 0, 0, 0, 0, 0, prot, 0,
event->mmap.filename, event->mmap.filename,
type, thread); thread);
if (map == NULL) if (map == NULL)
goto out_problem_map; goto out_problem_map;
......
...@@ -49,7 +49,7 @@ struct machine { ...@@ -49,7 +49,7 @@ struct machine {
struct perf_env *env; struct perf_env *env;
struct dsos dsos; struct dsos dsos;
struct map_groups kmaps; struct map_groups kmaps;
struct map *vmlinux_maps[MAP__NR_TYPES]; struct map *vmlinux_map;
u64 kernel_start; u64 kernel_start;
pid_t *current_tid; pid_t *current_tid;
union { /* Tool specific area */ union { /* Tool specific area */
...@@ -64,19 +64,13 @@ static inline struct threads *machine__threads(struct machine *machine, pid_t ti ...@@ -64,19 +64,13 @@ static inline struct threads *machine__threads(struct machine *machine, pid_t ti
return &machine->threads[(unsigned int)tid % THREADS__TABLE_SIZE]; return &machine->threads[(unsigned int)tid % THREADS__TABLE_SIZE];
} }
static inline
struct map *__machine__kernel_map(struct machine *machine, enum map_type type)
{
return machine->vmlinux_maps[type];
}
/* /*
* The main kernel (vmlinux) map * The main kernel (vmlinux) map
*/ */
static inline static inline
struct map *machine__kernel_map(struct machine *machine) struct map *machine__kernel_map(struct machine *machine)
{ {
return __machine__kernel_map(machine, MAP__FUNCTION); return machine->vmlinux_map;
} }
/* /*
...@@ -85,7 +79,7 @@ struct map *machine__kernel_map(struct machine *machine) ...@@ -85,7 +79,7 @@ struct map *machine__kernel_map(struct machine *machine)
static inline static inline
struct maps *machine__kernel_maps(struct machine *machine) struct maps *machine__kernel_maps(struct machine *machine)
{ {
return &machine->kmaps.maps[MAP__FUNCTION]; return &machine->kmaps.maps;
} }
int machine__get_kernel_start(struct machine *machine); int machine__get_kernel_start(struct machine *machine);
...@@ -202,27 +196,25 @@ struct dso *machine__findnew_dso(struct machine *machine, const char *filename); ...@@ -202,27 +196,25 @@ struct dso *machine__findnew_dso(struct machine *machine, const char *filename);
size_t machine__fprintf(struct machine *machine, FILE *fp); size_t machine__fprintf(struct machine *machine, FILE *fp);
static inline static inline
struct symbol *machine__find_kernel_symbol(struct machine *machine, struct symbol *machine__find_kernel_symbol(struct machine *machine, u64 addr,
enum map_type type, u64 addr,
struct map **mapp) struct map **mapp)
{ {
return map_groups__find_symbol(&machine->kmaps, type, addr, mapp); return map_groups__find_symbol(&machine->kmaps, addr, mapp);
} }
static inline static inline
struct symbol *machine__find_kernel_symbol_by_name(struct machine *machine, struct symbol *machine__find_kernel_symbol_by_name(struct machine *machine,
enum map_type type, const char *name, const char *name,
struct map **mapp) struct map **mapp)
{ {
return map_groups__find_symbol_by_name(&machine->kmaps, type, name, mapp); return map_groups__find_symbol_by_name(&machine->kmaps, name, mapp);
} }
static inline static inline
struct symbol *machine__find_kernel_function(struct machine *machine, u64 addr, struct symbol *machine__find_kernel_function(struct machine *machine, u64 addr,
struct map **mapp) struct map **mapp)
{ {
return machine__find_kernel_symbol(machine, MAP__FUNCTION, addr, return machine__find_kernel_symbol(machine, addr, mapp);
mapp);
} }
static inline static inline
...@@ -237,13 +229,7 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start, ...@@ -237,13 +229,7 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start,
const char *filename); const char *filename);
int arch__fix_module_text_start(u64 *start, const char *name); int arch__fix_module_text_start(u64 *start, const char *name);
int __machine__load_kallsyms(struct machine *machine, const char *filename, int machine__load_kallsyms(struct machine *machine, const char *filename);
enum map_type type);
static inline int machine__load_kallsyms(struct machine *machine, const char *filename)
{
return __machine__load_kallsyms(machine, filename, MAP__FUNCTION);
}
int machine__load_vmlinux_path(struct machine *machine); int machine__load_vmlinux_path(struct machine *machine);
......
...@@ -22,11 +22,6 @@ ...@@ -22,11 +22,6 @@
static void __maps__insert(struct maps *maps, struct map *map); static void __maps__insert(struct maps *maps, struct map *map);
const char *map_type__name[MAP__NR_TYPES] = {
[MAP__FUNCTION] = "Functions",
[MAP__VARIABLE] = "Variables",
};
static inline int is_anon_memory(const char *filename, u32 flags) static inline int is_anon_memory(const char *filename, u32 flags)
{ {
return flags & MAP_HUGETLB || return flags & MAP_HUGETLB ||
...@@ -129,10 +124,8 @@ static inline bool replace_android_lib(const char *filename, char *newfilename) ...@@ -129,10 +124,8 @@ static inline bool replace_android_lib(const char *filename, char *newfilename)
return false; return false;
} }
void map__init(struct map *map, enum map_type type, void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso)
u64 start, u64 end, u64 pgoff, struct dso *dso)
{ {
map->type = type;
map->start = start; map->start = start;
map->end = end; map->end = end;
map->pgoff = pgoff; map->pgoff = pgoff;
...@@ -149,7 +142,7 @@ void map__init(struct map *map, enum map_type type, ...@@ -149,7 +142,7 @@ void map__init(struct map *map, enum map_type type,
struct map *map__new(struct machine *machine, u64 start, u64 len, struct map *map__new(struct machine *machine, u64 start, u64 len,
u64 pgoff, u32 d_maj, u32 d_min, u64 ino, u64 pgoff, u32 d_maj, u32 d_min, u64 ino,
u64 ino_gen, u32 prot, u32 flags, char *filename, u64 ino_gen, u32 prot, u32 flags, char *filename,
enum map_type type, struct thread *thread) struct thread *thread)
{ {
struct map *map = malloc(sizeof(*map)); struct map *map = malloc(sizeof(*map));
struct nsinfo *nsi = NULL; struct nsinfo *nsi = NULL;
...@@ -203,7 +196,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, ...@@ -203,7 +196,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
if (dso == NULL) if (dso == NULL)
goto out_delete; goto out_delete;
map__init(map, type, start, start + len, pgoff, dso); map__init(map, start, start + len, pgoff, dso);
if (anon || no_dso) { if (anon || no_dso) {
map->map_ip = map->unmap_ip = identity__map_ip; map->map_ip = map->unmap_ip = identity__map_ip;
...@@ -214,7 +207,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, ...@@ -214,7 +207,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
* unnecessary map__load warning. * unnecessary map__load warning.
*/ */
if (!(prot & PROT_EXEC)) if (!(prot & PROT_EXEC))
dso__set_loaded(dso, map->type); dso__set_loaded(dso);
} }
dso->nsinfo = nsi; dso->nsinfo = nsi;
dso__put(dso); dso__put(dso);
...@@ -231,7 +224,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, ...@@ -231,7 +224,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
* they are loaded) and for vmlinux, where only after we load all the * they are loaded) and for vmlinux, where only after we load all the
* symbols we'll know where it starts and ends. * symbols we'll know where it starts and ends.
*/ */
struct map *map__new2(u64 start, struct dso *dso, enum map_type type) struct map *map__new2(u64 start, struct dso *dso)
{ {
struct map *map = calloc(1, (sizeof(*map) + struct map *map = calloc(1, (sizeof(*map) +
(dso->kernel ? sizeof(struct kmap) : 0))); (dso->kernel ? sizeof(struct kmap) : 0)));
...@@ -239,7 +232,7 @@ struct map *map__new2(u64 start, struct dso *dso, enum map_type type) ...@@ -239,7 +232,7 @@ struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
/* /*
* ->end will be filled after we load all the symbols * ->end will be filled after we load all the symbols
*/ */
map__init(map, type, start, 0, 0, dso); map__init(map, start, 0, 0, dso);
} }
return map; return map;
...@@ -256,12 +249,12 @@ struct map *map__new2(u64 start, struct dso *dso, enum map_type type) ...@@ -256,12 +249,12 @@ struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
*/ */
bool __map__is_kernel(const struct map *map) bool __map__is_kernel(const struct map *map)
{ {
return __machine__kernel_map(map->groups->machine, map->type) == map; return machine__kernel_map(map->groups->machine) == map;
} }
bool map__has_symbols(const struct map *map) bool map__has_symbols(const struct map *map)
{ {
return dso__has_symbols(map->dso, map->type); return dso__has_symbols(map->dso);
} }
static void map__exit(struct map *map) static void map__exit(struct map *map)
...@@ -284,7 +277,7 @@ void map__put(struct map *map) ...@@ -284,7 +277,7 @@ void map__put(struct map *map)
void map__fixup_start(struct map *map) void map__fixup_start(struct map *map)
{ {
struct rb_root *symbols = &map->dso->symbols[map->type]; struct rb_root *symbols = &map->dso->symbols;
struct rb_node *nd = rb_first(symbols); struct rb_node *nd = rb_first(symbols);
if (nd != NULL) { if (nd != NULL) {
struct symbol *sym = rb_entry(nd, struct symbol, rb_node); struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
...@@ -294,7 +287,7 @@ void map__fixup_start(struct map *map) ...@@ -294,7 +287,7 @@ void map__fixup_start(struct map *map)
void map__fixup_end(struct map *map) void map__fixup_end(struct map *map)
{ {
struct rb_root *symbols = &map->dso->symbols[map->type]; struct rb_root *symbols = &map->dso->symbols;
struct rb_node *nd = rb_last(symbols); struct rb_node *nd = rb_last(symbols);
if (nd != NULL) { if (nd != NULL) {
struct symbol *sym = rb_entry(nd, struct symbol, rb_node); struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
...@@ -309,7 +302,7 @@ int map__load(struct map *map) ...@@ -309,7 +302,7 @@ int map__load(struct map *map)
const char *name = map->dso->long_name; const char *name = map->dso->long_name;
int nr; int nr;
if (dso__loaded(map->dso, map->type)) if (dso__loaded(map->dso))
return 0; return 0;
nr = dso__load(map->dso, map); nr = dso__load(map->dso, map);
...@@ -353,7 +346,7 @@ struct symbol *map__find_symbol(struct map *map, u64 addr) ...@@ -353,7 +346,7 @@ struct symbol *map__find_symbol(struct map *map, u64 addr)
if (map__load(map) < 0) if (map__load(map) < 0)
return NULL; return NULL;
return __dso__find_symbol(map->dso, map->type, addr); return dso__find_symbol(map->dso, addr);
} }
struct symbol *map__find_symbol_by_name(struct map *map, const char *name) struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
...@@ -361,10 +354,10 @@ struct symbol *map__find_symbol_by_name(struct map *map, const char *name) ...@@ -361,10 +354,10 @@ struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
if (map__load(map) < 0) if (map__load(map) < 0)
return NULL; return NULL;
if (!dso__sorted_by_name(map->dso, map->type)) if (!dso__sorted_by_name(map->dso))
dso__sort_by_name(map->dso, map->type); dso__sort_by_name(map->dso);
return __dso__find_symbol_by_name(map->dso, map->type, name); return dso__find_symbol_by_name(map->dso, name);
} }
struct map *map__clone(struct map *from) struct map *map__clone(struct map *from)
...@@ -499,10 +492,7 @@ static void maps__init(struct maps *maps) ...@@ -499,10 +492,7 @@ static void maps__init(struct maps *maps)
void map_groups__init(struct map_groups *mg, struct machine *machine) void map_groups__init(struct map_groups *mg, struct machine *machine)
{ {
int i; maps__init(&mg->maps);
for (i = 0; i < MAP__NR_TYPES; ++i) {
maps__init(&mg->maps[i]);
}
mg->machine = machine; mg->machine = machine;
refcount_set(&mg->refcnt, 1); refcount_set(&mg->refcnt, 1);
} }
...@@ -530,22 +520,12 @@ static void maps__exit(struct maps *maps) ...@@ -530,22 +520,12 @@ static void maps__exit(struct maps *maps)
void map_groups__exit(struct map_groups *mg) void map_groups__exit(struct map_groups *mg)
{ {
int i; maps__exit(&mg->maps);
for (i = 0; i < MAP__NR_TYPES; ++i)
maps__exit(&mg->maps[i]);
} }
bool map_groups__empty(struct map_groups *mg) bool map_groups__empty(struct map_groups *mg)
{ {
int i; return !maps__first(&mg->maps);
for (i = 0; i < MAP__NR_TYPES; ++i) {
if (maps__first(&mg->maps[i]))
return false;
}
return true;
} }
struct map_groups *map_groups__new(struct machine *machine) struct map_groups *map_groups__new(struct machine *machine)
...@@ -571,10 +551,9 @@ void map_groups__put(struct map_groups *mg) ...@@ -571,10 +551,9 @@ void map_groups__put(struct map_groups *mg)
} }
struct symbol *map_groups__find_symbol(struct map_groups *mg, struct symbol *map_groups__find_symbol(struct map_groups *mg,
enum map_type type, u64 addr, u64 addr, struct map **mapp)
struct map **mapp)
{ {
struct map *map = __map_groups__find(mg, type, addr); struct map *map = map_groups__find(mg, addr);
/* Ensure map is loaded before using map->map_ip */ /* Ensure map is loaded before using map->map_ip */
if (map != NULL && map__load(map) >= 0) { if (map != NULL && map__load(map) >= 0) {
...@@ -613,13 +592,10 @@ struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, ...@@ -613,13 +592,10 @@ struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
} }
struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
enum map_type type,
const char *name, const char *name,
struct map **mapp) struct map **mapp)
{ {
struct symbol *sym = maps__find_symbol_by_name(&mg->maps[type], name, mapp); return maps__find_symbol_by_name(&mg->maps, name, mapp);
return sym;
} }
int map_groups__find_ams(struct addr_map_symbol *ams) int map_groups__find_ams(struct addr_map_symbol *ams)
...@@ -627,7 +603,7 @@ int map_groups__find_ams(struct addr_map_symbol *ams) ...@@ -627,7 +603,7 @@ int map_groups__find_ams(struct addr_map_symbol *ams)
if (ams->addr < ams->map->start || ams->addr >= ams->map->end) { if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {
if (ams->map->groups == NULL) if (ams->map->groups == NULL)
return -1; return -1;
ams->map = __map_groups__find(ams->map->groups, ams->map->type, ams->addr); ams->map = map_groups__find(ams->map->groups, ams->addr);
if (ams->map == NULL) if (ams->map == NULL)
return -1; return -1;
} }
...@@ -650,7 +626,7 @@ static size_t maps__fprintf(struct maps *maps, FILE *fp) ...@@ -650,7 +626,7 @@ static size_t maps__fprintf(struct maps *maps, FILE *fp)
printed += fprintf(fp, "Map:"); printed += fprintf(fp, "Map:");
printed += map__fprintf(pos, fp); printed += map__fprintf(pos, fp);
if (verbose > 2) { if (verbose > 2) {
printed += dso__fprintf(pos->dso, pos->type, fp); printed += dso__fprintf(pos->dso, fp);
printed += fprintf(fp, "--\n"); printed += fprintf(fp, "--\n");
} }
} }
...@@ -660,24 +636,14 @@ static size_t maps__fprintf(struct maps *maps, FILE *fp) ...@@ -660,24 +636,14 @@ static size_t maps__fprintf(struct maps *maps, FILE *fp)
return printed; return printed;
} }
size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
FILE *fp)
{
size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
return printed += maps__fprintf(&mg->maps[type], fp);
}
size_t map_groups__fprintf(struct map_groups *mg, FILE *fp) size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
{ {
size_t printed = 0, i; return maps__fprintf(&mg->maps, fp);
for (i = 0; i < MAP__NR_TYPES; ++i)
printed += __map_groups__fprintf_maps(mg, i, fp);
return printed;
} }
static void __map_groups__insert(struct map_groups *mg, struct map *map) static void __map_groups__insert(struct map_groups *mg, struct map *map)
{ {
__maps__insert(&mg->maps[map->type], map); __maps__insert(&mg->maps, map);
map->groups = mg; map->groups = mg;
} }
...@@ -762,19 +728,18 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp ...@@ -762,19 +728,18 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
FILE *fp) FILE *fp)
{ {
return maps__fixup_overlappings(&mg->maps[map->type], map, fp); return maps__fixup_overlappings(&mg->maps, map, fp);
} }
/* /*
* XXX This should not really _copy_ te maps, but refcount them. * XXX This should not really _copy_ te maps, but refcount them.
*/ */
int map_groups__clone(struct thread *thread, int map_groups__clone(struct thread *thread, struct map_groups *parent)
struct map_groups *parent, enum map_type type)
{ {
struct map_groups *mg = thread->mg; struct map_groups *mg = thread->mg;
int err = -ENOMEM; int err = -ENOMEM;
struct map *map; struct map *map;
struct maps *maps = &parent->maps[type]; struct maps *maps = &parent->maps;
down_read(&maps->lock); down_read(&maps->lock);
......
...@@ -12,15 +12,6 @@ ...@@ -12,15 +12,6 @@
#include <linux/types.h> #include <linux/types.h>
#include "rwsem.h" #include "rwsem.h"
enum map_type {
MAP__FUNCTION = 0,
MAP__VARIABLE,
};
#define MAP__NR_TYPES (MAP__VARIABLE + 1)
extern const char *map_type__name[MAP__NR_TYPES];
struct dso; struct dso;
struct ip_callchain; struct ip_callchain;
struct ref_reloc_sym; struct ref_reloc_sym;
...@@ -35,7 +26,6 @@ struct map { ...@@ -35,7 +26,6 @@ struct map {
}; };
u64 start; u64 start;
u64 end; u64 end;
u8 /* enum map_type */ type;
bool erange_warned; bool erange_warned;
u32 priv; u32 priv;
u32 prot; u32 prot;
...@@ -67,7 +57,7 @@ struct maps { ...@@ -67,7 +57,7 @@ struct maps {
}; };
struct map_groups { struct map_groups {
struct maps maps[MAP__NR_TYPES]; struct maps maps;
struct machine *machine; struct machine *machine;
refcount_t refcnt; refcount_t refcnt;
}; };
...@@ -125,7 +115,7 @@ struct thread; ...@@ -125,7 +115,7 @@ struct thread;
* Note: caller must ensure map->dso is not NULL (map is loaded). * Note: caller must ensure map->dso is not NULL (map is loaded).
*/ */
#define map__for_each_symbol(map, pos, n) \ #define map__for_each_symbol(map, pos, n) \
dso__for_each_symbol(map->dso, pos, n, map->type) dso__for_each_symbol(map->dso, pos, n)
/* map__for_each_symbol_with_name - iterate over the symbols in the given map /* map__for_each_symbol_with_name - iterate over the symbols in the given map
* that have the given name * that have the given name
...@@ -144,13 +134,13 @@ struct thread; ...@@ -144,13 +134,13 @@ struct thread;
#define map__for_each_symbol_by_name(map, sym_name, pos) \ #define map__for_each_symbol_by_name(map, sym_name, pos) \
__map__for_each_symbol_by_name(map, sym_name, (pos)) __map__for_each_symbol_by_name(map, sym_name, (pos))
void map__init(struct map *map, enum map_type type, void map__init(struct map *map,
u64 start, u64 end, u64 pgoff, struct dso *dso); u64 start, u64 end, u64 pgoff, struct dso *dso);
struct map *map__new(struct machine *machine, u64 start, u64 len, struct map *map__new(struct machine *machine, u64 start, u64 len,
u64 pgoff, u32 d_maj, u32 d_min, u64 ino, u64 pgoff, u32 d_maj, u32 d_min, u64 ino,
u64 ino_gen, u32 prot, u32 flags, u64 ino_gen, u32 prot, u32 flags,
char *filename, enum map_type type, struct thread *thread); char *filename, struct thread *thread);
struct map *map__new2(u64 start, struct dso *dso, enum map_type type); struct map *map__new2(u64 start, struct dso *dso);
void map__delete(struct map *map); void map__delete(struct map *map);
struct map *map__clone(struct map *map); struct map *map__clone(struct map *map);
...@@ -185,8 +175,6 @@ void map__fixup_end(struct map *map); ...@@ -185,8 +175,6 @@ void map__fixup_end(struct map *map);
void map__reloc_vmlinux(struct map *map); void map__reloc_vmlinux(struct map *map);
size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
FILE *fp);
void maps__insert(struct maps *maps, struct map *map); void maps__insert(struct maps *maps, struct map *map);
void maps__remove(struct maps *maps, struct map *map); void maps__remove(struct maps *maps, struct map *map);
struct map *maps__find(struct maps *maps, u64 addr); struct map *maps__find(struct maps *maps, u64 addr);
...@@ -197,33 +185,26 @@ struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, ...@@ -197,33 +185,26 @@ struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
void map_groups__init(struct map_groups *mg, struct machine *machine); void map_groups__init(struct map_groups *mg, struct machine *machine);
void map_groups__exit(struct map_groups *mg); void map_groups__exit(struct map_groups *mg);
int map_groups__clone(struct thread *thread, int map_groups__clone(struct thread *thread,
struct map_groups *parent, enum map_type type); struct map_groups *parent);
size_t map_groups__fprintf(struct map_groups *mg, FILE *fp); size_t map_groups__fprintf(struct map_groups *mg, FILE *fp);
int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name, int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name,
u64 addr); u64 addr);
static inline void map_groups__insert(struct map_groups *mg, struct map *map) static inline void map_groups__insert(struct map_groups *mg, struct map *map)
{ {
maps__insert(&mg->maps[map->type], map); maps__insert(&mg->maps, map);
map->groups = mg; map->groups = mg;
} }
static inline void map_groups__remove(struct map_groups *mg, struct map *map) static inline void map_groups__remove(struct map_groups *mg, struct map *map)
{ {
maps__remove(&mg->maps[map->type], map); maps__remove(&mg->maps, map);
}
static inline struct map *__map_groups__find(struct map_groups *mg,
enum map_type type, u64 addr)
{
return maps__find(&mg->maps[type], addr);
} }
static inline struct map *map_groups__find(struct map_groups *mg, u64 addr) static inline struct map *map_groups__find(struct map_groups *mg, u64 addr)
{ {
struct map *map = __map_groups__find(mg, MAP__FUNCTION, addr); return maps__find(&mg->maps, addr);
return map ?: __map_groups__find(mg, MAP__VARIABLE, addr);
} }
struct map *map_groups__first(struct map_groups *mg); struct map *map_groups__first(struct map_groups *mg);
...@@ -234,11 +215,9 @@ static inline struct map *map_groups__next(struct map *map) ...@@ -234,11 +215,9 @@ static inline struct map *map_groups__next(struct map *map)
} }
struct symbol *map_groups__find_symbol(struct map_groups *mg, struct symbol *map_groups__find_symbol(struct map_groups *mg,
enum map_type type, u64 addr, u64 addr, struct map **mapp);
struct map **mapp);
struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
enum map_type type,
const char *name, const char *name,
struct map **mapp); struct map **mapp);
...@@ -250,18 +229,13 @@ static inline ...@@ -250,18 +229,13 @@ static inline
struct symbol *map_groups__find_function_by_name(struct map_groups *mg, struct symbol *map_groups__find_function_by_name(struct map_groups *mg,
const char *name, struct map **mapp) const char *name, struct map **mapp)
{ {
return map_groups__find_symbol_by_name(mg, MAP__FUNCTION, name, mapp); return map_groups__find_symbol_by_name(mg, name, mapp);
} }
int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
FILE *fp); FILE *fp);
struct map *__map_groups__find_by_name(struct map_groups *mg, enum map_type type, const char *name); struct map *map_groups__find_by_name(struct map_groups *mg, const char *name);
static inline struct map *map_groups__find_by_name(struct map_groups *mg, const char *name)
{
return __map_groups__find_by_name(mg, MAP__FUNCTION, name);
}
bool __map__is_kernel(const struct map *map); bool __map__is_kernel(const struct map *map);
......
...@@ -3503,19 +3503,18 @@ int show_available_funcs(const char *target, struct nsinfo *nsi, ...@@ -3503,19 +3503,18 @@ int show_available_funcs(const char *target, struct nsinfo *nsi,
(target) ? : "kernel"); (target) ? : "kernel");
goto end; goto end;
} }
if (!dso__sorted_by_name(map->dso, map->type)) if (!dso__sorted_by_name(map->dso))
dso__sort_by_name(map->dso, map->type); dso__sort_by_name(map->dso);
/* Show all (filtered) symbols */ /* Show all (filtered) symbols */
setup_pager(); setup_pager();
for (nd = rb_first(&map->dso->symbol_names[map->type]); nd; nd = rb_next(nd)) { for (nd = rb_first(&map->dso->symbol_names); nd; nd = rb_next(nd)) {
struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
if (strfilter__compare(_filter, pos->sym.name)) if (strfilter__compare(_filter, pos->sym.name))
printf("%s\n", pos->sym.name); printf("%s\n", pos->sym.name);
} }
end: end:
map__put(map); map__put(map);
exit_probe_symbol_maps(); exit_probe_symbol_maps();
......
...@@ -1973,12 +1973,11 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg) ...@@ -1973,12 +1973,11 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg)
return false; return false;
} }
int maps__set_kallsyms_ref_reloc_sym(struct map **maps, int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name, u64 addr)
const char *symbol_name, u64 addr)
{ {
char *bracket; char *bracket;
int i;
struct ref_reloc_sym *ref; struct ref_reloc_sym *ref;
struct kmap *kmap;
ref = zalloc(sizeof(struct ref_reloc_sym)); ref = zalloc(sizeof(struct ref_reloc_sym));
if (ref == NULL) if (ref == NULL)
...@@ -1996,13 +1995,9 @@ int maps__set_kallsyms_ref_reloc_sym(struct map **maps, ...@@ -1996,13 +1995,9 @@ int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
ref->addr = addr; ref->addr = addr;
for (i = 0; i < MAP__NR_TYPES; ++i) { kmap = map__kmap(map);
struct kmap *kmap = map__kmap(maps[i]); if (kmap)
if (!kmap)
continue;
kmap->ref_reloc_sym = ref; kmap->ref_reloc_sym = ref;
}
return 0; return 0;
} }
......
...@@ -114,16 +114,9 @@ static inline int elf_sym__is_label(const GElf_Sym *sym) ...@@ -114,16 +114,9 @@ static inline int elf_sym__is_label(const GElf_Sym *sym)
sym->st_shndx != SHN_ABS; sym->st_shndx != SHN_ABS;
} }
static bool elf_sym__is_a(GElf_Sym *sym, enum map_type type) static bool elf_sym__filter(GElf_Sym *sym)
{ {
switch (type) { return elf_sym__is_function(sym) || elf_sym__is_object(sym);
case MAP__FUNCTION:
return elf_sym__is_function(sym);
case MAP__VARIABLE:
return elf_sym__is_object(sym);
default:
return false;
}
} }
static inline const char *elf_sym__name(const GElf_Sym *sym, static inline const char *elf_sym__name(const GElf_Sym *sym,
...@@ -150,17 +143,10 @@ static inline bool elf_sec__is_data(const GElf_Shdr *shdr, ...@@ -150,17 +143,10 @@ static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
return strstr(elf_sec__name(shdr, secstrs), "data") != NULL; return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
} }
static bool elf_sec__is_a(GElf_Shdr *shdr, Elf_Data *secstrs, static bool elf_sec__filter(GElf_Shdr *shdr, Elf_Data *secstrs)
enum map_type type)
{ {
switch (type) { return elf_sec__is_text(shdr, secstrs) ||
case MAP__FUNCTION: elf_sec__is_data(shdr, secstrs);
return elf_sec__is_text(shdr, secstrs);
case MAP__VARIABLE:
return elf_sec__is_data(shdr, secstrs);
default:
return false;
}
} }
static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr) static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
...@@ -256,7 +242,7 @@ static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name) ...@@ -256,7 +242,7 @@ static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name)
* And always look at the original dso, not at debuginfo packages, that * And always look at the original dso, not at debuginfo packages, that
* have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS). * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
*/ */
int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *map) int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss)
{ {
uint32_t nr_rel_entries, idx; uint32_t nr_rel_entries, idx;
GElf_Sym sym; GElf_Sym sym;
...@@ -369,7 +355,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * ...@@ -369,7 +355,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *
goto out_elf_end; goto out_elf_end;
plt_offset += plt_entry_size; plt_offset += plt_entry_size;
symbols__insert(&dso->symbols[map->type], f); symbols__insert(&dso->symbols, f);
++nr; ++nr;
} }
} else if (shdr_rel_plt.sh_type == SHT_REL) { } else if (shdr_rel_plt.sh_type == SHT_REL) {
...@@ -395,7 +381,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * ...@@ -395,7 +381,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *
goto out_elf_end; goto out_elf_end;
plt_offset += plt_entry_size; plt_offset += plt_entry_size;
symbols__insert(&dso->symbols[map->type], f); symbols__insert(&dso->symbols, f);
++nr; ++nr;
} }
} }
...@@ -844,7 +830,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, ...@@ -844,7 +830,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
* have the wrong values for the dso maps, so remove them. * have the wrong values for the dso maps, so remove them.
*/ */
if (kmodule && syms_ss->symtab) if (kmodule && syms_ss->symtab)
symbols__delete(&dso->symbols[map->type]); symbols__delete(&dso->symbols);
if (!syms_ss->symtab) { if (!syms_ss->symtab) {
/* /*
...@@ -936,7 +922,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, ...@@ -936,7 +922,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
const char *section_name; const char *section_name;
bool used_opd = false; bool used_opd = false;
if (!is_label && !elf_sym__is_a(&sym, map->type)) if (!is_label && !elf_sym__filter(&sym))
continue; continue;
/* Reject ARM ELF "mapping symbols": these aren't unique and /* Reject ARM ELF "mapping symbols": these aren't unique and
...@@ -974,7 +960,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, ...@@ -974,7 +960,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
gelf_getshdr(sec, &shdr); gelf_getshdr(sec, &shdr);
if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type)) if (is_label && !elf_sec__filter(&shdr, secstrs))
continue; continue;
section_name = elf_sec__name(&shdr, secstrs); section_name = elf_sec__name(&shdr, secstrs);
...@@ -1042,7 +1028,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, ...@@ -1042,7 +1028,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
snprintf(dso_name, sizeof(dso_name), snprintf(dso_name, sizeof(dso_name),
"%s%s", dso->short_name, section_name); "%s%s", dso->short_name, section_name);
curr_map = __map_groups__find_by_name(kmaps, map->type, dso_name); curr_map = map_groups__find_by_name(kmaps, dso_name);
if (curr_map == NULL) { if (curr_map == NULL) {
u64 start = sym.st_value; u64 start = sym.st_value;
...@@ -1055,8 +1041,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, ...@@ -1055,8 +1041,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
curr_dso->kernel = dso->kernel; curr_dso->kernel = dso->kernel;
curr_dso->long_name = dso->long_name; curr_dso->long_name = dso->long_name;
curr_dso->long_name_len = dso->long_name_len; curr_dso->long_name_len = dso->long_name_len;
curr_map = map__new2(start, curr_dso, curr_map = map__new2(start, curr_dso);
map->type);
dso__put(curr_dso); dso__put(curr_dso);
if (curr_map == NULL) { if (curr_map == NULL) {
goto out_elf_end; goto out_elf_end;
...@@ -1081,7 +1066,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, ...@@ -1081,7 +1066,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
dsos__add(&map->groups->machine->dsos, curr_dso); dsos__add(&map->groups->machine->dsos, curr_dso);
/* kmaps already got it */ /* kmaps already got it */
map__put(curr_map); map__put(curr_map);
dso__set_loaded(curr_dso, map->type); dso__set_loaded(curr_dso);
} else } else
curr_dso = curr_map->dso; curr_dso = curr_map->dso;
...@@ -1110,7 +1095,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, ...@@ -1110,7 +1095,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
arch__sym_update(f, &sym); arch__sym_update(f, &sym);
__symbols__insert(&curr_dso->symbols[curr_map->type], f, dso->kernel); __symbols__insert(&curr_dso->symbols, f, dso->kernel);
nr++; nr++;
} }
...@@ -1118,14 +1103,14 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, ...@@ -1118,14 +1103,14 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
* For misannotated, zeroed, ASM function sizes. * For misannotated, zeroed, ASM function sizes.
*/ */
if (nr > 0) { if (nr > 0) {
symbols__fixup_end(&dso->symbols[map->type]); symbols__fixup_end(&dso->symbols);
symbols__fixup_duplicate(&dso->symbols[map->type]); symbols__fixup_duplicate(&dso->symbols);
if (kmap) { if (kmap) {
/* /*
* We need to fixup this here too because we create new * We need to fixup this here too because we create new
* maps here, for things like vsyscall sections. * maps here, for things like vsyscall sections.
*/ */
__map_groups__fixup_end(kmaps, map->type); map_groups__fixup_end(kmaps);
} }
} }
err = nr; err = nr;
......
...@@ -288,8 +288,7 @@ void symsrc__destroy(struct symsrc *ss) ...@@ -288,8 +288,7 @@ void symsrc__destroy(struct symsrc *ss)
} }
int dso__synthesize_plt_symbols(struct dso *dso __maybe_unused, int dso__synthesize_plt_symbols(struct dso *dso __maybe_unused,
struct symsrc *ss __maybe_unused, struct symsrc *ss __maybe_unused)
struct map *map __maybe_unused)
{ {
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -260,16 +260,11 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map, ...@@ -260,16 +260,11 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
bool no_kcore); bool no_kcore);
int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map); int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map);
void dso__insert_symbol(struct dso *dso, enum map_type type, void dso__insert_symbol(struct dso *dso,
struct symbol *sym); struct symbol *sym);
struct symbol *__dso__find_symbol(struct dso *dso, enum map_type type, u64 addr); struct symbol *dso__find_symbol(struct dso *dso, u64 addr);
struct symbol *__dso__find_symbol_by_name(struct dso *dso, enum map_type type, const char *name); struct symbol *dso__find_symbol_by_name(struct dso *dso, const char *name);
static inline struct symbol *dso__find_symbol(struct dso *dso, u64 addr)
{
return __dso__find_symbol(dso, MAP__FUNCTION, addr);
}
struct symbol *symbol__next_by_name(struct symbol *sym); struct symbol *symbol__next_by_name(struct symbol *sym);
...@@ -312,8 +307,7 @@ int symbol__config_symfs(const struct option *opt __maybe_unused, ...@@ -312,8 +307,7 @@ int symbol__config_symfs(const struct option *opt __maybe_unused,
int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
struct symsrc *runtime_ss, int kmodule); struct symsrc *runtime_ss, int kmodule);
int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss);
struct map *map);
char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name); char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name);
...@@ -321,7 +315,7 @@ void __symbols__insert(struct rb_root *symbols, struct symbol *sym, bool kernel) ...@@ -321,7 +315,7 @@ void __symbols__insert(struct rb_root *symbols, struct symbol *sym, bool kernel)
void symbols__insert(struct rb_root *symbols, struct symbol *sym); void symbols__insert(struct rb_root *symbols, struct symbol *sym);
void symbols__fixup_duplicate(struct rb_root *symbols); void symbols__fixup_duplicate(struct rb_root *symbols);
void symbols__fixup_end(struct rb_root *symbols); void symbols__fixup_end(struct rb_root *symbols);
void __map_groups__fixup_end(struct map_groups *mg, enum map_type type); void map_groups__fixup_end(struct map_groups *mg);
typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data); typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data);
int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data, int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
......
...@@ -58,13 +58,13 @@ size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp) ...@@ -58,13 +58,13 @@ size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
} }
size_t dso__fprintf_symbols_by_name(struct dso *dso, size_t dso__fprintf_symbols_by_name(struct dso *dso,
enum map_type type, FILE *fp) FILE *fp)
{ {
size_t ret = 0; size_t ret = 0;
struct rb_node *nd; struct rb_node *nd;
struct symbol_name_rb_node *pos; struct symbol_name_rb_node *pos;
for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) { for (nd = rb_first(&dso->symbol_names); nd; nd = rb_next(nd)) {
pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
fprintf(fp, "%s\n", pos->sym.name); fprintf(fp, "%s\n", pos->sym.name);
} }
......
...@@ -302,23 +302,20 @@ int thread__insert_map(struct thread *thread, struct map *map) ...@@ -302,23 +302,20 @@ int thread__insert_map(struct thread *thread, struct map *map)
static int __thread__prepare_access(struct thread *thread) static int __thread__prepare_access(struct thread *thread)
{ {
bool initialized = false; bool initialized = false;
int i, err = 0; int err = 0;
struct maps *maps = &thread->mg->maps;
for (i = 0; i < MAP__NR_TYPES; ++i) { struct map *map;
struct maps *maps = &thread->mg->maps[i];
struct map *map;
down_read(&maps->lock); down_read(&maps->lock);
for (map = maps__first(maps); map; map = map__next(map)) { for (map = maps__first(maps); map; map = map__next(map)) {
err = unwind__prepare_access(thread, map, &initialized); err = unwind__prepare_access(thread, map, &initialized);
if (err || initialized) if (err || initialized)
break; break;
}
up_read(&maps->lock);
} }
up_read(&maps->lock);
return err; return err;
} }
...@@ -335,8 +332,6 @@ static int thread__prepare_access(struct thread *thread) ...@@ -335,8 +332,6 @@ static int thread__prepare_access(struct thread *thread)
static int thread__clone_map_groups(struct thread *thread, static int thread__clone_map_groups(struct thread *thread,
struct thread *parent) struct thread *parent)
{ {
int i;
/* This is new thread, we share map groups for process. */ /* This is new thread, we share map groups for process. */
if (thread->pid_ == parent->pid_) if (thread->pid_ == parent->pid_)
return thread__prepare_access(thread); return thread__prepare_access(thread);
...@@ -348,9 +343,8 @@ static int thread__clone_map_groups(struct thread *thread, ...@@ -348,9 +343,8 @@ static int thread__clone_map_groups(struct thread *thread,
} }
/* But this one is new process, copy maps. */ /* But this one is new process, copy maps. */
for (i = 0; i < MAP__NR_TYPES; ++i) if (map_groups__clone(thread, parent->mg) < 0)
if (map_groups__clone(thread, parent->mg, i) < 0) return -ENOMEM;
return -ENOMEM;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment