[CLASSES]: Rework the find_by routines

So that we can find all the cus for some specific class
(cus__find_class_by_name), or traverse all the CUs (cus__for_each_cu),
etc.

Now we don't look at just the first CU in multi-CU files (vmlinux, etc).

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2006-10-31 17:23:16 -03:00
parent 0ca9826e36
commit 5aaca80de6
4 changed files with 109 additions and 76 deletions

View File

@ -61,7 +61,7 @@ static const char *tag_name(const unsigned int tag)
return "";
}
struct class *cu__find_by_name(struct cu *self, const char *name)
struct class *cu__find_class_by_name(struct cu *self, const char *name)
{
struct class *pos;
@ -72,22 +72,27 @@ struct class *cu__find_by_name(struct cu *self, const char *name)
return NULL;
}
struct class *cu__find_by_id(const struct cu *self, const unsigned int id)
struct class *cus__find_class_by_name(struct cu **cu, const char *name)
{
struct class *pos;
struct cu *cu_pos;
list_for_each_entry(pos, &self->classes, node)
if (pos->id == id)
return pos;
list_for_each_entry(cu_pos, &cus__list, node) {
struct class *class = cu__find_class_by_name(cu_pos, name);
if (class != NULL) {
*cu = cu_pos;
return class;
}
}
return NULL;
}
struct cu *cus__find_by_id(const unsigned int id)
struct class *cu__find_class_by_id(const struct cu *self, const unsigned int id)
{
struct cu *pos;
struct class *pos;
list_for_each_entry(pos, &cus__list, node)
list_for_each_entry(pos, &self->classes, node)
if (pos->id == id)
return pos;
@ -100,7 +105,7 @@ static const unsigned long class__size(const struct class *self,
unsigned long size = self->size;
if (self->tag != DW_TAG_pointer_type && self->type != 0) {
struct class *class = cu__find_by_id(cu, self->type);
struct class *class = cu__find_class_by_id(cu, self->type);
if (class != NULL)
size = class__size(class, cu);
@ -119,7 +124,8 @@ static const char *class__name(struct class *self, const struct cu *cu,
if (self->type == 0) /* No type == void */
strncpy(bf, "void *", len);
else {
struct class *ptr_class = cu__find_by_id(cu, self->type);
struct class *ptr_class =
cu__find_class_by_id(cu, self->type);
if (ptr_class != NULL) {
char ptr_class_name[128];
@ -131,7 +137,7 @@ static const char *class__name(struct class *self, const struct cu *cu,
}
} else if (self->tag == DW_TAG_volatile_type ||
self->tag == DW_TAG_const_type) {
struct class *vol_class = cu__find_by_id(cu, self->type);
struct class *vol_class = cu__find_class_by_id(cu, self->type);
if (vol_class != NULL) {
char vol_class_name[128];
@ -143,7 +149,7 @@ static const char *class__name(struct class *self, const struct cu *cu,
sizeof(vol_class_name)));
}
} else if (self->tag == DW_TAG_array_type) {
struct class *ptr_class = cu__find_by_id(cu, self->type);
struct class *ptr_class = cu__find_class_by_id(cu, self->type);
if (ptr_class != NULL)
return class__name(ptr_class, cu, bf, len);
@ -176,14 +182,14 @@ static struct class_member *class_member__new(uintmax_t type,
static int class_member__size(const struct class_member *self,
const struct cu *cu)
{
struct class *class = cu__find_by_id(cu, self->type);
struct class *class = cu__find_class_by_id(cu, self->type);
return class != NULL ? class__size(class, cu) : -1;
}
static unsigned long class_member__print(struct class_member *self,
const struct cu *cu)
{
struct class *class = cu__find_by_id(cu, self->type);
struct class *class = cu__find_class_by_id(cu, self->type);
char class_name_bf[128];
char member_name_bf[128];
char bf[512];
@ -200,7 +206,8 @@ static unsigned long class_member__print(struct class_member *self,
/* Is it a function pointer? */
if (class->tag == DW_TAG_pointer_type) {
struct class *ptr_class = cu__find_by_id(cu, class->type);
struct class *ptr_class =
cu__find_class_by_id(cu, class->type);
if (ptr_class != NULL &&
ptr_class->tag == DW_TAG_subroutine_type) {
@ -209,7 +216,8 @@ static unsigned long class_member__print(struct class_member *self,
strcpy(bf, "void");
else {
struct class *ret_class =
cu__find_by_id(cu, ptr_class->type);
cu__find_class_by_id(cu,
ptr_class->type);
if (ret_class != NULL)
class_name = class__name(ret_class, cu,
@ -324,7 +332,7 @@ static void class__print_function(struct class *self, const struct cu *cu)
if (self->type == 0)
type = "void";
else {
class_type = cu__find_by_id(cu, self->type);
class_type = cu__find_class_by_id(cu, self->type);
if (class_type != NULL)
type = class__name(class_type, cu, bf, sizeof(bf));
}
@ -336,7 +344,7 @@ static void class__print_function(struct class *self, const struct cu *cu)
else
first_parameter = 0;
type = "<ERROR>";
class_type = cu__find_by_id(cu, pos->type);
class_type = cu__find_class_by_id(cu, pos->type);
if (class_type != NULL)
type = class__name(class_type, cu, bf, sizeof(bf));
printf("%s %s", type, pos->name);
@ -417,18 +425,29 @@ void class__print(struct class *self, const struct cu *cu)
putchar('\n');
}
void classes__for_each(int (*iterator)(struct class *class, void *cookie),
void *cookie)
int cu__for_each_class(struct cu *cu,
int (*iterator)(struct cu *cu,
struct class *class,
void *cookie),
void *cookie)
{
struct cu *cu_pos;
list_for_each_entry(cu_pos, &cus__list, node) {
struct class *class_pos;
struct class *pos;
list_for_each_entry(class_pos, &cu_pos->classes, node)
if (iterator(class_pos, cookie))
break;
}
list_for_each_entry(pos, &cu->classes, node)
if (iterator(cu, pos, cookie))
return 1;
return 0;
}
void cus__for_each_cu(int (*iterator)(struct cu *cu, void *cookie),
void *cookie)
{
struct cu *pos;
list_for_each_entry(pos, &cus__list, node)
if (iterator(pos, cookie))
break;
}
void classes__print(const unsigned int tag)

View File

@ -53,13 +53,19 @@ extern void class__find_holes(struct class *self, const struct cu *cu);
extern void class__print(struct class *self, const struct cu *cu);
extern int classes__load(const char *filename);
extern struct cu *cus__find_by_id(const unsigned int type);
extern struct class *cu__find_by_id(struct cu *cu, const unsigned int type);
extern struct class *cu__find_by_name(struct cu *cu, const char *name);
extern struct cu *cus__find_cu_by_id(const unsigned int type);
extern struct class *cu__find_class_by_id(const struct cu *cu,
const unsigned int type);
extern struct class *cu__find_class_by_name(struct cu *cu, const char *name);
extern void classes__print(const unsigned int tag);
extern void classes__for_each(int (*iterator)(struct class *class,
struct cu *cu,
void *cookie),
extern struct class *cus__find_class_by_name(struct cu **cu, const char *name);
extern int cu__for_each_class(struct cu *cu,
int (*iterator)(struct cu *cu,
struct class *class,
void *cookie),
void *cookie);
extern void cus__for_each_cu(int (*iterator)(struct cu *cu,
void *cookie),
void *cookie);
#endif /* _PAHOLE_CLASSES_H_ */

View File

@ -30,17 +30,13 @@ int main(int argc, char *argv[])
if (argc == 2)
classes__print(DW_TAG_structure_type);
else {
struct cu *cu = cus__find_by_id(0);
if (cu != NULL) {
struct class *class = cu__find_by_name(argv[2]);
if (class != NULL) {
class__find_holes(class, cu);
class__print(class, cu);
} else
printf("struct %s not found!\n", argv[2]);
struct cu *cu;
struct class *class = cus__find_class_by_name(&cu, argv[2]);
if (class != NULL) {
class__find_holes(class, cu);
class__print(class, cu);
} else
printf("cu 0 not found!\n");
printf("struct %s not found!\n", argv[2]);
}
return EXIT_SUCCESS;

View File

@ -40,10 +40,10 @@ static int class__has_parameter_of_type(struct cu *cu, struct class *self,
struct class_member *pos;
list_for_each_entry(pos, &self->members, node) {
struct class *class = cu__find_by_id(cu, pos->type);
struct class *class = cu__find_class_by_id(cu, pos->type);
if (class != NULL && class->tag == DW_TAG_pointer_type) {
class = cu__find_by_id(cu, class->type);
class = cu__find_class_by_id(cu, class->type);
if (class != NULL &&
class->id == target->id)
return 1;
@ -52,7 +52,7 @@ static int class__has_parameter_of_type(struct cu *cu, struct class *self,
return 0;
}
static int class_iterator(struct class *class, struct cu *cu, void *cookie)
static int class_iterator(struct cu *cu, struct class *class, void *cookie)
{
if (class->tag != DW_TAG_subprogram || class->inlined)
return 0;
@ -66,7 +66,17 @@ static int class_iterator(struct class *class, struct cu *cu, void *cookie)
return 0;
}
static int sizes_iterator(struct class *class, struct cu *cu, void *cookie)
static int cu_class_iterator(struct cu *cu, void *cookie)
{
struct class *target = cu__find_class_by_name(cu, cookie);
if (target == NULL)
return 0;
return cu__for_each_class(cu, class_iterator, target);
}
static int sizes_iterator(struct cu *cu, struct class *class, void *cookie)
{
if (class->tag != DW_TAG_subprogram || class->inlined)
return 0;
@ -75,12 +85,34 @@ static int sizes_iterator(struct class *class, struct cu *cu, void *cookie)
return 0;
}
static int cu_sizes_iterator(struct cu *cu, void *cookie)
{
return cu__for_each_class(cu, sizes_iterator, cookie);
}
static int function_iterator(struct cu *cu, struct class *class, void *cookie)
{
if (class->tag != DW_TAG_subprogram || class->inlined)
return 0;
if (strcmp(class->name, cookie) == 0) {
class__print(class, cu);
return 1;
}
return 0;
}
static int cu_function_iterator(struct cu *cu, void *cookie)
{
return cu__for_each_class(cu, function_iterator, cookie);
}
int main(int argc, char *argv[])
{
int option, option_index;
const char *file_name = NULL;
const char *class_name = NULL;
const char *function_name = NULL;
char *class_name = NULL;
char *function_name = NULL;
int show_sizes = 0;
while ((option = getopt_long(argc, argv, "c:sV",
@ -108,33 +140,13 @@ int main(int argc, char *argv[])
}
if (show_sizes)
classes__for_each(sizes_iterator, NULL);
else if (class_name != NULL) {
struct cu *cu = cus__find_by_id(0);
if (cu != NULL) {
struct class *class = cu__find_by_name(cu, class_name);
if (class != NULL)
classes__for_each(class_iterator, class);
else
printf("class %s not found!\n", class_name);
} else
printf("cu 0 not found!\n");
} else if (function_name == NULL)
cus__for_each_cu(cu_sizes_iterator, NULL);
else if (class_name != NULL)
cus__for_each_cu(cu_class_iterator, class_name);
else if (function_name == NULL)
classes__print(DW_TAG_subprogram);
else {
struct cu *cu = cus__find_by_id(0);
if (cu != NULL) {
struct class *class = cu__find_by_name(cu, function_name);
if (class != NULL)
class__print(class, cu);
else
printf("function %s not found!\n", function_name);
} else
printf("cu 0 not found!\n");
}
else
cus__for_each_cu(cu_function_iterator, function_name);
return EXIT_SUCCESS;
}