Logo Search packages:      
Sourcecode: hat version File versions  Download package

detectutils.c

/*
 *  Utility functions for hat-detect.
 */
#include <stdio.h>
#include <errno.h>

#ifdef DEBUG
#define HIDE(x) x
#else
#define HIDE(x)
#endif

#include "detectutils.h"

/* Return the next child of any of the parents in the ParentSet.  */
FileOffset
nextChild (ParentSet* ps)
{
  FileOffset node=0;
  /* keep searching one node at a time until a valid child turns up */
  do { node = childSearch(ps); } while (!node);
  return node;
}


/* Skip past one node of the file, returning its position if it is a child
 * of any of the parents in the ParentSet, or 0 otherwise.
 */
FileOffset
childSearch (ParentSet* ps)
{
  unsigned char c; int err;
  FileOffset parent, node = q_position;
  if (hat_interrupted) return 3;
  err = q_fread(&c,sizeof(unsigned char),1,HatFileSeq);
  if (err!=1) {
    return 1;     /* Assume EOF */
  }
  HIDE(fprintf(stderr,"childSearch: 0x%x, %d\n",node,c);)
  switch (lower5(c)) {  /* lower 5 bits identify the TraceType */
    case ExpApp:
    case ExpValueApp:
    case ExpValueUse:
    case ExpConstUse:
    case ExpProjection:
    case ExpConstDef:
    case ExpGuard:
    case ExpCase:
    case ExpIf:
    case ExpFieldUpdate:
    case ExpHidden:
    case ExpForward:
    case ExpDoStmt:
        parent = q_skipNode(c);
        if (elemParentSet(parent,ps)) return node; else return 0;
        break;
    default:
        q_skipNode(c); return 0; break;
  }
}


/* Print a message to stderr if the asserted condition is violated. */
void
assert (Bool cond, char *act)
{
  if (!cond) {
    fprintf(stderr,"Assertion failed: %s at 0x%x\n",act,q_position);
  }
}

/* Look for the file node that corresponds to the definition of Main.main */
FileOffset
findMainUse (Bool findUse)
{
    FileOffset fo;
    FileOffset atom;
    FileOffset def;
    FileOffset use;
    char c;
    char *str;
    
    // We should find the main module at 0x10
    fseek(HatFileSeq,0x10,SEEK_SET); q_position=0x10;
    q_fread(&c,sizeof(char),1,HatFileSeq);
    assert (lower5(c)==Module, "Module tag");
    str = q_readString();
    assert (!strcmp(str,"Main"),"Module is Main");
    
    // The next thing shoult be the atom variable belonging to that module
    q_readString();
    atom = q_position;
    q_fread(&c,sizeof(char),1,HatFileSeq);
    assert (lower5(c)==AtomVariable, "AtomVariable tag");
    fo = q_readFO();
    assert (fo==0x10, "AtomVariable module is Main");
    
    { /* skip defnpos */
        int x;
        q_fread(&x,sizeof(int),1,HatFileSeq);
    }
    { /* skip defnpos */
        int x;
        q_fread(&x,sizeof(int),1,HatFileSeq);
    }
    { /* skip fixity */
        char x;
        q_fread(&x,sizeof(char),1,HatFileSeq);
    }
    
    // Main takes no arguments
    q_fread(&c,sizeof(char),1,HatFileSeq);
    assert (c==0, "AtomVariable has arity 0");
    
    // Make sure the deffinition is main
    str = q_readString();
    assert (!strcmp(str,"main"),"AtomVariable is main");
    
    // Make sure there is a constant definition pointing at main
    def = q_position;
    q_fread(&c,sizeof(char),1,HatFileSeq);
    assert (lower5(c)==ExpConstDef, "ExpConstDef tag");
    q_readFO(); q_readFO();
    fo = q_readFO();
    assert (fo==atom, "ExpConstDef points to AtomVariable main");
    
    // Make sure that main is called
    use = q_position;
    q_fread(&c,sizeof(char),1,HatFileSeq);
    assert (lower5(c)==ExpConstUse, "ExpConstUse tag");
    if (hasSrcPos(c)) q_readFO();
    q_readFO();
    fo = q_readFO();
    assert(fo==def, "ExpConstUse points to ExpConstDef");
    
    if (findUse)
    {
        return use;
    }
    else
    {
        return def;
    }
    
    /* postcondition: q_position points to first node following ExpConstUse */
}


/* Decide whether to ask a question in hat-detect, by determining whether
 * any of the functional identifiers in an expression are untrusted.
 * Originally, we thought that only the 'real' function being applied
 * mattered.  But in a higher-order application like (filter f ...) then
 * we are probably interested in asking the question if f is suspect, even
 * though filter is trusted.  Even this is only an approximation, because
 * (filter f [] = []) is an uninteresting question - but it is too expensive
 * to search for any children of the node, just to rule it out when no 
 * children are found. */
Bool
anySuspect (FileOffset fo)
{
  char c, i;
  FileOffset ptr[20];         /* applications only recorded up to arity 15 */
  FileOffset r;
  if (fo==0) return False;
  freadAt(fo,&c,sizeof(char),1,HatFileRandom);
  switch (lower5(c)) {
    case ExpApp:
          HIDE(fprintf(stderr,"anysuspect: 0x%x ExpApp\n",fo);)
        if (hasSrcPos(c)) { readFO(); }         /* skip use position */
      readFO(); readFO();                 /* skip parent and result */
      ptr[0] = readFO();                  /* get fun */
      fread(&c,sizeof(char),1,HatFileRandom);   /* get arity */
      for (i=1; i<=c; i++) ptr[i] = readFO();   /* get args */
      if (anySuspect(ptr[0])) return True;
      for (i=1; i<=c; i++) {
        if (anySuspect(getResult(ptr[i],True))) return True;
      }
      return False;                       /* fall-through case */
      break;
    case ExpProjection:
    case ExpValueUse:
          HIDE(fprintf(stderr,"anysuspect: 0x%x ExpValueUse\n",fo);)
        if (hasSrcPos(c)) { readFO(); }         /* skip use position */
      readFO();                     /* skip parent */
      ptr[0] = readFO();                  /* get Atom */
      return anySuspect(ptr[0]);
      break;
    case AtomVariable:
          HIDE(fprintf(stderr,"anysuspect: 0x%x AtomVariable\n",fo);)
      ptr[0] = readFO();                  /* get Module */
      return anySuspect(ptr[0]);
      break;
    case Module:
          HIDE(fprintf(stderr,"anysuspect: 0x%x Module\n",fo);)
      return tracedModule(c);             /* check trust bit */
      break;
    default:
            return False;
      break;
  }
}

Generated by  Doxygen 1.6.0   Back to index