[BACK]Return to ptr_chck.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / gc

Annotation of OpenXM_contrib2/asir2000/gc/ptr_chck.c, Revision 1.5

1.1       noro        1: /*
                      2:  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
                      3:  *
                      4:  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
                      5:  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
                      6:  *
                      7:  * Permission is hereby granted to use or copy this program
                      8:  * for any purpose,  provided the above notices are retained on all copies.
                      9:  * Permission to modify the code and to distribute modified code is granted,
                     10:  * provided the above notices are retained, and a notice that the code was
                     11:  * modified is included with the above copyright notice.
                     12:  */
                     13:
1.2       noro       14: /*
                     15:  * These are checking routines calls to which could be inserted by a
                     16:  * preprocessor to validate C pointer arithmetic.
                     17:  */
                     18:
                     19: #include "private/gc_pmark.h"
1.1       noro       20:
                     21: #ifdef __STDC__
                     22: void GC_default_same_obj_print_proc(GC_PTR p, GC_PTR q)
                     23: #else
                     24: void GC_default_same_obj_print_proc (p, q)
                     25: GC_PTR p, q;
                     26: #endif
                     27: {
                     28:     GC_err_printf2("0x%lx and 0x%lx are not in the same object\n",
                     29:                   (unsigned long)p, (unsigned long)q);
                     30:     ABORT("GC_same_obj test failed");
                     31: }
                     32:
                     33: void (*GC_same_obj_print_proc) GC_PROTO((GC_PTR, GC_PTR))
                     34:                = GC_default_same_obj_print_proc;
                     35:
                     36: /* Check that p and q point to the same object.  Call          */
                     37: /* *GC_same_obj_print_proc if they don't.                      */
                     38: /* Returns the first argument.  (Return value may be hard      */
                     39: /* to use,due to typing issues.  But if we had a suitable      */
                     40: /* preprocessor ...)                                           */
                     41: /* Succeeds if neither p nor q points to the heap.             */
                     42: /* We assume this is performance critical.  (It shouldn't      */
                     43: /* be called by production code, but this can easily make      */
                     44: /* debugging intolerably slow.)                                        */
                     45: #ifdef __STDC__
                     46:   GC_PTR GC_same_obj(register void *p, register void *q)
                     47: #else
                     48:   GC_PTR GC_same_obj(p, q)
                     49:   register char *p, *q;
                     50: #endif
                     51: {
                     52:     register struct hblk *h;
                     53:     register hdr *hhdr;
                     54:     register ptr_t base, limit;
                     55:     register word sz;
                     56:
                     57:     if (!GC_is_initialized) GC_init();
                     58:     hhdr = HDR((word)p);
                     59:     if (hhdr == 0) {
                     60:        if (divHBLKSZ((word)p) != divHBLKSZ((word)q)
                     61:            && HDR((word)q) != 0) {
                     62:            goto fail;
                     63:        }
                     64:        return(p);
                     65:     }
                     66:     /* If it's a pointer to the middle of a large object, move it      */
                     67:     /* to the beginning.                                               */
                     68:     if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
                     69:        h = HBLKPTR(p) - (word)hhdr;
                     70:        hhdr = HDR(h);
                     71:        while (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
                     72:           h = FORWARDED_ADDR(h, hhdr);
                     73:           hhdr = HDR(h);
                     74:        }
1.2       noro       75:        limit = (ptr_t)((word *)h + hhdr -> hb_sz);
1.1       noro       76:        if ((ptr_t)p >= limit || (ptr_t)q >= limit || (ptr_t)q < (ptr_t)h ) {
                     77:            goto fail;
                     78:        }
                     79:        return(p);
                     80:     }
                     81:     sz = WORDS_TO_BYTES(hhdr -> hb_sz);
