sb-bsd-sockets: check for MAKE-ALIEN success in GET-PROTOCOL-BY-NAME
[sbcl.git] / src / runtime / gc-common.c
index cc76f5c..96de172 100644 (file)
@@ -1885,7 +1885,7 @@ scav_lose(lispobj *where, lispobj object)
 {
     lose("no scavenge function for object 0x%08x (widetag 0x%x)\n",
          (unsigned long)object,
-         widetag_of(object));
+         widetag_of(*where));
 
     return 0; /* bogus return value to satisfy static type checking */
 }
@@ -1904,7 +1904,7 @@ size_lose(lispobj *where)
 {
     lose("no size function for object at 0x%08x (widetag 0x%x)\n",
          (unsigned long)where,
-         widetag_of(LOW_WORD(where)));
+         widetag_of(*where));
     return 1; /* bogus return value to satisfy static type checking */
 }
 
@@ -1916,7 +1916,7 @@ size_lose(lispobj *where)
 void
 gc_init_tables(void)
 {
-    unsigned long i;
+    unsigned long i, j;
 
     /* Set default value in all slots of scavenge table.  FIXME
      * replace this gnarly sizeof with something based on
@@ -1931,11 +1931,14 @@ gc_init_tables(void)
      */
 
     for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) {
-        scavtab[EVEN_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_immediate;
+        for (j = 0; j < (1<<N_LOWTAG_BITS); j++) {
+            if (fixnump(j)) {
+                scavtab[j|(i<<N_LOWTAG_BITS)] = scav_immediate;
+            }
+        }
         scavtab[FUN_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_fun_pointer;
         /* skipping OTHER_IMMEDIATE_0_LOWTAG */
         scavtab[LIST_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_list_pointer;
-        scavtab[ODD_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_immediate;
         scavtab[INSTANCE_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] =
             scav_instance_pointer;
         /* skipping OTHER_IMMEDIATE_1_LOWTAG */
@@ -1984,16 +1987,16 @@ gc_init_tables(void)
         scav_vector_unsigned_byte_16;
     scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
         scav_vector_unsigned_byte_16;
-#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
-    scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
+#if (N_WORD_BITS == 32)
+    scavtab[SIMPLE_ARRAY_UNSIGNED_FIXNUM_WIDETAG] =
         scav_vector_unsigned_byte_32;
 #endif
     scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
         scav_vector_unsigned_byte_32;
     scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
         scav_vector_unsigned_byte_32;
-#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
-    scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
+#if (N_WORD_BITS == 64)
+    scavtab[SIMPLE_ARRAY_UNSIGNED_FIXNUM_WIDETAG] =
         scav_vector_unsigned_byte_64;
 #endif
 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
@@ -2011,16 +2014,16 @@ gc_init_tables(void)
     scavtab[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
         scav_vector_unsigned_byte_16;
 #endif
-#ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
-    scavtab[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
+#if (N_WORD_BITS == 32)
+    scavtab[SIMPLE_ARRAY_FIXNUM_WIDETAG] =
         scav_vector_unsigned_byte_32;
 #endif
 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
     scavtab[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
         scav_vector_unsigned_byte_32;
 #endif
-#ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
-    scavtab[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
+#if (N_WORD_BITS == 64)
+    scavtab[SIMPLE_ARRAY_FIXNUM_WIDETAG] =
         scav_vector_unsigned_byte_64;
 #endif
 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
@@ -2122,16 +2125,16 @@ gc_init_tables(void)
         trans_vector_unsigned_byte_16;
     transother[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
         trans_vector_unsigned_byte_16;
-#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
-    transother[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
+#if (N_WORD_BITS == 32)
+    transother[SIMPLE_ARRAY_UNSIGNED_FIXNUM_WIDETAG] =
         trans_vector_unsigned_byte_32;
 #endif
     transother[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
         trans_vector_unsigned_byte_32;
     transother[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
         trans_vector_unsigned_byte_32;
-#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
-    transother[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
+#if (N_WORD_BITS == 64)
+    transother[SIMPLE_ARRAY_UNSIGNED_FIXNUM_WIDETAG] =
         trans_vector_unsigned_byte_64;
 #endif
 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
@@ -2150,16 +2153,16 @@ gc_init_tables(void)
     transother[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
         trans_vector_unsigned_byte_16;
 #endif
-#ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
-    transother[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
+#if (N_WORD_BITS == 32)
+    transother[SIMPLE_ARRAY_FIXNUM_WIDETAG] =
         trans_vector_unsigned_byte_32;
 #endif
 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
     transother[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
         trans_vector_unsigned_byte_32;
 #endif
-#ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
-    transother[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
+#if (N_WORD_BITS == 64)
+    transother[SIMPLE_ARRAY_FIXNUM_WIDETAG] =
         trans_vector_unsigned_byte_64;
 #endif
 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
@@ -2213,11 +2216,14 @@ gc_init_tables(void)
     for (i = 0; i < ((sizeof sizetab)/(sizeof sizetab[0])); i++)
         sizetab[i] = size_lose;
     for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) {
-        sizetab[EVEN_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = size_immediate;
+        for (j = 0; j < (1<<N_LOWTAG_BITS); j++) {
+            if (fixnump(j)) {
+                sizetab[j|(i<<N_LOWTAG_BITS)] = size_immediate;
+            }
+        }
         sizetab[FUN_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
         /* skipping OTHER_IMMEDIATE_0_LOWTAG */
         sizetab[LIST_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
-        sizetab[ODD_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = size_immediate;
         sizetab[INSTANCE_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
         /* skipping OTHER_IMMEDIATE_1_LOWTAG */
         sizetab[OTHER_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
@@ -2263,16 +2269,16 @@ gc_init_tables(void)
         size_vector_unsigned_byte_16;
     sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
         size_vector_unsigned_byte_16;
-#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
-    sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
+#if (N_WORD_BITS == 32)
+    sizetab[SIMPLE_ARRAY_UNSIGNED_FIXNUM_WIDETAG] =
         size_vector_unsigned_byte_32;
 #endif
     sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
         size_vector_unsigned_byte_32;
     sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
         size_vector_unsigned_byte_32;
-#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
-    sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
+#if (N_WORD_BITS == 64)
+    sizetab[SIMPLE_ARRAY_UNSIGNED_FIXNUM_WIDETAG] =
         size_vector_unsigned_byte_64;
 #endif
 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
@@ -2290,16 +2296,16 @@ gc_init_tables(void)
     sizetab[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
         size_vector_unsigned_byte_16;
 #endif
-#ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
-    sizetab[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
+#if (N_WORD_BITS == 32)
+    sizetab[SIMPLE_ARRAY_FIXNUM_WIDETAG] =
         size_vector_unsigned_byte_32;
 #endif
 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
     sizetab[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
         size_vector_unsigned_byte_32;
 #endif
-#ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
-    sizetab[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
+#if (N_WORD_BITS == 64)
+    sizetab[SIMPLE_ARRAY_FIXNUM_WIDETAG] =
         size_vector_unsigned_byte_64;
 #endif
 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
@@ -2403,6 +2409,236 @@ gc_search_space(lispobj *start, size_t words, lispobj *pointer)
     return (NULL);
 }
 
+/* Helper for valid_lisp_pointer_p (below) and
+ * possibly_valid_dynamic_space_pointer (gencgc).
+ *
+ * pointer is the pointer to validate, and start_addr is the address
+ * of the enclosing object.
+ */
+int
+looks_like_valid_lisp_pointer_p(lispobj *pointer, lispobj *start_addr)
+{
+    if (!is_lisp_pointer((lispobj)pointer)) {
+        return 0;
+    }
+
+    /* Check that the object pointed to is consistent with the pointer
+     * low tag. */
+    switch (lowtag_of((lispobj)pointer)) {
+    case FUN_POINTER_LOWTAG:
+        /* Start_addr should be the enclosing code object, or a closure
+         * header. */
+        switch (widetag_of(*start_addr)) {
+        case CODE_HEADER_WIDETAG:
+          /* Make sure we actually point to a function in the code object,
+           * as opposed to a random point there. */
+          if (SIMPLE_FUN_HEADER_WIDETAG==widetag_of(*((lispobj *)(((unsigned long)pointer)-FUN_POINTER_LOWTAG))))
+            return 1;
+          else
+            return 0;
+        case CLOSURE_HEADER_WIDETAG:
+        case FUNCALLABLE_INSTANCE_HEADER_WIDETAG:
+            if ((unsigned long)pointer !=
+                ((unsigned long)start_addr+FUN_POINTER_LOWTAG)) {
+                return 0;
+            }
+            break;
+        default:
+            return 0;
+        }
+        break;
+    case LIST_POINTER_LOWTAG:
+        if ((unsigned long)pointer !=
+            ((unsigned long)start_addr+LIST_POINTER_LOWTAG)) {
+            return 0;
+        }
+        /* Is it plausible cons? */
+        if ((is_lisp_pointer(start_addr[0]) ||
+             is_lisp_immediate(start_addr[0])) &&
+            (is_lisp_pointer(start_addr[1]) ||
+             is_lisp_immediate(start_addr[1])))
+            break;
+        else {
+            return 0;
+        }
+    case INSTANCE_POINTER_LOWTAG:
+        if ((unsigned long)pointer !=
+            ((unsigned long)start_addr+INSTANCE_POINTER_LOWTAG)) {
+            return 0;
+        }
+        if (widetag_of(start_addr[0]) != INSTANCE_HEADER_WIDETAG) {
+            return 0;
+        }
+        break;
+    case OTHER_POINTER_LOWTAG:
+
+#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
+        /* The all-architecture test below is good as far as it goes,
+         * but an LRA object is similar to a FUN-POINTER: It is
+         * embedded within a CODE-OBJECT pointed to by start_addr, and
+         * cannot be found by simply walking the heap, therefore we
+         * need to check for it. -- AB, 2010-Jun-04 */
+        if ((widetag_of(start_addr[0]) == CODE_HEADER_WIDETAG)) {
+            lispobj *potential_lra =
+                (lispobj *)(((unsigned long)pointer) - OTHER_POINTER_LOWTAG);
+            if ((widetag_of(potential_lra[0]) == RETURN_PC_HEADER_WIDETAG) &&
+                ((potential_lra - HeaderValue(potential_lra[0])) == start_addr)) {
+                return 1; /* It's as good as we can verify. */
+            }
+        }
+#endif
+
+        if ((unsigned long)pointer !=
+            ((unsigned long)start_addr+OTHER_POINTER_LOWTAG)) {
+            return 0;
+        }
+        /* Is it plausible?  Not a cons. XXX should check the headers. */
+        if (is_lisp_pointer(start_addr[0]) || ((start_addr[0] & 3) == 0)) {
+            return 0;
+        }
+        switch (widetag_of(start_addr[0])) {
+        case UNBOUND_MARKER_WIDETAG:
+        case NO_TLS_VALUE_MARKER_WIDETAG:
+        case CHARACTER_WIDETAG:
+#if N_WORD_BITS == 64
+        case SINGLE_FLOAT_WIDETAG:
+#endif
+            return 0;
+
+            /* only pointed to by function pointers? */
+        case CLOSURE_HEADER_WIDETAG:
+        case FUNCALLABLE_INSTANCE_HEADER_WIDETAG:
+            return 0;
+
+        case INSTANCE_HEADER_WIDETAG:
+            return 0;
+
+            /* the valid other immediate pointer objects */
+        case SIMPLE_VECTOR_WIDETAG:
+        case RATIO_WIDETAG:
+        case COMPLEX_WIDETAG:
+#ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
+        case COMPLEX_SINGLE_FLOAT_WIDETAG:
+#endif
+#ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
+        case COMPLEX_DOUBLE_FLOAT_WIDETAG:
+#endif
+#ifdef COMPLEX_LONG_FLOAT_WIDETAG
+        case COMPLEX_LONG_FLOAT_WIDETAG:
+#endif
+        case SIMPLE_ARRAY_WIDETAG:
+        case COMPLEX_BASE_STRING_WIDETAG:
+#ifdef COMPLEX_CHARACTER_STRING_WIDETAG
+        case COMPLEX_CHARACTER_STRING_WIDETAG:
+#endif
+        case COMPLEX_VECTOR_NIL_WIDETAG:
+        case COMPLEX_BIT_VECTOR_WIDETAG:
+        case COMPLEX_VECTOR_WIDETAG:
+        case COMPLEX_ARRAY_WIDETAG:
+        case VALUE_CELL_HEADER_WIDETAG:
+        case SYMBOL_HEADER_WIDETAG:
+        case FDEFN_WIDETAG:
+        case CODE_HEADER_WIDETAG:
+        case BIGNUM_WIDETAG:
+#if N_WORD_BITS != 64
+        case SINGLE_FLOAT_WIDETAG:
+#endif
+        case DOUBLE_FLOAT_WIDETAG:
+#ifdef LONG_FLOAT_WIDETAG
+        case LONG_FLOAT_WIDETAG:
+#endif
+        case SIMPLE_BASE_STRING_WIDETAG:
+#ifdef SIMPLE_CHARACTER_STRING_WIDETAG
+        case SIMPLE_CHARACTER_STRING_WIDETAG:
+#endif
+        case SIMPLE_BIT_VECTOR_WIDETAG:
+        case SIMPLE_ARRAY_NIL_WIDETAG:
+        case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
+        case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
+        case SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG:
+        case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
+        case SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG:
+        case SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG:
+
+        case SIMPLE_ARRAY_UNSIGNED_FIXNUM_WIDETAG:
+
+        case SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG:
+        case SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG:
+#ifdef  SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
+        case SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG:
+#endif
+#ifdef  SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
+        case SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG:
+#endif
+#ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
+        case SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG:
+#endif
+#ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
+        case SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG:
+#endif
+
+        case SIMPLE_ARRAY_FIXNUM_WIDETAG:
+
+#ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
+        case SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG:
+#endif
+#ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
+        case SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG:
+#endif
+        case SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG:
+        case SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG:
+#ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
+        case SIMPLE_ARRAY_LONG_FLOAT_WIDETAG:
+#endif
+#ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
+        case SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG:
+#endif
+#ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
+        case SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG:
+#endif
+#ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
+        case SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG:
+#endif
+        case SAP_WIDETAG:
+        case WEAK_POINTER_WIDETAG:
+            break;
+
+        default:
+            return 0;
+        }
+        break;
+    default:
+        return 0;
+    }
+
+    /* looks good */
+    return 1;
+}
+
+/* Used by the debugger to validate possibly bogus pointers before
+ * calling MAKE-LISP-OBJ on them.
+ *
+ * FIXME: We would like to make this perfect, because if the debugger
+ * constructs a reference to a bugs lisp object, and it ends up in a
+ * location scavenged by the GC all hell breaks loose.
+ *
+ * Whereas possibly_valid_dynamic_space_pointer has to be conservative
+ * and return true for all valid pointers, this could actually be eager
+ * and lie about a few pointers without bad results... but that should
+ * be reflected in the name.
+ */
+int
+valid_lisp_pointer_p(lispobj *pointer)
+{
+    lispobj *start;
+    if (((start=search_dynamic_space(pointer))!=NULL) ||
+        ((start=search_static_space(pointer))!=NULL) ||
+        ((start=search_read_only_space(pointer))!=NULL))
+        return looks_like_valid_lisp_pointer_p(pointer, start);
+    else
+        return 0;
+}
+
 boolean
 maybe_gc(os_context_t *context)
 {
@@ -2514,7 +2750,7 @@ scrub_control_stack(void)
 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
     sp = (lispobj *)&sp - 1;
 #else
-    sp = current_control_stack_pointer;
+    sp = access_control_stack_pointer(th);
 #endif
  scrub:
     if ((((os_vm_address_t)sp < (hard_guard_page_address + os_vm_page_size)) &&