|
@@ -29,6 +29,7 @@ void map__init(struct map *self, enum map_type type,
|
|
|
self->unmap_ip = map__unmap_ip;
|
|
|
RB_CLEAR_NODE(&self->rb_node);
|
|
|
self->groups = NULL;
|
|
|
+ self->referenced = false;
|
|
|
}
|
|
|
|
|
|
struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
|
|
@@ -387,6 +388,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
|
|
|
{
|
|
|
struct rb_root *root = &self->maps[map->type];
|
|
|
struct rb_node *next = rb_first(root);
|
|
|
+ int err = 0;
|
|
|
|
|
|
while (next) {
|
|
|
struct map *pos = rb_entry(next, struct map, rb_node);
|
|
@@ -402,12 +404,6 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
|
|
|
}
|
|
|
|
|
|
rb_erase(&pos->rb_node, root);
|
|
|
- /*
|
|
|
- * We may have references to this map, for instance in some
|
|
|
- * hist_entry instances, so just move them to a separate
|
|
|
- * list.
|
|
|
- */
|
|
|
- list_add_tail(&pos->node, &self->removed_maps[map->type]);
|
|
|
/*
|
|
|
* Now check if we need to create new maps for areas not
|
|
|
* overlapped by the new map:
|
|
@@ -415,8 +411,10 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
|
|
|
if (map->start > pos->start) {
|
|
|
struct map *before = map__clone(pos);
|
|
|
|
|
|
- if (before == NULL)
|
|
|
- return -ENOMEM;
|
|
|
+ if (before == NULL) {
|
|
|
+ err = -ENOMEM;
|
|
|
+ goto move_map;
|
|
|
+ }
|
|
|
|
|
|
before->end = map->start - 1;
|
|
|
map_groups__insert(self, before);
|
|
@@ -427,14 +425,27 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
|
|
|
if (map->end < pos->end) {
|
|
|
struct map *after = map__clone(pos);
|
|
|
|
|
|
- if (after == NULL)
|
|
|
- return -ENOMEM;
|
|
|
+ if (after == NULL) {
|
|
|
+ err = -ENOMEM;
|
|
|
+ goto move_map;
|
|
|
+ }
|
|
|
|
|
|
after->start = map->end + 1;
|
|
|
map_groups__insert(self, after);
|
|
|
if (verbose >= 2)
|
|
|
map__fprintf(after, fp);
|
|
|
}
|
|
|
+move_map:
|
|
|
+ /*
|
|
|
+ * If we have references, just move them to a separate list.
|
|
|
+ */
|
|
|
+ if (pos->referenced)
|
|
|
+ list_add_tail(&pos->node, &self->removed_maps[map->type]);
|
|
|
+ else
|
|
|
+ map__delete(pos);
|
|
|
+
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -506,6 +517,11 @@ void maps__insert(struct rb_root *maps, struct map *map)
|
|
|
rb_insert_color(&map->rb_node, maps);
|
|
|
}
|
|
|
|
|
|
+void maps__remove(struct rb_root *self, struct map *map)
|
|
|
+{
|
|
|
+ rb_erase(&map->rb_node, self);
|
|
|
+}
|
|
|
+
|
|
|
struct map *maps__find(struct rb_root *maps, u64 ip)
|
|
|
{
|
|
|
struct rb_node **p = &maps->rb_node;
|
|
@@ -551,13 +567,6 @@ static void dsos__delete(struct list_head *self)
|
|
|
|
|
|
void machine__exit(struct machine *self)
|
|
|
{
|
|
|
- struct kmap *kmap = map__kmap(self->vmlinux_maps[MAP__FUNCTION]);
|
|
|
-
|
|
|
- if (kmap->ref_reloc_sym) {
|
|
|
- free((char *)kmap->ref_reloc_sym->name);
|
|
|
- free(kmap->ref_reloc_sym);
|
|
|
- }
|
|
|
-
|
|
|
map_groups__exit(&self->kmaps);
|
|
|
dsos__delete(&self->user_dsos);
|
|
|
dsos__delete(&self->kernel_dsos);
|
|
@@ -565,6 +574,12 @@ void machine__exit(struct machine *self)
|
|
|
self->root_dir = NULL;
|
|
|
}
|
|
|
|
|
|
+void machine__delete(struct machine *self)
|
|
|
+{
|
|
|
+ machine__exit(self);
|
|
|
+ free(self);
|
|
|
+}
|
|
|
+
|
|
|
struct machine *machines__add(struct rb_root *self, pid_t pid,
|
|
|
const char *root_dir)
|
|
|
{
|