Improvements of the `database.types` namespace like serializing a local type as a graph.
There's a lot of type information stashed away in the "ida_typeinf" module specifically for dealing with C and C++ types. Some of this is already exposed via the member_t.typeinfo member in the structure module, or the default functions for the database.type and function.type namespaces, but enumeration and customization is still pretty limited.
It would be pretty handy to expose interacting with the idaapi.tinfo_t and the idaapi.til_t library using the database.types namespace. The idaapi.tinfo_t includes a tinfo_t.serialize method which can be used to construct a type with tinfo_t.deserialize, but not all information (like names and field comments) is persisted. Instead of using these APIs, it would be better to use idaapi.get_numbered_type, and idaapi.set_numbered_type instead. Unfortunately, growing the types database requires other APIs like idaapi.alloc_type_ordinals.
Anyways, this way the exchanging of type information between databases can be greatly simplified.
When copying structures/unions/enums, the id numbers that are being serialized for members will need to be kept track of in some way as moving them between databases will break their references.
A preliminary namespace for database.types was added by commit e665422bfd0e295efc0fe213cbad5712a23dabe7.
This was partially handled by commit d5abb9a5fbc38f15d2f735d335a274b6c7fbf7e0 which introduces flags that can allow you to distinguish between aliases (typedef), integers, pointers, and complex types.
I don't know if I'll ever index this or anything for searching because it's still a dead API to me, but the next iteration of this could allow you to serialize and deserialize a local type and all of its dependencies. This would probably require me to traverse the type in order to capture its dependencies in a graph and then that way it can be unloaded into a new database. The hacky way of doing this is to use print_decls (or whatever it's called), but it has name constraints and the definitions are not guaranteed since ordinals might get used.
As per #158, the database.types namespace is pretty complete and allows support for interacting with the different available type libraries in a database. The best way (as always) to share types with another database is actually through "tags". If a database does not have the base type that you require, you can just use database.types.add(name) to create an empty type ( which Hex-Rays does by default anyways).
A quick way to list all of the unknown types in your database is to do:
Python> db.types.list(defined=False)
WARNING:root:database.types.__iterate__(<ida_typeinf.til_t; <Local type definitions>>) : Skipping the type at the current ordinal (139) due to it having been deleted.
[181] +0x0 : ?T-- : CjxFilerConnect
This, if you need to share unknown types with all your databases you can just do:
names = [name for ordinal, name, tinfo in db.types.iterate(defined=False)]
and then to create the necessary placeholders.
[db.types.add(name) for name in names]
After you have the local types, you can use them however you want. To bring their contents in, you can just pickle the structure that's related to the type that you want and then unpickle it directly in the database. (If the names match, it will be connected).
ti = db.types.by(name)
if struc.has(ti):
st = struc.by(ti)
print(pickle.dumps(st))
else:
print('no structure found for {!s}'.format(ti)
Closing this issue as it doesn't make sense to completely parse and serialize type information since you can already exchange types with other databases, and you can also use other databases as type libraries