Skip to content

Commit

Permalink
Made some progress on the pid hash case, code is still a mess, have f…
Browse files Browse the repository at this point in the history
…ixed many bugs but still not 100% working
  • Loading branch information
Svetlitski committed Dec 7, 2021
1 parent 3d41960 commit cadd964
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 6 deletions.
78 changes: 74 additions & 4 deletions libdrgn/iterators.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,40 @@ struct drgn_error *pid_iter_init(struct drgn_program *prog,
goto out;
} else if (err->code == DRGN_ERROR_LOOKUP) {
ret->has_idr = false;
// TODO: pid_hash case
ret->index = -1;
ret->ns = ns;
drgn_object_init(&ret->hlist_node, prog);
ret->hlist_node.value.bufp = NULL;
drgn_object_init(&ret->pid_hash, prog);
drgn_object_init(&ret->entry, prog);
err = drgn_program_find_object(prog, "pid_hash", NULL, DRGN_FIND_OBJECT_VARIABLE, &ret->pid_hash);
if (err)
goto out;
err = drgn_program_find_type(prog, "struct pid", NULL,
&ret->pid_type);
if (err)
goto out;
err = drgn_program_find_type(prog, "struct upid", NULL,
&ret->upid_type);
if (err)
goto out;
struct drgn_object ns_level;
drgn_object_init(&ns_level, prog);
err = drgn_object_member_dereference(&ns_level, ns, "level");
if (err)
goto out;
err = drgn_object_read_unsigned(&ns_level, &ret->ns_level);
if (err)
goto out;
struct drgn_object pidhash_shift;
drgn_object_init(&pidhash_shift, prog);
err = drgn_program_find_object(prog, "pidhash_shift", NULL, DRGN_FIND_OBJECT_VARIABLE, &pidhash_shift);
if (err)
goto out;
err = drgn_object_read_unsigned(&pidhash_shift, &ret->hash_length);
if (err)
goto out;
ret->hash_length = 1 << ret->hash_length;
} else {
goto out;
}
Expand All @@ -268,9 +301,10 @@ struct drgn_error *pid_iter_init(struct drgn_program *prog,

struct drgn_error *pid_iter_next(struct pid_iter *iter, pid_iter_entry_t **ret)
{
struct drgn_error *err;
if (iter->has_idr) {
idr_iter_entry_t *entry;
struct drgn_error *err = idr_iter_next(&iter->iter, &entry);
err = idr_iter_next(&iter->iter, &entry);
if (err)
return err;
if (!entry) {
Expand All @@ -283,9 +317,45 @@ struct drgn_error *pid_iter_next(struct pid_iter *iter, pid_iter_entry_t **ret)
*ret = &entry->node;
return err;
} else {
//TODO
return NULL;
while (true) {
if (iter->index != -1 && iter->index >= iter->hash_length) {
*ret = NULL;
return NULL;
}
if (!iter->hlist_node.value.bufp) {
err = drgn_object_subscript(&iter->hlist_node, &iter->pid_hash, ++iter->index);
if (err)
return err;
err = drgn_object_member(&iter->hlist_node, &iter->hlist_node, "first");
if (err)
return err;
} else {
err = drgn_object_member(&iter->hlist_node, &iter->hlist_node, "next");
if (err)
return err;
}
err = drgn_object_container_of(&iter->entry, &iter->hlist_node, iter->upid_type, "pid_chain");
if (err)
return err;
struct drgn_object upid_ns;
drgn_object_init(&upid_ns, drgn_object_program(&iter->entry));
err = drgn_object_member_dereference(&upid_ns, &iter->entry, "ns");
if (err)
return err;
// TODO: if upid.ns == ns
if (upid_ns.value.bufp != iter->ns->value.bufp)
continue;
char* member;
// TODO do this at init and save it to iter->member or something
asprintf(&member, "numbers[%lu]", iter->ns_level);
err = drgn_object_container_of(&iter->entry, &iter->entry, iter->pid_type, member);
if (err)
return err;
*ret = &iter->entry;
break;
}
}
return NULL;
}

struct drgn_error *task_iter_init(struct drgn_program *prog,
Expand Down
9 changes: 7 additions & 2 deletions libdrgn/iterators.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,20 @@ typedef struct drgn_object pid_iter_entry_t;

struct pid_iter {
bool has_idr;
struct drgn_qualified_type pid_type;
union {
struct {
struct idr_iter iter;
struct drgn_qualified_type pid_type;
};
struct {
struct drgn_object* ns;
pid_iter_entry_t entry;
struct drgn_object pid_hash;
uint64_t pid_hash_shift;
struct drgn_object hlist_node;
struct drgn_qualified_type upid_type;
size_t hash_length;
int index;
uint64_t ns_level;
};
};
};
Expand Down

0 comments on commit cadd964

Please sign in to comment.