Alien-TinyCC

 view release on metacpan or  search on metacpan

src/lib/bcheck.c  view on Meta::CPAN

static void bound_alloc_error(void)
{
    bound_error("not enough memory for bound checking code");
}

/* return '(p + offset)' for pointer arithmetic (a pointer can reach
   the end of a region in this case */
void * FASTCALL __bound_ptr_add(void *p, int offset)
{
    unsigned long addr = (unsigned long)p;
    BoundEntry *e;
#if defined(BOUND_DEBUG)
    printf("add: 0x%x %d\n", (int)p, offset);
#endif

    e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
    e = (BoundEntry *)((char *)e + 
                       ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
                        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
    addr -= e->start;
    if (addr > e->size) {
        e = __bound_find_region(e, p);
        addr = (unsigned long)p - e->start;
    }
    addr += offset;
    if (addr > e->size)
        return INVALID_POINTER; /* return an invalid pointer */
    return p + offset;
}

/* return '(p + offset)' for pointer indirection (the resulting must
   be strictly inside the region */
#define BOUND_PTR_INDIR(dsize)                                          \
void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset)        \
{                                                                       \
    unsigned long addr = (unsigned long)p;                              \
    BoundEntry *e;                                                      \
                                                                        \
    e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];            \
    e = (BoundEntry *)((char *)e +                                      \
                       ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &      \
                        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));        \
    addr -= e->start;                                                   \
    if (addr > e->size) {                                               \
        e = __bound_find_region(e, p);                                  \
        addr = (unsigned long)p - e->start;                             \
    }                                                                   \
    addr += offset + dsize;                                             \
    if (addr > e->size)                                                 \
        return INVALID_POINTER; /* return an invalid pointer */         \
    return p + offset;                                                  \
}

BOUND_PTR_INDIR(1)
BOUND_PTR_INDIR(2)
BOUND_PTR_INDIR(4)
BOUND_PTR_INDIR(8)
BOUND_PTR_INDIR(12)
BOUND_PTR_INDIR(16)

/* return the frame pointer of the caller */
#define GET_CALLER_FP(fp)\
{\
    fp = (unsigned long)__builtin_frame_address(1);\
}

/* called when entering a function to add all the local regions */
void FASTCALL __bound_local_new(void *p1) 
{
    unsigned long addr, size, fp, *p = p1;
    GET_CALLER_FP(fp);
    for(;;) {
        addr = p[0];
        if (addr == 0)
            break;
        addr += fp;
        size = p[1];
        p += 2;
        __bound_new_region((void *)addr, size);
    }
}

/* called when leaving a function to delete all the local regions */
void FASTCALL __bound_local_delete(void *p1) 
{
    unsigned long addr, fp, *p = p1;
    GET_CALLER_FP(fp);
    for(;;) {
        addr = p[0];
        if (addr == 0)
            break;
        addr += fp;
        p += 2;
        __bound_delete_region((void *)addr);
    }
}

static BoundEntry *__bound_new_page(void)
{
    BoundEntry *page;
    int i;

    page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE);
    if (!page)
        bound_alloc_error();
    for(i=0;i<BOUND_T2_SIZE;i++) {
        /* put empty entries */
        page[i].start = 0;
        page[i].size = EMPTY_SIZE;
        page[i].next = NULL;
        page[i].is_invalid = 0;
    }
    return page;
}

/* currently we use malloc(). Should use bound_new_page() */
static BoundEntry *bound_new_entry(void)
{
    BoundEntry *e;
    e = libc_malloc(sizeof(BoundEntry));
    return e;
}

static void bound_free_entry(BoundEntry *e)



( run in 1.003 second using v1.01-cache-2.11-cpan-df04353d9ac )