Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dereference member from struct #4317

Open
rockrid3r opened this issue Mar 2, 2024 · 4 comments
Open

Dereference member from struct #4317

rockrid3r opened this issue Mar 2, 2024 · 4 comments

Comments

@rockrid3r
Copy link
Contributor

Is your feature request related to a problem? Please describe.
Working on #4257 currently. It is useful to be able to get offset from base type to it's member. For if we want to read b from this struct:

struct A {
    int a;
    int b;
}

we should calculate it's offset from A based on the type info of A.

There are many different structs and many different members in #4257 that needs to be processed like this. So a whole new feature dedicated specifically to this task will be useful.

Describe the solution you'd like
The simple rz_vector_foreach(btype->struct_data.members, memb_iter) will not work (generally). For example, for this struct:

struct A {
    struct {
        int b;
    }
} a;

you can do this: a->b.

So if we consider our struct as tree, then:

  • non-anonymous members are leaves
  • anonymous members are nodes, which should be investigated further!

BFS/DFS problem as I see it. Comments are welcome!

@XVilka
Copy link
Member

XVilka commented Mar 2, 2024

It is already implemented if I understood the question right - see functions from librz/type/path.c

@rockrid3r
Copy link
Contributor Author

rockrid3r commented Mar 2, 2024

Thanks, didn't see this. Still the code (taken from librz/type/path.c)

RZ_API ut64 rz_type_db_struct_member_offset(RZ_NONNULL const RzTypeDB *typedb, RZ_NONNULL const char *name, RZ_NONNULL const char *member) {
	rz_return_val_if_fail(typedb && name && member, 0);
	RzBaseType *btype = rz_type_db_get_base_type(typedb, name);
	if (!btype || btype->kind != RZ_BASE_TYPE_KIND_STRUCT) {
		return 0;
	}
	RzTypeStructMember *memb;
	rz_vector_foreach(&btype->struct_data.members, memb) {
		if (!strcmp(memb->name, member)) {
			return memb->offset;
		}
	}
	return 0;
}

won't work with the described test case:

struct A {
    struct {
        int b;
    }
} a;

because struct A has only 1 member: anonymous struct. This code won't reach b.

@XVilka
Copy link
Member

XVilka commented Mar 2, 2024

Ah, yes, currently there is no support for anonymous structs in type paths. I am not sure if ti worth implementing because it will create unnecessary ambiguity. Keep in mind, all features in Rizin are for the reverse engineering. Simply omitting types in type paths might create confusion in some cases. We can produce something like that instead:
a->(anonymous struct 0)->b.

@rockrid3r
Copy link
Contributor Author

Ok, somewhat agree here. Maybe we shouldn't close the issue though.

C keeps that somewhat strict. This

struct A {
    struct {
        int b;
    };
    int b;
} a;

won't compile with error duplicate member 'b'. (I've ran gcc on this).

But I didn't test it that much. Maybe there are some confusions, not sure.

I will implement it locally in code for #4257 and see if it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants