	+ valgrind bits ...
		+ as per memcheck:
		    + needs to trap & check every read & write
			+ substantially reduce the granularity ...
		    + 'lackey' - seems to do this already
		      [ with code access too ]
		+ want to trap all read/write/I/O interesting syscalls ...
		    + coregrind/mlibc_file
		    + coregrind/m_syswrap/syswrap-linux.c /sys_llseek/ (eg.)
		    + currently - we don't have this level of semantic
		      visibility, we need to hook coregrind bits.
			+ cf. POST_MEM_WRITE hard-coding etc.
		+ thunk on explicit I/O ? [ eg. map / unmap to keep addresses consistent ? ]

	+ Visualisation:
		+ break down *code* by section information and chart that ...
		+ [ hmm ]
		+ re-use OO.o's charting ? ;-)
		+ Break down working set by *allocation* ! ;-)
			+ what code allocated & then touched what ...
			+ [need more precision]



	+ Track:
		+ all operations on file descriptors
		+ open/close/read/mmap/...
		+ 

Setup some new 'track_io_call' type methods:

track_io_open ...
track_io_read
track_io_write
track_io_close ?

/usr/src/linux/include/linux/syscalls.h:

asmlinkage long sys_sync(void);
asmlinkage long sys_fsync(unsigned int fd);
asmlinkage long sys_fdatasync(unsigned int fd);
asmlinkage long sys_truncate(const char __user *path,
				unsigned long length);
asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
asmlinkage long sys_stat(char __user *filename,
			struct __old_kernel_stat __user *statbuf);
asmlinkage long sys_statfs(const char __user * path,
				struct statfs __user *buf);
asmlinkage long sys_statfs64(const char __user *path, size_t sz,
				struct statfs64 __user *buf);
asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user *buf);
asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz,
				struct statfs64 __user *buf);
asmlinkage long sys_lstat(char __user *filename,
			struct __old_kernel_stat __user *statbuf);
asmlinkage long sys_fstat(unsigned int fd,
			struct __old_kernel_stat __user *statbuf);
asmlinkage long sys_newstat(char __user *filename,
				struct stat __user *statbuf);
asmlinkage long sys_newlstat(char __user *filename,
				struct stat __user *statbuf);
asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf);
asmlinkage long sys_ustat(unsigned dev, struct ustat __user *ubuf);
#if BITS_PER_LONG == 32
asmlinkage long sys_stat64(char __user *filename,
				struct stat64 __user *statbuf);
asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf);
asmlinkage long sys_lstat64(char __user *filename,
				struct stat64 __user *statbuf);
asmlinkage long sys_truncate64(const char __user *path, loff_t length);
asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length);
#endif
h
/* Omit all the set/get xattr API calls in the 1st pass ... */
asmlinkage unsigned long sys_mremap(unsigned long addr,
				unsigned long old_len, unsigned long new_len,
				unsigned long flags, unsigned long new_addr);
asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
			unsigned long prot, unsigned long pgoff,
			unsigned long flags);
asmlinkage long sys_msync(unsigned long start, size_t len, int flags);
asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice);
asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice);
asmlinkage long sys_munmap(unsigned long addr, size_t len);
asmlinkage long sys_madvise(unsigned long start, size_t len, int behavior);
asmlinkage long sys_chroot(const char __user *filename); // tracking paths
asmlinkage long sys_mknod(const char __user *filename, int mode,
				unsigned dev);
asmlinkage long sys_link(const char __user *oldname,
				const char __user *newname);
asmlinkage long sys_symlink(const char __user *old, const char __user *new);
asmlinkage long sys_unlink(const char __user *pathname);
asmlinkage long sys_rename(const char __user *oldname,
				const char __user *newname);
asmlinkage long sys_chmod(const char __user *filename, mode_t mode);
asmlinkage long sys_fchmod(unsigned int fd, mode_t mode);
asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
#if BITS_PER_LONG == 32
asmlinkage long sys_fcntl64(unsigned int fd,
				unsigned int cmd, unsigned long arg);
#endif
asmlinkage long sys_dup(unsigned int fildes);
asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd);
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on);
asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd,
				unsigned long arg);
asmlinkage long sys_flock(unsigned int fd, unsigned int cmd);


// omit async I/O bits ...

asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd,
				off_t __user *offset, size_t count);
asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd,
				loff_t __user *offset, size_t count);
asmlinkage long sys_readlink(const char __user *path,
				char __user *buf, int bufsiz);
asmlinkage long sys_creat(const char __user *pathname, int mode);
asmlinkage long sys_open(const char __user *filename,
				int flags, int mode);
asmlinkage long sys_close(unsigned int fd);
asmlinkage long sys_access(const char __user *filename, int mode);
asmlinkage long sys_chown(const char __user *filename,
				uid_t user, gid_t group);
asmlinkage long sys_lchown(const char __user *filename,
				uid_t user, gid_t group);
asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group);
#ifdef CONFIG_UID16
asmlinkage long sys_chown16(const char __user *filename,
				old_uid_t user, old_gid_t group);
asmlinkage long sys_lchown16(const char __user *filename,
				old_uid_t user, old_gid_t group);
asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group);

asmlinkage long sys_utime(char __user *filename,
				struct utimbuf __user *times);
asmlinkage long sys_utimes(char __user *filename,
				struct timeval __user *utimes);
asmlinkage off_t sys_lseek(unsigned int fd, off_t offset,
				unsigned int origin);
asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high,
			unsigned long offset_low, loff_t __user *result,
			unsigned int origin);
asmlinkage ssize_t sys_read(unsigned int fd, char __user *buf,
				size_t count);
asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count);
asmlinkage ssize_t sys_readv(unsigned long fd,
				const struct iovec __user *vec,
				unsigned long vlen);
asmlinkage ssize_t sys_write(unsigned int fd, const char __user *buf,
				size_t count);
asmlinkage ssize_t sys_writev(unsigned long fd,
				const struct iovec __user *vec,
				unsigned long vlen);
asmlinkage long sys_getcwd(char __user *buf, unsigned long size);
asmlinkage long sys_mkdir(const char __user *pathname, int mode);
asmlinkage long sys_chdir(const char __user *filename);
asmlinkage long sys_fchdir(unsigned int fd);
asmlinkage long sys_rmdir(const char __user *pathname);
asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user *buf, size_t len);
asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special,
				qid_t id, void __user *addr);
asmlinkage long sys_getdents(unsigned int fd,
				struct linux_dirent __user *dirent,
				unsigned int count);
asmlinkage long sys_getdents64(unsigned int fd,
				struct linux_dirent64 __user *dirent,
				unsigned int count);
	   
// omit select / poll etc.


/* New and under-used bits ... !? 
asmlinkage long sys_mknodat(int dfd, const char __user * filename, int mode,
			    unsigned dev);
asmlinkage long sys_mkdirat(int dfd, const char __user * pathname, int mode);
asmlinkage long sys_unlinkat(int dfd, const char __user * pathname, int flag);
asmlinkage long sys_symlinkat(const char __user * oldname,
			      int newdfd, const char __user * newname);
asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
			   int newdfd, const char __user *newname, int flags);
asmlinkage long sys_renameat(int olddfd, const char __user * oldname,
			     int newdfd, const char __user * newname);
asmlinkage long sys_futimesat(int dfd, char __user *filename,
			      struct timeval __user *utimes);
asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode);
asmlinkage long sys_fchmodat(int dfd, const char __user * filename,
			     mode_t mode);
asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user,
			     gid_t group, int flag);
asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
			   int mode);
asmlinkage long sys_newfstatat(int dfd, char __user *filename,
			       struct stat __user *statbuf, int flag);
asmlinkage long sys_fstatat64(int dfd, char __user *filename,
			       struct stat64 __user *statbuf, int flag);
asmlinkage long sys_readlinkat(int dfd, const char __user *path, char __user *buf,
			       int bufsiz);
asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename,
				     struct compat_timeval __user *t);
asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename,
				      struct compat_stat __user *statbuf,
				      int flag);
asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename,
				   int flags, int mode);
*/


** Target just a few to start with: **

open("/usr/lib/locale/en_GB.UTF-8/LC_NUMERIC", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_GB.utf8/LC_NUMERIC", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=54, ...}) = 0
mmap2(NULL, 54, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f17000
close(3)                                = 0
open("/usr/lib/locale/en_GB.UTF-8/LC_CTYPE", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_GB.utf8/LC_CTYPE", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=208464, ...}) = 0
mmap2(NULL, 208464, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7cba000
close(3)                                = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, TIOCGWINSZ, {ws_row=57, ws_col=158, ws_xpixel=1600, ws_ypixel=1149}) = 0
open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY) = 3
fstat64(3, {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
getdents64(3, /* 14 entries */, 4096)   = 360
getdents64(3, /* 0 entries */, 4096)    = 0


asmlinkage long sys_open(const char __user *filename,
				int flags, int mode);
asmlinkage long sys_close(unsigned int fd);
asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf);



OO.o -writer startup: sys-call count:

   4312  open			I
   3006  read			I
    839  _llseek		I
    766  stat64			I
    758  access			I
    664  gettimeofday
    615  close			I
    589  write			I
    571  fstat64		I
    563  mmap2			I
    496  lseek			I
    490  lstat64		I
    348  poll			I
    238  brk
    233  fcntl64		I
    168  munmap			I
    167  futex
    155  getdents64		I
    154  ioctl
    149  madvise		I
    142  getcwd
    120  time
     84  writev			I
     73  select
     43  rt_sigaction
     43  getuid32
     33  uname
     32  send
     18  unlink
     18  readv			I
     17  mprotect
     14  socket
     13  mkdir
     11  readlink		I
     11  connect
      9  rename			I
      7  times
      7  recv
      7  clone
      6  umask
      5  pipe
      5  getrlimit
      5  _exit
      4  shutdown
      3  setsockopt
      2  sched_get_priority_max
      2  rmdir
      2  recvmsg
      2  pread64
      2  listen
      2  geteuid32
      2  clock_gettime
      2  bind
      1  utime
      1  _sysctl
      1  shmget
      1  shmctl
      1  shmat
      1  set_tid_address
      1  set_thread_area
      1  setrlimit
      1  sched_getscheduler
      1  sched_get_priority_min
      1  sched_getparam
      1  rt_sigprocmask
      1  nanosleep
      1  link
      1  getsockname
      1  getresuid32
      1  getresgid32
      1  getgid32
      1  getegid32
      1  ftruncate64
      1  ftruncate
      1  exit_group
      1  execve
      1  accept


** Calltree format:

    + generic cost annotation language
	+ could be re-used for output from a profiler ...
    + increment a byte - wraparound ?
	-> trigger a hit ?

** Kcachegrind:
    + replicate 'part view' ?

** Step 1:
    + trap open / mmaps (and munmaps)
    + trap all code & data access
    + log these
	+ simulate ...

** log memory accesses on the side:
    + what structure to use for that ?

    + multi-level page lookup (?)
	+ look at bottom, look at middle, look at top ...


** To output:
    + mmap data ...
	+ if code: where all the sections are (etc.)
    + Where we are writing to ...
	+ what the writes are doing ...


** Compress stack trace data ...
    + [?]
    + how does callgrind do it ? :-)
    + re-use (similar?) representation [!?]
    + 

    + uniquify each stack trace (?)
	+ hash ?
	+ itemize loads per trace ?

    + Want a 'bootchart' type view too ...

** Need to log mmap information:

    + use pub_tool_aspacemgr.h (?)
// See pub_core_aspacemgr.h for description.
extern NSegment const * VG_(am_find_nsegment) ( Addr a ); 

or pub_core_aspacemgr.h:

/* Notifies aspacem that the client completed an mmap successfully.
   The segment array is updated accordingly.  If the returned Bool is
   True, the caller should immediately discard translations from the
   specified address range. */
extern Bool VG_(am_notify_client_mmap)
   ( Addr a, SizeT len, UInt prot, UInt flags, Int fd, Off64T offset );

/* Notifies aspacem that an munmap completed successfully.  The
   segment array is updated accordingly.  As with
   VG_(am_notify_munmap), we merely record the given info, and don't
   check it for sensibleness.  If the returned Bool is True, the
   caller should immediately discard translations from the specified
   address range. */
extern Bool VG_(am_notify_munmap)( Addr start, SizeT len );

syswrap-generic.c:

void 
ML_(notify_aspacem_and_tool_of_mmap) ( Addr a, SizeT len, UInt prot, 
                                       UInt flags, Int fd, Off64T offset )

   VG_TRACK( new_mem_mmap, a, len, rr, ww, xx );


   VG_(track_new_mem_startup)     ( mc_new_mem_startup );
   VG_(track_new_mem_stack_signal)( MC_(make_mem_undefined) );
   VG_(track_new_mem_brk)         ( MC_(make_mem_undefined) );
   VG_(track_new_mem_mmap)        ( mc_new_mem_mmap );

   VG_(track_die_mem_stack_signal)( MC_(make_mem_noaccess) ); 
   VG_(track_die_mem_brk)         ( MC_(make_mem_noaccess) );
   VG_(track_die_mem_munmap)      ( MC_(make_mem_noaccess) ); 

* Accurate per section breakdown for shlib sections ? ;-) [hmm]

* Draw mmaps in a 2nd pass (alpha ?) ...

* FIXME:
    + add a firmer concept of time into the simulator
    + stamp each event with the correct time ...

    + how to visualise ?
	+ each I/O causing event is -so- long that ... (?)
	+ the others are ~trivial in comparison (?)
	+ so - Elapsed time is useful & also current time.
	    + store current time only for mmaps ?

    + re-factor layout code out of the simulator ?
	+ whack that into the rendering code: build a model.
	+ then bin the simulator ?

    + inherit each struct from Region (?)

    + get types out of the structure (?)



TODO:
    + suck out initial mmap ...
        + -d -d (?)
--3336:1:aspacem  <<< SHOW_SEGMENTS: Memory layout at client startup (25 segments, 4 segnames)

    + stack behaves in an odd way - extensions of it etc.

    + Section names



TODO:
    + use 'Tree' structure in 'Layout.cs' to generate a pleasing layout.
        [ + track & generate overlaps [?] - or ignore them ? ]
    + write some (manually generated) test cases that map / unmap / re-map
      the same address space

    + prune 'using' lines ...