1.5     ! noro       82:     if (sz > MAXOBJBYTES) {
1.1       noro       83:       base = (ptr_t)HBLKPTR(p);
                     84:       limit = base + sz;
                     85:       if ((ptr_t)p >= limit) {
                     86:         goto fail;
                     87:       }
                     88:     } else {
1.2       noro       89:       register int map_entry;
                     90:       register int pdispl = HBLKDISPL(p);
                     91:
                     92:       map_entry = MAP_ENTRY((hhdr -> hb_map), pdispl);
                     93:       if (map_entry > CPP_MAX_OFFSET) {
                     94:          map_entry = BYTES_TO_WORDS(pdispl) % BYTES_TO_WORDS(sz);
                     95:         if (HBLKPTR(p) != HBLKPTR(q)) goto fail;
                     96:                /* W/o this check, we might miss an error if    */
                     97:                /* q points to the first object on a page, and  */
                     98:                /* points just before the page.                 */
                     99:       }
                    100:       base = (char *)((word)p & ~(WORDS_TO_BYTES(1) - 1));
                    101:       base -= WORDS_TO_BYTES(map_entry);
1.1       noro      102:       limit = base + sz;
                    103:     }
                    104:     /* [base, limit) delimits the object containing p, if any. */
                    105:     /* If p is not inside a valid object, then either q is     */
                    106:     /* also outside any valid object, or it is outside                 */
                    107:     /* [base, limit).                                          */
                    108:     if ((ptr_t)q >= limit || (ptr_t)q < base) {
                    109:        goto fail;
                    110:     }
                    111:     return(p);
                    112: fail:
                    113:     (*GC_same_obj_print_proc)((ptr_t)p, (ptr_t)q);
                    114:     return(p);
                    115: }
                    116:
                    117: #ifdef __STDC__
                    118: void GC_default_is_valid_displacement_print_proc (GC_PTR p)
                    119: #else
                    120: void GC_default_is_valid_displacement_print_proc (p)
                    121: GC_PTR p;
                    122: #endif
                    123: {
                    124:     GC_err_printf1("0x%lx does not point to valid object displacement\n",
                    125:                   (unsigned long)p);
                    126:     ABORT("GC_is_valid_displacement test failed");
                    127: }
                    128:
                    129: void (*GC_is_valid_displacement_print_proc) GC_PROTO((GC_PTR)) =
                    130:        GC_default_is_valid_displacement_print_proc;
                    131:
                    132: /* Check that if p is a pointer to a heap page, then it points to      */
                    133: /* a valid displacement within a heap object.                          */
