\input texinfo @c -*- texinfo -*-
@comment %**start of header
@setfilename techview.info
@settitle Technical view of Checker
@comment %**end of header

@iftex
@finalout
@end iftex

@ifinfo
This file documents technical points of Checker, a memory access detector.

Copyright (C) 1997 Tristan Gingold.

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
@end ifinfo

@ignore
Before reading this doc, you should know that English is not my native
language.  So, if you find mistakes, please correct them, and send me your
corrections.
Moreover, since it is my first doc, the doc can be sometimes fuzzy, or
unclear.  Please tell me about that.  If you think something is not
developed enough, or needs an example, or is badly presented, please tell me.
@end ignore

@iftex
@titlepage
@title Technical view of Checker
@subtitle Copyright @copyright{} 1997 Tristan Gingold.
@author by Tristan Gingold
@end titlepage
@setchapternewpage off
@headings off
@everyheading @| @thispage @|
@end iftex

@node Top, Basic concepts, (dir), (dir)
@comment  node-name,  next,  previous,  up

@menu
* Basic concepts::              
* Stubs Introduction::          
* The Rights::                  
* Handling Rights::             
* Writing Stubs::               
@end menu

@node Basic concepts, Stubs Introduction, Top, Top
@comment  node-name,  next,  previous,  up
@chapter Basic concepts
@section Checker is a memory access detector

As you should know, @code{Checker} is a memory access detector.  Its main
feature is detecting bad memory accesses, such as reading an
uninitialized variable, violating (by reading or writing) bounds of an
array.  This is done with a bitmap: each byte of the memory has its own rights
stored in a bitmap.  Rights are readable and writable.  The bitmap is modified
very often: if a byte is stored into the memory, this byte becomes
readble, and this fact must be stored into the bitmap.
With this dummy example, things should become clearer:
@example
int middle (int a, int b)
@{
  int res;              /* At this time, RES is uninitialized but
                           writable only.  */

  res = a;              /* Check A is readable, Check RES is writable,
                           RES becomes readable and writable.  */
  res += b;             /* Check B is readable, Check RES is readable and
                           writable.  */
  return res / 2;
@}
@end example

@node Stubs Introduction, The Rights, Basic concepts, Top
@comment  node-name,  next,  previous,  up
@section The code checkered should be closed
Since you often use standard functions that you didn't write and you didn't
compile, your program compiled through @code{Checker} will be linked with
functions not compiled through @code{Checker}.  Imagine this simple function:
@example
int read_and_negate_int (int fd)
@{
  int val;              /* VAL is only writable.  */

  if (read (fd, &val, sizeof (int)) != sizeof (int))
    fatal ("Can't read an int\n");
  else
    return -val;        /* Check val is readable.  */
@}
@end example
When @var{val} is negated, the code compiled checks at first that it is
readable.  However, in this function, @var{val} is initialized by @code{read}
which must mark it readable (it remains writable also).  But @code{read} is
a function that was not compiled through @code{Checker}.  If nothing was done,
a message telling you are reading an initialized variable will appear.
To avoid such a problem, @dfn{stubs} are used: they are small functions used
instead of a function in order to do as if this function was compiled through
@code{Checker}.  Of course, the stub for the @code{read} function will call
@code{read}.  @xref{Writing Stubs} for details.

This little example also illustrates why your code compiled through
@code{Checker} must be closed.  By @dfn{closed}, I mean that all your
code must either use functions compiled by @code{Checker} or functions
(like stubs) that behave as if they were compiled by @code{Checker}.  If
you call a function that is not inside, the bitmap will not be up to
date.  Of course, you could call an outside (ie not compiled through
@code{Checker} or not called via a stub) function that didn't use change
your static, dynamic or allocated variable without causing any troubles.
But it is clearer to use stubs (in thid case dummy stubs) for these functions
(@samp{pause} and @samp{atoi} are examples of such functions).

@node The Rights, Handling Rights, Stubs Introduction, Top
@comment  node-name,  next,  previous,  up
@section A little bit more about the rights
A right for a byte is two bits: one for the read right, one for the write
right.  So there is four states:
@table @bullet
@item none
No rights.  This is also called red zone.  Such zones are used to protect
internal structures (such as FILE, DIR) or around allocated memory to detect
bounds violation.
@item Read Only
This is the right of the .text segment (your code) and of the constant.
Generally, to optimize memory, only one state covers all these zones.
@item Write Only
This is the initial right of uninitialized memory (dynamic or allocated
variables).  Once the memory is written, it becomes readable and writable
@item Read and Write
This is the right of an initialized but not constant variable.
@end table

@node Handling Rights, Writing Stubs, The Rights, Top
@comment  node-name,  next,  previous,  up
@section Handling the rights
The rights can be either set or copied or checked.

Checking the rights is the standard operation: when you are reading, writing
or modifying a variable, the rights are checked.  Note that checking for
writable can update the rights to read/write.

Setting the rights is internally used, for example at initialisation or, when
a memory block is allocated, it is set writable.

Copying the rights is used when a zone of memory is copied.  
If simple (ie not an aggregate) is copied, in fact rights are checked: the
source must be readable, the destination must be writable (and becomes
readable).  This is different for an aggregate (a structure or a union):  since
aggregates often contain pads (unused bytes to conserve the alignment), the
whole aggregate is rarely readable.  So, when an aggregate is copied, the
destination must be writable, the source must not contain red zones and the
rights of the source are copied for the destination.

Note: GCC often use standard types (char, short, int, long) for very small
aggregate.  So, care must be taken.

@node Writing Stubs,  , Handling Rights, Top
@comment  node-name,  next,  previous,  up
@section Writing Stubs

When a program is compiled with @samp{-fcheck-memory-usage}, function
names are prefixed with @samp{chkr.} (According to your machine, the
prefix can be slightly different).  As a result, stubs are functions
whose name begins with @samp{chkr.}.  The stubs should check each
argument (if necessary) and should update the bitmap according to the
results.  The best way to create a stub is to copy its prototype, to change
the name to avoid any conflicts with the real prototype and to
add the prefix with an @code{__asm__} (since the prefix can contain illegal
characters such as @samp{.} or @samp{$}).  Let's go with a simple example:

@example
/* The prototype.  */
size_t chkr_stub_strlen (const char *) __asm__ ("chkr.strlen");

/* The stub.  Stage 1.  */
size_t
chkr_stub_strlen (const char *str)
@{
@}
@end example
The incoming argument should be checked with @code{stubs_chkr_check_addr} or
@code{stubs_chkr_check_str}.  In our example, there is
just one argument, @samp{str}, which represents a string and is only read. 
Futhermore, the function @code{strlen} doesn't modify the memory, so there
is nothing to do after the ation.  By the way, you should include
@file{checker_api.h} to use the @code{Checker} functions.  This file
also defines a macro @code{CHKR_PREFIX}, used to create the stub name
from the function name.  This improves portability.
@example
#include "checker_api.h"
#include <strings.h>

size_t chkr_stub_strlen (const char *) __asm__ (CHKR_PREFIX ("strlen"));

/* The stub.  */
size_t
chkr_stub_strlen (const char *str)
@{
  stubs_chkr_check_str (str, CHKR_RO, "str");
  return strlen (str);
@}
@end example
Let's see another example:
@example
#include "checker_api.h"
#include <unistd.h>

size_t chkr_stub_read (int fd, PTR buf, size_t n)
         __asm__ (CHKR_PREFIX ("read"));
size_t
chkr_stub_read (int fd, PTR buf, size_t n)
@{
  size_t len;
  
  fd_used_by_prog (fd);
  if (n > 0)
    stubs_chkr_check_addr (buf, n, CHKR_MW, "buf");
  len = read (fd, buf, n);
  if (len > 0)
    chkr_set_right (buf, len, CHKR_RW);
  return len;
@}
@end example
Here, the stub at first checks that the buffer is writable.  It uses a
special right, @samp{CHKR_MW}, which tests and marks the zone write-only, so
that memory not modified by @code{read} will not be readable.  Note that the
size of the zone is an argument; this is is not a problem but the size must
not be null.  After the call, the stub marks the memory writable, according
to the result.
If an incoming argument is a structure, do not check it globally: check it
field by field because the structure may contains pads, which could be not
initialized.

What must be checked?
@itemize @bullet
@item incoming pointer argument. 
If it is used only as an incoming argument, check for being readable.  If it
is used as an incoming and outcoming argument, check for being readable
and writable.  If the argument is an aggregate (ie a structure or an union),
check field one by one, because the aggregate can contain pads.

It it not necessary to check the presence of an incoming arguement, this
is the purpose of prototypes.  Furthermore, these arguments can be
stored into registers, which have no rights.

@c @item incoming structure.  They are generally passed through a pointer.

@item incoming file descriptor.
Since @code{Checker} uses some file descriptor (to output the messages or to
read some files), it also checks that your program does not try to use these
reserved file descriptor.  As a consequence, if you create a stub that
return or handle directly or not (through a structure such as @samp{FILE})
a file descriptor, you must inform @code{Checker}.  Some functions are
provided:
@table @code
@findex fd_used_by_prog
@item int fd_used_by_prog (int @var{fd})
inform that @var{fd} is a file descriptor given as an incoming argument to
the stub.

@findex fd_returned_by_system
@item int fd_returned_by_system (int @var{fd})
inform that the OS has returned a new file descriptor (generaly through a
system call such as @code{open}, @code{create}, @code{socket}).

@findex fd_closed 
@item int fd_closed (int @var{fd})
inform that @var{fd} has been closed.

@findex fd_duped
@item int fd_duped (int @var{fdres}, int @var{fdd})
inform that a new file descriptor was created by duping one.  The genuine
file descriptor is @var{fdd}.

@end table

@item outcoming pointer.
If your function return a pointer, you must set the right on the area
according to its meaning.

@item outcoming structure.
If your function return a structure, you must also set the rights.  You
should know that generally structure and union (these are named aggregate)
are returned through an invisible reference: the caller give to the function
an address where to store the result.  So you must set the right of this
area.  The address of the area can be got with the builtin function:
@example
void *__builtin_aggregate_incoming_address (void)
@end example
If the call is illegal or if the aggregate is returned by value (GCC does
this for small aggregate), this function returns 0.  Please, always check
this value.  Please check the fields one by one.
@end itemize

If your function is based on a well known function (for example
@samp{my_printf}), refer to the already written stubs.


@contents
@bye
