| Age | Commit message (Collapse) | Author | Files | Lines |
|
The Makefile has variables for both PREFIX (default $(HOME)) and BINDIR
(default $(PREFIX)/bin); however, it then uses $(PREFIX)/bin in several other
places, making it difficult to install to an alternate BINDIR. Fix this by
using $(BINDIR) consistently throughout the Makefile.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
This patch adds dissect.{h,c} files to the sparse distribution.
From dissect.h:
struct reporter
{
void (*r_symdef)(struct symbol*);
void (*r_symbol)(unsigned mode, struct position*, struct symbol*);
void (*r_member)(unsigned mode, struct position*, struct symbol*, struct symbol*);
};
extern void dissect(struct symbol_list*, struct reporter*);
dissect() walks the output of the sparse_file() and calls reporter's
callbacks.
->r_symdef() is called when the symbol (variable or function) is defined.
->r_symbol() - when the symbol is used in any way. The 'mode' parameter
denotes how this symbol was used. It is a bitmask of possible flags:
FLAG: Code example:
U_R_VAL return VAR;
U_W_VAL VAR = 0;
U_R_PTR return *VAR;
U_W_PTR *VAR = 0;
U_R_AOF const void *... = &VAR;
U_W_AOF memset(&VAR, ...);
->r_member() tracks the use of members of structures in the same way.
This patch also adds test-dissect.c, a simple and stupid example. It
prints the 'mode' parameter in a human readable format along with the
storage info, variable's name (or struct_name.member_name), and it's
type.
The 'mode' is dumped as a 3-letter string. The first letter denotes
AOF part, 2-nd - VAL, 3-rd - PTR.
0 -> '-'
U_R_xxx -> 'r'
U_W_xxx -> 'w'
U_R_xxx | U_W_xxx -> 'm'
Example:
$ cat -n T.c
1 int var;
2
3 static void func(void)
4 {
5 int *ptr;
6
7 ptr = &var;
8 *ptr = var;
9
10 var = *++ptr;
11 }
$ ./test-dissect T.c
FILE: T.c
1:5 g def var int
3:13 s def func void ( )( ... )
5:6 l def ptr int *
7:2 l -w- ptr int *
7:9 g m-- var int
8:3 l --w ptr int *
8:9 g -r- var int
10:2 g -w- var int
10:11 l -mr ptr int *
Note that '*ptr' does not add U_R_VAL flag, this is a feature, not a bug,
even if technically wrong.
dissect() does not check the code for correctness, for example:
0 = X = Y;
gives this output:
5:6 g -w- X bad type
5:10 g -r- Y bad type
Again, X has no U_R_VAL, notabug.
Members of structures usage:
task_t *tsk;
tsk->parent->real_parent->pid++;
output:
7:2 l --r tsk struct task_struct [usertype] *
7:5 g --r task_struct.parent struct task_struct *
7:13 g --m task_struct.real_parent struct task_struct *
7:26 g -m- task_struct.pid int
dissect() tries to de-anonymize unnamed structures/unions:
1 struct T {
2 struct {
3 int x, y;
4 } m;
5 } t = {
6 { undeclared }
7 };
output:
5:3 g def t struct T
5:3 g -w- t struct T
6:2 s -w- T.m struct T:m
6:4 s -w- T:m.x int
6:4 g -r- undeclared bad type
When entire struct is overwritten, ->r_member() is called with mem == NULL,
this reported as struct_name.*, example:
*new_vma = *vma;
output:
2028:5 l --w new_vma struct vm_area_struct *
2028:13 g -w- vm_area_struct.* struct vm_area_struct
2028:13 g -w- pgprot_t.* struct pgprot_t
2028:13 g -w- rb_node.* struct rb_node
2028:13 g -w- vm_area_struct:shared.* union vm_area_struct:shared
2028:13 g -w- vm_area_struct:shared:vm_set.* struct vm_area_struct:shared:vm_set
2028:13 g -w- list_head.* struct list_head
2028:13 g -w- raw_prio_tree_node.* struct raw_prio_tree_node
2028:13 g -w- list_head.* struct list_head
2028:16 l --r vma struct vm_area_struct *
Function calls use U_R_PTR bit:
5 func();
6 pf = func;
7 pf();
5:2 g --r func void ( )( ... )
6:2 l -w- pf void ( * )( ... )
6:7 g r-- func void ( )( ... )
7:2 l --r pf void ( * )( ... )
BUGS:
1. dissect() confuses array-in-container with a pointer:
3 struct T { int ary[]; } t;
4
5 t.ary[0] = 0;
output:
5:2 l -r- t /* BUG, should be -w- */ struct T
5:3 s -w- T.ary int [0]
2. It can't detect the case when the address is taken only for writing,
eg: *(&i + 1) = 0, so U_W_AOF always implies U_R_AOF.
3. It does not support "flat" initializers without braces:
3 struct O {
4 struct I {
5 int x, y;
6 } a, b;
7 };
8
9 struct O o1 = { 1, 2, 3 };
buggy output:
9:11 l -w- o1 struct O
9:18 s -w- O.a struct I
9:21 s -w- O.b struct I
9:24 s -w- O.? bad type
This is ok:
11 struct O o2 = { { 1 }, .b = { .y = 0 } };
11:11 l -w- o2 struct O
11:18 s -w- O.a struct I
11:20 s -w- I.x int
11:30 s -w- O.b struct I
11:37 s -w- I.y int
4. The implementation is far from perfect. It was really done
in "add some code + printf and see what happens" manner, without
studying the sources first. However I beleive it may be useful
for others, that is why I am posting it.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
For now, it use a simple method but which introduces a lot more copies
than necessary. Can be fixed later.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@looxix.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Right now it only makes 'blob_free()' mprotect(PROT_NONE) the buffer it
free's instead of unmapping it, but that's already quite useful for
figuring out when we've freed up memory that we later end up using after
all.
In particular, the multi-file mode ends up having different lifetime
rules for the various objects, so it introduced some nasty MM bugs.
With -DDEBUG we get some nice SIGSEGV's rather than just strange memory
corruption.
|
|
They rate their own "ptrlist" library status, since they are
definitely potentially useful outside of sparse.
|
|
|
|
Also, if we want to use "-lsparse" to link the thing, that's the
naming pattern we'd want, as pointed out by Jeff
|
|
Small patch to also delete libsparse.so (SLIB_FILE) in "clean" target.
|
|
I chickened out, and the actual programs don't link against
the shared version, but that is easy to do if somebody wants
to (just change the definition of "LIBS" to point to the
shared library instead, and possibly add -rpath to the link
flags).
|
|
Replace it with a simple pathname comparison instead.
The pathname check is not only portable (no need for any
compatibility helper functions), but we can do it much
earlier, and thus make the check much cheaper by avoiding
three extra system calls when it triggers (open/fstat/close).
And the pathname test seems to match all the cases anyway.
|
|
Add dependency on .h files for storage.o
|
|
the "example output" program from it.
|
|
This one links up the inter-bb usage pseudos to each other
with "storage" structures, which should make it possible to
write a simple code generator that doesn't need to worry
about any global state - all the decisions are local.
There are probably cases where this simply doesn't work, but
I want to try to start generating _some_ code at least.
|
|
|
|
It's disgusting how intimate lib.c is with all the types,
and this is slowly trying to split things up a bit. Now
the intimate part is in allocate.c, but maybe we can get
to the point where each allocation user just declares its
own allocation strategy, and just uses the generic routines
in allocate.c
|
|
|
|
It's a bit more simple-minded than the symbol simplification,
and it can be more costly. So we start off with the (cheap)
symbol simplification algorithm, and then use this new more
generic phase later.
This allows us to remove extra loads (and, in theory, stores,
but the dead store elimination is so simple-minded right now
that it's effectively useless).
|
|
track of which instructions use which pseudos.
It also verifies the usage, which shows a few bugs in
structure handling.
|
|
This is a celebration of a nice round ChangeSet number. This
is v1.1000. Woot woot woot!
|
|
Also, allow marking a pseudo unused by setting it to VOID,
which just disables further renaming of that use. This is
needed to make phi-source instructions (that can be shared
among multiple phi-nodes thanks to CSE) be collectable.
We used to just mark the phi source dead, but that was
wrong, since _another_ phi node might be using it.
|
|
|
|
It ain't very smart yet, but give it time.
In particular, right now it gathers information for the
whole function, but it only does the actual replacement
if the instructions are in the same basic block.
|
|
Small files are good. Now "linearize" really just contains the
code that does a straightforward linearization of the tree, and
flow.c contains the stuff that tries to analyse the result.
|
|
Instead of just silently creating it, make the thing tell
the user to create it and add the directory to the PATH.
Andrew didn't even _have_ a ~/bin. He may not be the only
person with that strange deficiency.
|
|
|
|
|
|
Noted by Chris Wedgwood.
|
|
|
|
up for various system deficiencies.
This makes sparse easier to port to silly things like
MinGW or Solaris. In particular:
- strtold() is a C99 thing, not everybody has it
- MinGW has problems with mmap(MAP_ANONYMOUS) and doesn't zero it.
- st_ino/st_dev is POSIX identity testing, not supported by MinGW
|
|
This changes the sparse Makefile to use $(CC) (which is already defined
at the top) instead of using gcc directly. That makes it possible to
use "make CC=/long/path/bin/gcc".
|
|
is just different enough to be confusing.
Thank you, thank you, I'll be here all week. Please remember
to tip your waitresses.
|
|
The only remaining place was the magic constant "0" "1" number
token generated by "defined(xxx)". And since we never actually
modify number tokens (which would have broken that code anyway),
let's just make that const'ness explicit.
|
|
I hit some SEGV turn out to dependency related.
|
|
|
|
When we don't have bugs all the time, we can strip it
again, but for now it just makes debugging harder.
|
|
Chris Wedgwood pointed these out.
|
|
check.o doesn't have LIB_H dep, trival fix below. with this you can:
make clean
bk -r clean
make -j install
and it works as expected
|
|
|
|
Three small hunks:
- new builtin used on ia64 (__builtin_ffs())
- new attribute on ia64 (syscall_linkage)
- drop the -C from the install line, most people have a recent install
which dosn't have this...
|
|
Fix a few "might be uninitialized" warnings (some might even
be valid).
|
|
instead of hardcoding it at compile time. This allows
us to do "cross-checks" much more easily.
|
|
|
|
|
|
This required making the inter-BB trampoline to be done
using indirection through a symbol, rather than as direct
pointers from one BB to another. Fix up code to match.
Avoid a few warnings by handling GOTO_BB in the case
statements.
|
|
the linearization phase.
|
|
Here's what I have so far.
Comments welcome. It cannot be considered anywhere near complete, but
it acts like it generates x86 asm for a bunch of small test cases anyway :)
It started out as show-parse.c. The emit_xxx stuff is what I have
converted from show-parse pseudo-code into x86 code generation. The
x86_xxx stuff is the stuff that remains. FIXMEs abound.
I haven't actually tried to assmble anything yet. Just studying what
gcc generates, and then what I generate.
A few random notes in closing:
* function-at-a-time
* just does one subl and one addl for stack manipulation, which implies
that it has to output everything from post-function cleanup pass
(emit_func_post).
* however, x86_xxx stuff (not yet converted) will still print out
pseudocode. So your output will look like
function header
psuedocode (i.e. stuff not yet handled)
real x86 code
If you don't see any pseudocode... you may actually be lucky enough to
be able to compile your asm ;-)
|
|
|
|
does type evaluation, the second one does value evaluation
and inline expansion.
This has the advantage that by the time we do value evaluation
and inline expansion, we have traversed the tree fully once,
which allows us to take advantage of function-global information,
ie we know whether symbols have ever been accessed etc.
|
|
allocation checking etc).
|
|
Calling it "check" is just too generic a name if we install it
somewhere global.
|
|
This patch makes compilation of sparse use the correct version of gcc
throughout. (It doesn't seem to have caused any problems, but the
current situation isn't strictly correct, so...)
|
|
used for inlining. Right now the copying is totally broken, since
we don't actually do any symbol replacement, but hey, we'll get there
some day.
Make "inline_function()" call the new copy_statement() function.
|
|
This update (hopefully) will allow 'check' to find the appropriate, gcc-local
include headers (dependent, of course, upon the system it was built on)
It's still a hack, but at least it will work in a few more places.
|
|
to public license.
From Jeff Garzik with modifications.
|
|
else. This is useful to get warnings from the parser and type evaluator.
|
|
|
|
Add "obfuscate" as a stupid back-end. It will generate some
really really horrible C output if I get my way.
Don't expose "attribute" for type attributes. Use only the
double-underscore version
|
|
evaluate.c instead of keeping it in pre-process.c.
Add the proper dependencies
|
|
|
|
Parse trees, symbols and expressions are now printed out
in show-parse.c instead of cluttering up the main parsing
files.
|
|
its own - expression.c.
|
|
lazy and not doing it right.
|
|
|
|
|
|
expressions by just walking the parse tree.
We de-allocate all the C preprocessor expressions at the end, before
we actually start doing the real C parsing. There is no history.
|
|
symbol expansion (ie no argument-handling yet).
Mark the EOF token as being on a new line, to make preprocessing simpler.
|
|
Make tokens know about newlines
|
|
|
|
This adds a layer of symbol information on top of the raw tokens.
|
|
Namespace handling (and types) still not even started.
|
|
simple binops so far, type parsing is still way off).
Clean up and update tokenization.
|
|
to do a semantic parser that is smaller than gcc is.
Right now this is just the lexer, though, along with a test app to print
the results back out to verify the thing.
|