/*===- ExactCheck.cpp - Implementation of exactcheck functions ------------===*/
/*                                                                            */
/*                          The SAFECode Compiler                             */
/*                                                                            */
/* This file was developed by the LLVM research group and is distributed      */
/* under the University of Illinois Open Source License. See LICENSE.TXT for  */
/* details.                                                                   */
/*                                                                            */
/*===----------------------------------------------------------------------===*/
/*                                                                            */
/* This file implements the exactcheck family of functions.                   */
/*                                                                            */
/*===----------------------------------------------------------------------===*/

#include "DebugReport.h"
#include "ConfigData.h"

#include "../include/BitmapAllocator.h"
#include "../include/CWE.h"


#include "PoolAllocator.h"
#include "RewritePtr.h"


#include <stdint.h>

#include <cstdio>

extern FILE * ReportLog;

using namespace llvm;

static void *
exactcheck_check (void * Source, void * ObjStart, void * ObjEnd,
                  const void * Dest, const char * SourceFile,
                  unsigned int lineno) __attribute__((noinline));

static void
failLSCheck (const char *base,
             const char *result,
             unsigned size,
             const char * SourceFile,
             unsigned int lineno) __attribute__((noinline));

void
failLSCheck (const char *base,
             const char *result,
             unsigned size,
             const char * SourceFile,
             unsigned int lineno) {
  DebugViolationInfo v;
  v.type = ViolationInfo::FAULT_LOAD_STORE,
    v.faultPC = __builtin_return_address(0),
    v.faultPtr = result,
    v.CWE = CWEBufferOverflow,
    v.PoolHandle = 0,
    v.dbgMetaData = NULL,
    v.SourceFile = SourceFile,
    v.lineNo = lineno;
  
  ReportMemoryViolation(&v);
}

/*
 * Function: fastlscheck()
 *
 * Description:
 *  This function performs a fast load/store check.  If the check fails, it
 *  will *not* attempt to do pointer rewriting.
 *
 * Inputs:
 *  base   - The address of the first byte of a memory object.
 *  result - The pointer that is being checked.
 *  size   - The size of the object in bytes.
 *  lslen  - The length of the data accessed in memory.
 */
void
fastlscheck (const char *base, const char *result, unsigned size,
             unsigned lslen) {
  /*
   * If the pointer is within the object, the check passes.  Return the checked
   * pointer.
   */
  const char * end = result + lslen - 1;
  if ((result >= base) && (result < (base + size))) {
    if ((end >= base) && (end < (base + size))) {
      return;
    }
  }

  /*
   * If the memory access accesses zero bytes, don't report an error.  This can
   * happen with load/store checks on memcpy()/memset() calls.
   */
  if (!lslen)
    return;

  failLSCheck (base, result, size, "unknown", 0);
  return;
}

/*
 * Function: fastlscheck_debug()
 *
 * Description:
 *  This function performs a fast load/store check.  If the check fails, it
 *  will *not* attempt to do pointer rewriting.
 *
 * Inputs:
 *  base   - The address of the first byte of a memory object.
 *  result - The pointer that is being checked.
 *  size   - The size of the object in bytes.
 */
void
fastlscheck_debug (const char *base, const char *result, unsigned size,
                   unsigned lslen,
                   unsigned tag,
                   const char * SourceFile,
                   unsigned lineno) {
  /*
   * If the pointer is within the object, the check passes.  Return the checked
   * pointer.
   */
  const char * end = result + lslen - 1;
  if ((result >= base) && (result < (base + size))) {
    if ((end >= base) && (end < (base + size))) {
      return;
    }
  }

  /*
   * If the memory access accesses zero bytes, don't report an error.  This can
   * happen with load/store checks on memcpy()/memset() calls.
   */
  if (!lslen)
    return;

  failLSCheck (base, result, size, SourceFile, lineno);
  return;
}

