⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bcheck.c

📁 tcc
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (e->start == 0) {        /* no region : add it */        e->start = start;        e->size = size;    } else {        /* already regions in the list: add it at the head */        e1 = bound_new_entry();        e1->start = e->start;        e1->size = e->size;        e1->next = e->next;        e->start = start;        e->size = size;        e->next = e1;    }}/* create a new region. It should not already exist in the region list */void __bound_new_region(void *p, unsigned long size){    unsigned long start, end;    BoundEntry *page, *e, *e2;    int t1_start, t1_end, i, t2_start, t2_end;    start = (unsigned long)p;    end = start + size;    t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);    t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);    /* start */    page = get_page(t1_start);    t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &         ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);    t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &         ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);#ifdef BOUND_DEBUG    printf("new %lx %lx %x %x %x %x\n",            start, end, t1_start, t1_end, t2_start, t2_end);#endif    e = (BoundEntry *)((char *)page + t2_start);    add_region(e, start, size);    if (t1_end == t1_start) {        /* same ending page */        e2 = (BoundEntry *)((char *)page + t2_end);        if (e2 > e) {            e++;            for(;e<e2;e++) {                e->start = start;                e->size = size;            }            add_region(e, start, size);        }    } else {        /* mark until end of page */        e2 = page + BOUND_T2_SIZE;        e++;        for(;e<e2;e++) {            e->start = start;            e->size = size;        }        /* mark intermediate pages, if any */        for(i=t1_start+1;i<t1_end;i++) {            page = get_page(i);            e2 = page + BOUND_T2_SIZE;            for(e=page;e<e2;e++) {                e->start = start;                e->size = size;            }        }        /* last page */        page = get_page(t1_end);        e2 = (BoundEntry *)((char *)page + t2_end);        for(e=page;e<e2;e++) {            e->start = start;            e->size = size;        }        add_region(e, start, size);    }}/* delete a region */static inline void delete_region(BoundEntry *e,                                  void *p, unsigned long empty_size){    unsigned long addr;    BoundEntry *e1;    addr = (unsigned long)p;    addr -= e->start;    if (addr <= e->size) {        /* region found is first one */        e1 = e->next;        if (e1 == NULL) {            /* no more region: mark it empty */            e->start = 0;            e->size = empty_size;        } else {            /* copy next region in head */            e->start = e1->start;            e->size = e1->size;            e->next = e1->next;            bound_free_entry(e1);        }    } else {        /* find the matching region */        for(;;) {            e1 = e;            e = e->next;            /* region not found: do nothing */            if (e == NULL)                break;            addr = (unsigned long)p - e->start;            if (addr <= e->size) {                /* found: remove entry */                e1->next = e->next;                bound_free_entry(e);                break;            }        }    }}/* WARNING: 'p' must be the starting point of the region. *//* return non zero if error */int __bound_delete_region(void *p){    unsigned long start, end, addr, size, empty_size;    BoundEntry *page, *e, *e2;    int t1_start, t1_end, t2_start, t2_end, i;    start = (unsigned long)p;    t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);    t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &         ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);        /* find region size */    page = __bound_t1[t1_start];    e = (BoundEntry *)((char *)page + t2_start);    addr = start - e->start;    if (addr > e->size)        e = __bound_find_region(e, p);    /* test if invalid region */    if (e->size == EMPTY_SIZE || (unsigned long)p != e->start)         return -1;    /* compute the size we put in invalid regions */    if (e->is_invalid)        empty_size = INVALID_SIZE;    else        empty_size = EMPTY_SIZE;    size = e->size;    end = start + size;    /* now we can free each entry */    t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);    t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &         ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);    delete_region(e, p, empty_size);    if (t1_end == t1_start) {        /* same ending page */        e2 = (BoundEntry *)((char *)page + t2_end);        if (e2 > e) {            e++;            for(;e<e2;e++) {                e->start = 0;                e->size = empty_size;            }            delete_region(e, p, empty_size);        }    } else {        /* mark until end of page */        e2 = page + BOUND_T2_SIZE;        e++;        for(;e<e2;e++) {            e->start = 0;            e->size = empty_size;        }        /* mark intermediate pages, if any */        /* XXX: should free them */        for(i=t1_start+1;i<t1_end;i++) {            page = get_page(i);            e2 = page + BOUND_T2_SIZE;            for(e=page;e<e2;e++) {                e->start = 0;                e->size = empty_size;            }        }        /* last page */        page = get_page(t2_end);        e2 = (BoundEntry *)((char *)page + t2_end);        for(e=page;e<e2;e++) {            e->start = 0;            e->size = empty_size;        }        delete_region(e, p, empty_size);    }    return 0;}/* return the size of the region starting at p, or EMPTY_SIZE if non   existant region. */static unsigned long get_region_size(void *p){    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);    if (e->start != (unsigned long)p)        return EMPTY_SIZE;    return e->size;}/* patched memory functions */static void install_malloc_hooks(void){#ifdef CONFIG_TCC_MALLOC_HOOKS    saved_malloc_hook = __malloc_hook;    saved_free_hook = __free_hook;    saved_realloc_hook = __realloc_hook;    saved_memalign_hook = __memalign_hook;    __malloc_hook = __bound_malloc;    __free_hook = __bound_free;    __realloc_hook = __bound_realloc;    __memalign_hook = __bound_memalign;#endif}static void restore_malloc_hooks(void){#ifdef CONFIG_TCC_MALLOC_HOOKS    __malloc_hook = saved_malloc_hook;    __free_hook = saved_free_hook;    __realloc_hook = saved_realloc_hook;    __memalign_hook = saved_memalign_hook;#endif}static void *libc_malloc(size_t size){    void *ptr;    restore_malloc_hooks();    ptr = malloc(size);    install_malloc_hooks();    return ptr;}static void libc_free(void *ptr){    restore_malloc_hooks();    free(ptr);    install_malloc_hooks();}/* XXX: we should use a malloc which ensure that it is unlikely that   two malloc'ed data have the same address if 'free' are made in   between. */void *__bound_malloc(size_t size, const void *caller){    void *ptr;        /* we allocate one more byte to ensure the regions will be       separated by at least one byte. With the glibc malloc, it may       be in fact not necessary */    ptr = libc_malloc(size + 1);        if (!ptr)        return NULL;    __bound_new_region(ptr, size);    return ptr;}void *__bound_memalign(size_t size, size_t align, const void *caller){    void *ptr;    restore_malloc_hooks();#ifndef HAVE_MEMALIGN    if (align > 4) {        /* XXX: handle it ? */        ptr = NULL;    } else {        /* we suppose that malloc aligns to at least four bytes */        ptr = malloc(size + 1);    }#else    /* we allocate one more byte to ensure the regions will be       separated by at least one byte. With the glibc malloc, it may       be in fact not necessary */    ptr = memalign(size + 1, align);#endif        install_malloc_hooks();        if (!ptr)        return NULL;    __bound_new_region(ptr, size);    return ptr;}void __bound_free(void *ptr, const void *caller){    if (ptr == NULL)        return;    if (__bound_delete_region(ptr) != 0)        bound_error("freeing invalid region");    libc_free(ptr);}void *__bound_realloc(void *ptr, size_t size, const void *caller){    void *ptr1;    int old_size;    if (size == 0) {        __bound_free(ptr, caller);        return NULL;    } else {        ptr1 = __bound_malloc(size, caller);        if (ptr == NULL || ptr1 == NULL)            return ptr1;        old_size = get_region_size(ptr);        if (old_size == EMPTY_SIZE)            bound_error("realloc'ing invalid pointer");        memcpy(ptr1, ptr, old_size);        __bound_free(ptr, caller);        return ptr1;    }}#ifndef CONFIG_TCC_MALLOC_HOOKSvoid *__bound_calloc(size_t nmemb, size_t size){    void *ptr;    size = size * nmemb;    ptr = __bound_malloc(size);    if (!ptr)        return NULL;    memset(ptr, 0, size);    return ptr;}#endif#if 0static void bound_dump(void){    BoundEntry *page, *e;    int i, j;    printf("region dump:\n");    for(i=0;i<BOUND_T1_SIZE;i++) {        page = __bound_t1[i];        for(j=0;j<BOUND_T2_SIZE;j++) {            e = page + j;            /* do not print invalid or empty entries */            if (e->size != EMPTY_SIZE && e->start != 0) {                printf("%08x:",                        (i << (BOUND_T2_BITS + BOUND_T3_BITS)) +                        (j << BOUND_T3_BITS));                do {                    printf(" %08lx:%08lx", e->start, e->start + e->size);                    e = e->next;                } while (e != NULL);                printf("\n");            }        }    }}#endif/* some useful checked functions *//* check that (p ... p + size - 1) lies inside 'p' region, if any */static void __bound_check(const void *p, size_t size){    if (size == 0)        return;    p = __bound_ptr_add((void *)p, size);    if (p == INVALID_POINTER)        bound_error("invalid pointer");}void *__bound_memcpy(void *dst, const void *src, size_t size){    __bound_check(dst, size);    __bound_check(src, size);    /* check also region overlap */    if (src >= dst && src < dst + size)        bound_error("overlapping regions in memcpy()");    return memcpy(dst, src, size);}void *__bound_memmove(void *dst, const void *src, size_t size){    __bound_check(dst, size);    __bound_check(src, size);    return memmove(dst, src, size);}void *__bound_memset(void *dst, int c, size_t size){    __bound_check(dst, size);    return memset(dst, c, size);}/* XXX: could be optimized */int __bound_strlen(const char *s){    const char *p;    int len;    len = 0;    for(;;) {        p = __bound_ptr_indir1((char *)s, len);        if (p == INVALID_POINTER)            bound_error("bad pointer in strlen()");        if (*p == '\0')            break;        len++;    }    return len;}char *__bound_strcpy(char *dst, const char *src){    int len;    len = __bound_strlen(src);    return __bound_memcpy(dst, src, len + 1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -