blob: 01e025d4ab155eceb3829ecb84784aa7a98be20a [file] [log] [blame]
//===- PoolAllocator.h - Pool allocator runtime interface file --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// 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 defines the interface which is implemented by the LLVM pool
// allocator runtime library.
//
//===----------------------------------------------------------------------===//
#ifndef POOLALLOCATOR_RUNTIME_H
#define POOLALLOCATOR_RUNTIME_H
#include "safecode/Config/config.h"
#include "poolalloc/ADT/HashExtras.h"
#include "poolalloc_runtime/Support/SplayTree.h"
#include <stdarg.h>
#include <string.h>
#include <map>
#include <utility>
#define AddrArrSize 2
extern unsigned poolmemusage;
//unsigned PCheckPassed = 1;
//
// Structure: DebugMetaData
//
// Description:
// This structure contains information on the error to be reported.
//
// Fields:
// allocID : The ID number of the allocation of the object.
// freeID : The ID number of the deallocation of the object.
// allocPC : The program counter at which the object was last allocated.
// freePC : The program counter at which the object was last deallocated.
// canonAddr : The canonical address of the memory reference.
// SourceFile : A string containing the source file to which the erring
// instruction is found.
// lineno : The line number in the source file to which the erring
// instruction is found.
//
typedef struct DebugMetaData {
unsigned allocID;
unsigned freeID;
void * allocPC;
void * freePC;
void * canonAddr;
// Source filename
void * SourceFile;
// Line number
unsigned lineno;
} DebugMetaData;
typedef DebugMetaData * PDebugMetaData;
typedef struct PoolTy {
// Splay tree used for object registration
RangeSplaySet<> Objects;
#if SC_ENABLE_OOB
// Splay tree used for out of bound objects
RangeSplayMap<void *> OOB;
#endif
// FIXME: should be dangling pointer macro
#if SC_DEBUGTOOL
// Splay tree used by dangling pointer runtime
RangeSplayMap<PDebugMetaData> DPTree;
#endif
// Linked list of slabs used for stack allocations
void * StackSlabs;
// Linked list of slabs available for stack allocations
void * FreeStackSlabs;
// Ptr1, Ptr2 - Implementation specified data pointers.
void *Ptr1, *Ptr2;
// NodeSize - Keep track of the object size tracked by this pool
unsigned short NodeSize;
// FreeablePool - Set to false if the memory from this pool cannot be freed
// before destroy.
//
// unsigned short FreeablePool;
// Use the hash_set only if the number of Slabs exceeds AddrArrSize
hash_set<void*> *Slabs;
// The array containing the initial address of slabs (as long as there are
// fewer than a certain number of them)
void* SlabAddressArray[AddrArrSize];
// The number of slabs allocated. Large arrays are not counted
unsigned NumSlabs;
// Large arrays. In SAFECode, these are currently not freed or reused.
// A better implementation could split them up into single slabs for reuse,
// upon being freed.
void *LargeArrays;
void *FreeLargeArrays;
void *prevPage[4];
unsigned short lastUsed;
// Interpretation of AllocadPool variable in original SAFECode:
// AllocadPool = -1 : unused so far
// AllocadPool 0 : used only for mallocs
// AllocadPool >0 : used for only allocas indicating the size
short AllocadPool;
void *allocaptr;
#if 0
std::map<void *,unsigned> * RegNodes;
#endif
} PoolTy;
extern "C" {
void pool_init_runtime(unsigned Dangling,
unsigned RewriteOOB,
unsigned Terminate);
void poolinit(PoolTy *Pool, unsigned NodeSize);
void poolmakeunfreeable(PoolTy *Pool);
void pooldestroy(PoolTy *Pool);
void * poolalloc(PoolTy *Pool, unsigned NumBytes);
void * poolrealloc(PoolTy *Pool, void *Node, unsigned NumBytes);
void * poolcalloc (PoolTy *Pool, unsigned Number, unsigned NumBytes);
void * poolstrdup(PoolTy *Pool, char *Node);
void poolargvregister (int argc, char ** argv);
void poolregister(PoolTy *Pool, void *allocaptr, unsigned NumBytes);
void poolunregister(PoolTy *Pool, void *allocaptr);
void pool_protect_object (void * Node);
void poolfree(PoolTy *Pool, void *Node);
void poolcheck(PoolTy *Pool, void *Node);
void poolcheckui(PoolTy *Pool, void *Node);
void poolcheckoptim(PoolTy *Pool, void *Node);
void * boundscheck (PoolTy * Pool, void * Source, void * Dest);
int boundscheckui_lookup (PoolTy * Pool, void * Source) __attribute__ ((const, noinline));
void * boundscheckui_check (int len, PoolTy * Pool, void * Source, void * Dest) __attribute__ ((noinline));
void * boundscheckui (PoolTy * Pool, void * Source, void * Dest);
void funccheck (unsigned num, void *f, void *g, ...);
void poolstats(void);
void poolcheckalign(PoolTy *Pool, void *Node, unsigned Offset);
void pool_newstack (PoolTy * Pool);
void pool_delstack (PoolTy * Pool);
void * pool_alloca (PoolTy * Pool, unsigned int NumBytes);
void * rewrite_ptr (PoolTy *, void *, void *, void *, void *, unsigned);
void * poolalloc_debug (PoolTy *P, unsigned Size, void * SrcFle, unsigned no);
void * poolcalloc_debug (PoolTy *P, unsigned Num, unsigned Size, void * S, unsigned no);
void poolregister_debug (PoolTy *P, void * p, unsigned size, void * SF,
unsigned lineno);
void poolfree_debug (PoolTy *P, void * ptr, void * SrcFle, unsigned no);
void poolcheck_debug (PoolTy *P, void * Node, void * SrcFle, unsigned no);
void poolcheckalign_debug (PoolTy *P, void *Node, unsigned Offset, void * SourceFile, unsigned lineno);
void * boundscheck_debug (PoolTy * P, void * S, void * D, void * SFile, unsigned int lineno);
void * boundscheckui_debug (PoolTy * P, void * S, void * D, void * SFile, unsigned int lineno);
void * pchk_getActualValue (PoolTy * Pool, void * src);
//void protect_shadowpage();
// Barebone allocators, which only do allocations
// They should not be used directly.
void __barebone_poolinit(PoolTy *Pool, unsigned NodeSize);
void __barebone_pooldestroy(PoolTy *Pool);
void __barebone_poolfree(PoolTy *Pool, void *Node);
void * __barebone_poolalloc(PoolTy *Pool, unsigned NumBytes);
void * __barebone_pool_alloca(PoolTy * Pool, unsigned int NumBytes);
}
/// Template class to implement
/// realloc, calloc, strdup based on a particular implementation
/// of a pool allocator
template <class AllocatorT>
class PoolAllocatorFacade {
PoolAllocatorFacade();
~PoolAllocatorFacade();
public:
typedef typename AllocatorT::PoolT PoolT;
static void * realloc(PoolT * Pool, void * Node, unsigned NumBytes) {
if (Node == 0) return AllocatorT::poolalloc(Pool, NumBytes);
if (NumBytes == 0) {
poolfree(Pool, Node);
return 0;
}
void *New = AllocatorT::poolalloc(Pool, NumBytes);
memcpy(New, Node, NumBytes);
AllocatorT::poolfree(Pool, Node);
return New;
}
static void * calloc(PoolT *Pool, unsigned Number, unsigned NumBytes) {
void * New = AllocatorT::poolalloc (Pool, Number * NumBytes);
if (New) bzero (New, Number * NumBytes);
return New;
}
static void * strdup(PoolT *Pool, char *Node) {
if (Node == 0) return 0;
unsigned int NumBytes = strlen(Node) + 1;
void *New = AllocatorT::poolalloc(Pool, NumBytes);
if (New) {
memcpy(New, Node, NumBytes+1);
}
return New;
}
};
#endif