/*
 * Function: exactcheck2()
 *
 * Description:
 *  Determine whether a pointer is within the specified bounds of an object.
 *
 * Inputs:
 *  source - The source pointer of the indexing operation (the GEP).
 *  base   - The address of the first byte of a memory object.
 *  result - The pointer that is being checked.
 *  size   - The size of the object in bytes.
 *
 * Return value:
 *  If there is no bounds check violation, the result pointer is returned.
 *  Otherwise, depending upon the configuration of the run-time, either an
 *  error is returned or a rewritten Out-of-Bounds (OOB) pointer is returned.
 */
void *
exactcheck2 (char * source, char *base, char *result, unsigned size) {

  /*
   * If the pointer is within the object, the check passes.  Return the checked
   * pointer.
   */
  if ((result >= base) && (result < (base + size))) {
    return (void*)result;
  }
  return exactcheck_check (source, base, base + size-1, result, NULL, 0);
}

/*
 * Function: exactcheck2_debug()
 *
 * Description:
 *  This function is identical to exactcheck2(), but the caller provides more
 *  source level information about the run-time check for error reporting if
 *  the check fails.
 *
 * Inputs:
 *  source - The source pointer of the indexing operation (the GEP).
 *  base   - The address of the first byte of a memory object.
 *  result - The pointer that is being checked.
 *  size   - The size of the object in bytes.
 *
 * Return value:
 *  If there is no bounds check violation, the result pointer is returned.
 *  This forces the call to exactcheck() to be considered live (previous
 *  optimizations dead-code eliminated it).
 */
void *
exactcheck2_debug (char *source,
                   char *base,
                   char *result,
                   unsigned size,
                   unsigned tag,
                   const char * SourceFile,
                   unsigned lineno) {
  /*
   * If the pointer is within the object, the check passes.  Return the checked
   * pointer.
   */
  if ((result >= base) && (result < (base + size))) {
    return (void*) result;
  }

  return exactcheck_check (source, base, base + size - 1, result, 
                           SourceFile, lineno);
}

/*
 * Function: exactcheck_check()
 *
 * Description:
 *  This is the slow path for an exactcheck.  It handles pointer rewriting
 *  and error reporting when an exactcheck fails.
 *
 * Inputs:
 *  source - The source pointer of the indexing operation (the GEP).
 *  ObjStart - The address of the first valid byte of the object.
 *  ObjEnd   - The address of the last valid byte of the object.
 *  Dest     - The result pointer of the indexing operation (the GEP).
 *  SourceFile - The name of the file in which the check occurs.
 *  lineno     - The line number within the file in which the check occurs.
 */
