mtag: introduce memory tags
commitf6bdb9a759809edb96e61f601ba73c2124ccb7ed
authorDan Carpenter <dan.carpenter@oracle.com>
Wed, 22 Nov 2017 11:02:28 +0000 (22 14:02 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Wed, 22 Nov 2017 11:18:40 +0000 (22 14:18 +0300)
tree735f6c78f626fa7e063882fc354a69bbb59ab001
parent894cc5eac09953253addff00ff93a1acdd75ed65
mtag: introduce memory tags

Smatch has a bunch of somewhat duplicative and half implemented ways to
describe memory in the DB.  I haven't finished implementing it, or
committed it yet, but there is a type_info table which is supposed to
store information about struct member like (struct foo)->bar is user data,
or is in byte units.  We also that the type_value data which is pretty
useful.  Then there is the local_values which is pretty incomplete and
rubbish, I'm going to just delete it without investigating much further.
Then we have the data_info, which kind of duplicates local_values but it
also has a bunch of things like (struct foo)->array has (struct foo)->size
elements.  This should probably be stored in type_info or in constraints.
We also have type_size which could probably be replaced with type_info.

My new idea is to assign all pointers a hash called an mtag.  This will
replace local_values and data_info values directly.  To create the mtag you
make a string based on several things depending on the type of allocation
and take the md5hash.  It's complicated to store anything larger than s64max
in SQLite3 so we only use the low 63 bits of the hash.

The long term goal is to write everything in terms of containers_of().  So
you have a struct member, and you follow it back to the first pointer and
you see if you can determine the mtag for that pointer.

Then when a pointer is stored like "foo->bar = ptr;" we take the member
offset of ->bar, let's say 48 bytes and the mtag of foo and we record it
in the DB:  "foo_mtag, 48, ptr_mtag".  (I haven't totally figured out the
format yet.)  So, ideally, you would be able to take any pointer and follow
it back to a toplevel variable.  That won't happen most of the time in
real life, but it's the target.

The other thing is that we can allocate mtags ->probe() functions.  It's
pretty standard that the ->probe() function gets some kind of device
pointer and then we pass that device pointer to all the ->open() and
->read() functions.  This feature will let us record in the DB that these
pointers are all the same, then we'll be able to track what is stored in
the dev->private_data pointer.  Again this is not something I have
implemented yet, but it is the end goal.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Makefile
check_list.h
smatch.h
smatch_data/db/build_early_index.sh
smatch_data/db/mtag_about.schema [new file with mode: 0644]
smatch_db.c
smatch_mtags.c [new file with mode: 0644]