If you have any problems building or using cqual, don't hesitate to
email questions to:
                        cqual@cs.umd.edu

***
*** Building and installing cqual
***

To build cqual, you need

- gcc
- emacs (cqual has some code generators written in elisp)
- perl

After untarring and cd'ing into the top-level directory,

$ ./configure
$ make

and as root

$ make install

Among other things, cqual installs
- cqual    # the analysis engine backend (sort of like cc1)
- gcqual   # a frontend for the analysis (sort of like gcc)
- kqual    # a convenience script for kernel developers
- PAM mode # _very_ nice error message browsing in emacs

To make PAM mode available, you will probably have to add
the following two lines to your .emacs file:

(setq load-path (cons "/usr/local/share/emacs/site-lisp/cqual" load-path))
(load "cqual-pam")

*** Alternatives to "make install"

If you don't want to install cqual system wide, then you can have
everything installed under $some_dir by doing

$ ./configure --prefix=$some_dir

Then just make sure that $some_dir/bin is in your $PATH.  You can also
run cqual in place.  Assuming you're in the cqual top level directory,

$ export PATH=$PATH:$PWD/bin:$PWD/src
$ export CQUAL_CONFIG_DIR=$PWD/config


***
*** Using cqual, an example
***

The file examples/user1.c has a user-kernel bug (see the comments in
the file for an explanation).  Here's what you get when you run
kqual (the output line numbers have been added):

Note: In the output below, cqual doesn't distinguish between 
  msgs[i].buf (where msgs is a pointer)
and
  msgs->buf

$ kqual examples/user1.c
 1: examples/user1.c:31 type of actual argument 2 doesn't match type of formal
 2: karg.msgs: $kernel $user 
 3: ./config/proto-noderef.i:2      $user == copy_from_user_arg2
 4:         examples/user1.c:31           == copy_from_user_arg2@31
 5:         examples/user1.c:31           == karg.msgs
 6:         examples/user1.c:17           == &karg.msgs->buf
 7:         examples/user1.c:38           == _op_deref_arg1@38
 8: ./config/proto-noderef.i:66           == $kernel
 9: 
10: examples/user1.c:38 type of actual argument 1 doesn't match type of formal
11: msgs->buf: $kernel $user 
12: ./config/proto-noderef.i:2      $user == *copy_from_user_arg1
13:         examples/user1.c:31           == *copy_from_user_arg1@31
14:         examples/user1.c:31           == *msgs
15:         examples/user1.c:24           == msgs->buf
16:         examples/user1.c:38           == copy_from_user_arg1@38
17:         examples/user1.c:38           == copy_from_user_arg1
18: ./config/proto-noderef.i:2            == $kernel

Here's an explanation of the important lines:

Line 2: The variable karg.msgs is used inconsistently: sometimes
        as a kernel pointer, sometimes as user.

Line 3-8: This is an explanation of the error.
  Line 3: Formal arg 2 of copy_from_user is a user pointer.
  Line 4: "copy_from_user_arg2@31" just refers to arg 2 of the
          call to copy_from_user on line 31.
  Line 5: karg.msgs is the actual arg 2, so it must be user.
  Line 6: &karg.msgs->buf is a user pointer if and only if
          karg.msgs is, so &karg.msgs->buf must be a user pointer.
  Line 7: &karg.msgs->buf is dereferenced on line 38 when
          karg.msgs[i].buf is copied to the stack in preparation
          for the call to copy_from_user.
  Line 8: only kernel pointers can be dereferenced.  ERROR!

The first warning is a real bug.  Here's the second:

Line 11: msgs.buf is used sometimes as a user pointer, sometimes as 
         a kernel pointer

  Line 12: This rule states that, "If you pass a pointer p as the
           first arg to copy_from_user(), then *p is under user
           control and thus not safe to dereference."
  Line 13-14: So the contents of the structures pointed to by the
              msgs are under user control.
  Line 15: msgs->buf is part of those contents, and hence is not
           safe to dereference.
  Line 16: msgs[i].buf is passed as the arg 1 to copy_from_user.
  Line 17-18: But copy_from_user requires arg 1 to be safe to 
              dereference.  ERROR!

This looks serious, but actually, msgs.buf is reset to be a kernel
pointer (line 34) before being passed to copy_from_user, so there is
really no error.  However, cqual requires every program variable to
have only one type: either always user or always kernel.  This is a
common requirement.  Linus' sparse has the same rule, and the code
must be rewritten to pass either sparse or cqual.


***
*** Using cqual in the kernel build process
***

Make sure that you have module versioning (i.e. CONFIG_MODVERSIONS)
turned off in your kernel's .config file.  This is required because,
currently, cqual's annotations are kept seperate from the main kernel,
so the module versioning name mangling confuses cqual.  Incorporating
cqual's annotations into the kernel would eliminate this step.

kqual generates no output if the file being checked has no errors.

*** Linux 2.6:

$ make C=1 CHECK=kqual <target>

This will build and check <target> using kqual instead of sparse.

*** Linux 2.4:

$ make foo/bar/source.i
$ kqual foo/bar/source.i

Alternatively, in the kernel Makefile, set CC=kqual
and run

$ make <target>

*** Multiple files

You can analyze multiple files at once by specifying them all on the
command line, e.g.

$ kqual drivers/foo/some_module/*.i

This allows cqual to find bugs that cross source files.
Alternatively, you can annotate all the symbols shared between the
different source files.

*** Caveats

CQual currently ignores the __user annotations in the kernel because
they are frequently used in casts, and therefore can allow buggy code
to pass cqual without generating any warnings.  Incorrect casts have
already allowed some buggy code to pass through sparse without
generating warnings, so we strongly discourage casting user and kernel
annotations.


***
*** PAM mode
***

If you're having trouble understanding an error reported by cqual, you
can use PAM mode, an interactive emacs mode for exploring the errors
found by cqual.  To analyze a C file in PAM mode, first run it through
the preprocessor.  For most kernel files, this is just a matter of
running something like

$ make init/main.i

To use the example from before, run

$ gcc -E examples/user1.c -o examples/user1.i

Then, in emacs, type M-x cqual<RETURN>, and give the name of the
preprocessed file to be analyzed, e.g. examples/user1.i in this case.
After a moment, emacs will display a results screen with two errors.
You can use the middle mouse button to follow links which explain the
errors.  For example, clicking on the first error will open
examples/user1.i with the pointer at the site of the error.  Clicking
on "msgs" to the right of the cursor opens a description of that
variable's type.  Clicking on "karg.msgs" shows the explanation for
the error.  Clicking on each "==" in the path will jump the cursor to
the relevant location in the file.

PAM mode displays suspicious variables in purple, so, as a general
rule, clicking on anything purple is good.  Section 1.3 of
doc/user-guide.ps has a more detailed tutorial on using PAM mode.


This documentation is copyright (c) 2003 The Regents of the
University of California.