1.2       noro      134: /* Uninteresting with GC_all_interior_pointers.                                */
1.1       noro      135: /* Always returns its argument.                                                */
                    136: /* Note that we don't lock, since nothing relevant about the header    */
                    137: /* should change while we have a valid object pointer to the block.    */
                    138: #ifdef __STDC__
                    139:   void * GC_is_valid_displacement(void *p)
                    140: #else
                    141:   char *GC_is_valid_displacement(p)
                    142:   char *p;
                    143: #endif
                    144: {
                    145:     register hdr *hhdr;
                    146:     register word pdispl;
                    147:     register struct hblk *h;
                    148:     register map_entry_type map_entry;
                    149:     register word sz;
                    150:
                    151:     if (!GC_is_initialized) GC_init();
                    152:     hhdr = HDR((word)p);
                    153:     if (hhdr == 0) return(p);
                    154:     h = HBLKPTR(p);
1.2       noro      155:     if (GC_all_interior_pointers) {
1.1       noro      156:        while (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
                    157:           h = FORWARDED_ADDR(h, hhdr);
                    158:           hhdr = HDR(h);
                    159:        }
1.2       noro      160:     }
1.1       noro      161:     if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
                    162:        goto fail;
                    163:     }
                    164:     sz = WORDS_TO_BYTES(hhdr -> hb_sz);
                    165:     pdispl = HBLKDISPL(p);
                    166:     map_entry = MAP_ENTRY((hhdr -> hb_map), pdispl);
                    167:     if (map_entry == OBJ_INVALID
1.5     ! noro      168:        || sz > MAXOBJBYTES && (ptr_t)p >= (ptr_t)h + sz) {
1.1       noro      169:        goto fail;
                    170:     }
                    171:     return(p);
                    172: fail:
                    173:     (*GC_is_valid_displacement_print_proc)((ptr_t)p);
                    174:     return(p);
                    175: }
                    176:
                    177: #ifdef __STDC__
                    178: void GC_default_is_visible_print_proc(GC_PTR p)
                    179: #else
                    180: void GC_default_is_visible_print_proc(p)
                    181: GC_PTR p;
                    182: #endif
                    183: {
                    184:     GC_err_printf1("0x%lx is not a GC visible pointer location\n",
                    185:                   (unsigned long)p);
                    186:     ABORT("GC_is_visible test failed");
                    187: }
                    188:
                    189: void (*GC_is_visible_print_proc) GC_PROTO((GC_PTR p)) =
                    190:        GC_default_is_visible_print_proc;
                    191:
                    192: /* Could p be a stack address? */
                    193: GC_bool GC_on_stack(p)
                    194: ptr_t p;
                    195: {
                    196: #   ifdef THREADS
                    197:        return(TRUE);
                    198: #   else
                    199:        int dummy;
                    200: #      ifdef STACK_GROWS_DOWN
                    201:            if ((ptr_t)p >= (ptr_t)(&dummy) && (ptr_t)p < GC_stackbottom ) {
                    202:                return(TRUE);
                    203:            }
                    204: #      else
                    205:            if ((ptr_t)p <= (ptr_t)(&dummy) && (ptr_t)p > GC_stackbottom ) {
                    206:                return(TRUE);
                    207:            }
                    208: #      endif
                    209:        return(FALSE);
                    210: #   endif
                    211: }
                    212:
                    213: /* Check that p is visible                                             */
                    214: /* to the collector as a possibly pointer containing location.         */
                    215: /* If it isn't invoke *GC_is_visible_print_proc.                       */
                    216: /* Returns the argument in all cases.  May erroneously succeed         */
                    217: /* in hard cases.  (This is intended for debugging use with            */
                    218: /* untyped allocations.  The idea is that it should be possible, though        */
                    219: /* slow, to add such a call to all indirect pointer stores.)           */
                    220: /* Currently useless for multithreaded worlds.                         */
                    221: #ifdef __STDC__
                    222:   void * GC_is_visible(void *p)
                    223: #else
                    224:   char *GC_is_visible(p)
                    225:   char *p;
                    226: #endif
                    227: {
                    228:     register hdr *hhdr;
                    229:
                    230:     if ((word)p & (ALIGNMENT - 1)) goto fail;
                    231:     if (!GC_is_initialized) GC_init();
                    232: #   ifdef THREADS
                    233:        hhdr = HDR((word)p);
                    234:         if (hhdr != 0 && GC_base(p) == 0) {
                    235:             goto fail;
                    236:         } else {
                    237:             /* May be inside thread stack.  We can't do much. */
                    238:             return(p);
                    239:         }
                    240: #   else
                    241:        /* Check stack first: */
                    242:          if (GC_on_stack(p)) return(p);
                    243:        hhdr = HDR((word)p);
                    244:        if (hhdr == 0) {
                    245:            GC_bool result;
                    246:
                    247:            if (GC_is_static_root(p)) return(p);
                    248:            /* Else do it again correctly:      */
1.2       noro      249: #           if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || \
                    250:                defined(MSWINCE) || defined(PCR)) \
1.1       noro      251:                 && !defined(SRC_M3)
                    252:                DISABLE_SIGNALS();
                    253:                GC_register_dynamic_libraries();
                    254:                result = GC_is_static_root(p);
                    255:                ENABLE_SIGNALS();
                    256:                if (result) return(p);
                    257: #          endif
                    258:            goto fail;
                    259:        } else {
                    260:            /* p points to the heap. */
                    261:            word descr;
                    262:            ptr_t base = GC_base(p);    /* Should be manually inlined? */
                    263:
                    264:            if (base == 0) goto fail;
                    265:            if (HBLKPTR(base) != HBLKPTR(p)) hhdr = HDR((word)p);
                    266:            descr = hhdr -> hb_descr;
                    267:     retry:
1.2       noro      268:            switch(descr & GC_DS_TAGS) {
                    269:                case GC_DS_LENGTH:
1.1       noro      270:                    if ((word)((ptr_t)p - (ptr_t)base) > (word)descr) goto fail;
                    271:                    break;
1.2       noro      272:                case GC_DS_BITMAP:
1.1       noro      273:                    if ((ptr_t)p - (ptr_t)base
                    274:                         >= WORDS_TO_BYTES(BITMAP_BITS)
                    275:                         || ((word)p & (sizeof(word) - 1))) goto fail;
                    276:                    if (!((1 << (WORDSZ - ((ptr_t)p - (ptr_t)base) - 1))
                    277:                          & descr)) goto fail;
                    278:                    break;
1.2       noro      279:                case GC_DS_PROC:
1.1       noro      280:                    /* We could try to decipher this partially.         */
                    281:                    /* For now we just punt.                            */
                    282:                    break;
1.2       noro      283:                case GC_DS_PER_OBJECT:
                    284:                    if ((signed_word)descr >= 0) {
                    285:                      descr = *(word *)((ptr_t)base + (descr & ~GC_DS_TAGS));
                    286:                    } else {
                    287:                      ptr_t type_descr = *(ptr_t *)base;
                    288:                      descr = *(word *)(type_descr
                    289:                              - (descr - (GC_DS_PER_OBJECT
                    290:                                          - GC_INDIR_PER_OBJ_BIAS)));
                    291:                    }
1.1       noro      292:                    goto retry;
                    293:            }
                    294:            return(p);
                    295:        }
                    296: #   endif
                    297: fail:
                    298:     (*GC_is_visible_print_proc)((ptr_t)p);
                    299:     return(p);
                    300: }
                    301:
                    302:
                    303: GC_PTR GC_pre_incr (p, how_much)
                    304: GC_PTR *p;
                    305: size_t how_much;
                    306: {
                    307:     GC_PTR initial = *p;
                    308:     GC_PTR result = GC_same_obj((GC_PTR)((word)initial + how_much), initial);
                    309:
1.2       noro      310:     if (!GC_all_interior_pointers) {
1.1       noro      311:        (void) GC_is_valid_displacement(result);
1.2       noro      312:     }
1.1       noro      313:     return (*p = result);
                    314: }
                    315:
                    316: GC_PTR GC_post_incr (p, how_much)
                    317: GC_PTR *p;
                    318: size_t how_much;
                    319: {
                    320:     GC_PTR initial = *p;
                    321:     GC_PTR result = GC_same_obj((GC_PTR)((word)initial + how_much), initial);
                    322:
1.2       noro      323:     if (!GC_all_interior_pointers) {
1.1       noro      324:        (void) GC_is_valid_displacement(result);
1.2       noro      325:     }
1.1       noro      326:     *p = result;
                    327:     return(initial);
                    328: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>