void *
exactcheck_check (void * Source,
                  void * ObjStart,
                  void * ObjEnd,
                  const void * Dest,
                  const char * SourceFile,
                  unsigned int lineno) {

  void * RealDest = const_cast<void*>(Dest);
  void * RealObjStart = ObjStart;
  void * RealObjEnd = ObjEnd;

  /*
   * On entry, we know that the supplied Dest pointer lies outside the 
   * bounds indicated by ObjStart and ObjEnd.  However, it is possible 
   * that Dest, ObjStart, and ObjEnd were all computed from a rewrite
   * pointer.  Test to see if this is the case, and re-run the check
   * if it is.
   *
   * Note that we define pool = NULL.  This forces use of the global
   * pool, which is the only pool that can be used at present.  Change
   * the function to pass in a pool pointer later if need be.
   */
  if (isRewritePtr (Source)) {
    /*
     * Get the real pointer value (which must be outside the bounds 
     * of a valid object, as the pointer was re-written).
     */
    DebugPoolTy * Pool = NULL;
    void * RealSrc = pchk_getActualValue (Pool, Source);

    /*
     * Compute the real result pointer (the value the GEP would really have
     * on the original pointer value).
     */
     RealDest = (void *)((intptr_t) RealSrc + 
                        ((intptr_t) Dest - (intptr_t) Source));

    /*
     * Retrieve the original bounds of the object.
     */
    getOOBObject(Source, RealObjStart, RealObjEnd);

    /* 
     * Re-run the bounds check
     */
    if (__builtin_expect (((RealObjStart <= RealDest) && 
                          ((RealDest <= RealObjEnd))), 1)) {
      if (logregs) {
        fprintf (stderr, "exactcheck:unrewrite(1): %p -> %p, Dest: %p, Obj: %p - %p\n", Source, RealSrc, RealDest, RealObjStart, RealObjEnd);
        fflush (stderr);
      }

      return(RealDest);
    }
  }

  /*
   * At this point, we have that the RealDest pointer is out of range,
   * and that it was not computed from a re-written OOB source pointer.
   *
   * If we indexed off the beginning or end of a valid object, 
   * determine if we can rewrite the pointer into an OOB pointer.  
   * Whether we can or not depends upon the SAFECode configuration.
   */
  if ((!(ConfigData.StrictIndexing)) ||
      (((char *) RealDest) == (((char *)RealObjEnd)+1))) {
    void * ptr = rewrite_ptr (0, RealDest, RealObjStart, RealObjEnd, SourceFile, lineno);
    if (logregs) {
      fprintf (ReportLog,
               "exactcheck: rewrite(1): %p %p %p at pc=%p to %p: %s %d\n",
               RealObjStart, RealObjEnd, RealDest, (void*)__builtin_return_address(0), ptr,
               SourceFile, lineno);
      fflush (ReportLog);
    }

    return ptr;
  } else {
    //
    // Determine if this is a rewrite pointer that is being indexed.
    //
    if ((logregs) && (isRewritePtr ((void *)Dest))) {
      fprintf (stderr, "Was a rewrite: %p\n", Dest);
      fflush (stderr);
    }

    OutOfBoundsViolation v;
    v.type = ViolationInfo::FAULT_OUT_OF_BOUNDS,
      v.faultPC = __builtin_return_address(0),
      v.faultPtr = RealDest,
      v.CWE = CWEBufferOverflow,
      v.PoolHandle = 0,
      v.dbgMetaData = NULL,
      v.SourceFile = SourceFile,
      v.objStart = RealObjStart,
      v.objLen = (unsigned)((const char*)ObjEnd - (const char*)ObjStart + 1),
      v.lineNo = lineno;
    
    ReportMemoryViolation(&v);
  }

  return const_cast<void*>(Dest);

}

#if 0
/// UNUSED CODE

/*
 * Function: exactcheck()
 *
 * Description:
 *  Determine whether the index is within the specified bounds.
 *
 * Inputs:
 *  a      - The index given as an integer.
 *  b      - The index of one past the end of the array.
 *  result - The pointer that is being checked.
 *
 * Return value:
 *  If there is no bounds check violation, the result pointer is returned.
 *  This forces the call to exactcheck() to be considered live (previous
 *  optimizations dead-code eliminated it).
 */
void *
exactcheck (int a, int b, void * result) {
  if ((0 > a) || (a >= b)) {
    ReportExactCheck ((unsigned)0xbeefdeed,
                      (uintptr_t)result,
                      (uintptr_t)__builtin_return_address(0),
                      (unsigned)a,
                      (unsigned)0,
                      "<Unknown>",
                      0);
#if 0
    poolcheckfail ("exact check failed", (a), (void*)__builtin_return_address(0));
    poolcheckfail ("exact check failed", (b), (void*)__builtin_return_address(0));
#endif
  }
  return result;
}


void *
exactcheck3(signed char *base, signed char *result, signed char * end) {
  if ((result < base) || (result > end )) {
    ReportExactCheck ((unsigned)0xbeefbeef,
                      (uintptr_t)result,
                      (uintptr_t)__builtin_return_address(0),
                      (uintptr_t)base,
                      (unsigned)(end-base),
                      "<Unknown>",
                      0);
  }
  return result;
}


void *
exactcheck2a (signed char *base, signed char *result, unsigned size) {
  if (result >= base + size ) {
    ReportExactCheck ((unsigned)0xbeefdeed,
                      (uintptr_t)result,
                      (uintptr_t)__builtin_return_address(0),
                      (uintptr_t)base,
                      (unsigned)size,
                      "<Unknown>",
                      0);
  }
  return result;
}

#endif
