Author: mdf
Date: Wed Jan 12 17:52:48 2011
New Revision: 217313
URL: http://svn.freebsd.org/changeset/base/217313

Log:
  Add type checking for static and dynamic sysctls using scalar types.
  The code is turned off until the tree is fixed up so it compiles.
  __FreeBSD_version was already bumped once today, so skip the bump, but
  add an entry to UPDATING.
  
  Note that __DESCR() is used in the SYSCTL_OID() macro and so is not
  needed in macros that invoke it.  This use was inconsistent in the
  file and I have made it consistent any lines already being changed.
  
  Reviewed by:  bde (previous version), -arch (previous version)

Modified:
  head/UPDATING
  head/sys/sys/sysctl.h

Modified: head/UPDATING
==============================================================================
--- head/UPDATING       Wed Jan 12 16:16:54 2011        (r217312)
+++ head/UPDATING       Wed Jan 12 17:52:48 2011        (r217313)
@@ -23,6 +23,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.
        ln -s aj /etc/malloc.conf.)
 
 20110112:
+       A SYSCTL_[ADD_]UQUAD was added for unsigned uint64_t pointers,
+       symmetric with the existing SYSCTL_[ADD_]QUAD.  Type checking
+       for scalar sysctls is defined but disabled.  Code that needs
+       UQUAD to pass the type checking that must compile on older
+       systems where the define is not present can check against
+       __FreeBSD_version >= 900030.
+
        The system dialog(1) has been replaced with a new version previously
        in ports as devel/cdialog. dialog(1) is mostly command-line compatible
        with the previous version, but the libdialog associated with it has

Modified: head/sys/sys/sysctl.h
==============================================================================
--- head/sys/sys/sysctl.h       Wed Jan 12 16:16:54 2011        (r217312)
+++ head/sys/sys/sysctl.h       Wed Jan 12 17:52:48 2011        (r217313)
@@ -216,6 +216,55 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_e
 #define SYSCTL_NODE_CHILDREN(parent, name) \
        sysctl_##parent##_##name##_children
 
+/*
+ * These macros provide type safety for sysctls.  SYSCTL_ALLOWED_TYPES()
+ * defines a transparent union of the allowed types.  SYSCTL_ASSERT_TYPE()
+ * and SYSCTL_ADD_ASSERT_TYPE() use the transparent union to assert that
+ * the pointer matches the allowed types.
+ *
+ * The allow_0 member allows a literal 0 to be passed for ptr.
+ */
+#define        SYSCTL_ALLOWED_TYPES(type, decls)                       \
+       union sysctl_##type {                                   \
+               long allow_0;                                   \
+               decls                                           \
+       } __attribute__((__transparent_union__));               \
+                                                               \
+       static inline void *                                    \
+       __sysctl_assert_##type(union sysctl_##type ptr)         \
+       {                                                       \
+               return (ptr.a);                                 \
+       }                                                       \
+       struct __hack
+
+SYSCTL_ALLOWED_TYPES(INT, int *a; );
+SYSCTL_ALLOWED_TYPES(UINT, unsigned int *a; );
+SYSCTL_ALLOWED_TYPES(XINT, unsigned int *a; int *b; );
+SYSCTL_ALLOWED_TYPES(LONG, long *a; );
+SYSCTL_ALLOWED_TYPES(ULONG, unsigned long *a; );
+SYSCTL_ALLOWED_TYPES(XLONG, unsigned long *a; long b; );
+SYSCTL_ALLOWED_TYPES(INT64, int64_t *a; long long *b; );
+SYSCTL_ALLOWED_TYPES(UINT64, uint64_t *a; unsigned long long *b; );
+
+#ifdef notyet
+#define        SYSCTL_ADD_ASSERT_TYPE(type, ptr)       \
+       __sysctl_assert_ ## type (ptr)
+#define        SYSCTL_ASSERT_TYPE(type, ptr, parent, name)     \
+       _SYSCTL_ASSERT_TYPE(type, ptr, __LINE__, parent##_##name)
+#else
+#define        SYSCTL_ADD_ASSERT_TYPE(type, ptr)       ptr
+#define        SYSCTL_ASSERT_TYPE(type, ptr, parent, name)
+#endif
+#define        _SYSCTL_ASSERT_TYPE(t, p, l, id)                \
+       __SYSCTL_ASSERT_TYPE(t, p, l, id)
+#define        __SYSCTL_ASSERT_TYPE(type, ptr, line, id)                       
\
+       static inline void                                              \
+       sysctl_assert_##line##_##id(void)                               \
+       {                                                               \
+               (void)__sysctl_assert_##type(ptr);                      \
+       }                                                               \
+       struct __hack
+
 #ifndef NO_SYSCTL_DESCR
 #define __DESCR(d) d
 #else
@@ -252,65 +301,106 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_e
        arg, len, sysctl_handle_string, "A", __DESCR(descr))
 
 /* Oid for an int.  If ptr is NULL, val is returned. */
-#define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) \
-       SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|CTLFLAG_MPSAFE|(access), \
-               ptr, val, sysctl_handle_int, "I", descr)
-
-#define SYSCTL_ADD_INT(ctx, parent, nbr, name, access, ptr, val, descr)        
    \
-       sysctl_add_oid(ctx, parent, nbr, name, 
CTLTYPE_INT|CTLFLAG_MPSAFE|(access),         \
-       ptr, val, sysctl_handle_int, "I", __DESCR(descr))
+#define        SYSCTL_INT(parent, nbr, name, access, ptr, val, descr)          
\
+       SYSCTL_ASSERT_TYPE(INT, ptr, parent, name);                     \
+       SYSCTL_OID(parent, nbr, name,                                   \
+           CTLTYPE_INT | CTLFLAG_MPSAFE | (access),                    \
+           ptr, val, sysctl_handle_int, "I", descr)
+
+#define        SYSCTL_ADD_INT(ctx, parent, nbr, name, access, ptr, val, descr) 
\
+       sysctl_add_oid(ctx, parent, nbr, name,                          \
+           CTLTYPE_INT | CTLFLAG_MPSAFE | (access),                    \
+           SYSCTL_ADD_ASSERT_TYPE(INT, ptr), val,                      \
+           sysctl_handle_int, "I", __DESCR(descr))
 
 /* Oid for an unsigned int.  If ptr is NULL, val is returned. */
-#define SYSCTL_UINT(parent, nbr, name, access, ptr, val, descr) \
-       SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|CTLFLAG_MPSAFE|(access), \
-               ptr, val, sysctl_handle_int, "IU", descr)
-
-#define SYSCTL_ADD_UINT(ctx, parent, nbr, name, access, ptr, val, descr)    \
-       sysctl_add_oid(ctx, parent, nbr, name, 
CTLTYPE_UINT|CTLFLAG_MPSAFE|(access),        \
-       ptr, val, sysctl_handle_int, "IU", __DESCR(descr))
-
-#define SYSCTL_XINT(parent, nbr, name, access, ptr, val, descr) \
-       SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|CTLFLAG_MPSAFE|(access), \
-               ptr, val, sysctl_handle_int, "IX", descr)
-
-#define SYSCTL_ADD_XINT(ctx, parent, nbr, name, access, ptr, val, descr)    \
-       sysctl_add_oid(ctx, parent, nbr, name, 
CTLTYPE_UINT|CTLFLAG_MPSAFE|(access),        \
-       ptr, val, sysctl_handle_int, "IX", __DESCR(descr))
+#define        SYSCTL_UINT(parent, nbr, name, access, ptr, val, descr)         
\
+       SYSCTL_ASSERT_TYPE(UINT, ptr, parent, name);                    \
+       SYSCTL_OID(parent, nbr, name,                                   \
+           CTLTYPE_UINT | CTLFLAG_MPSAFE | (access),                   \
+           ptr, val, sysctl_handle_int, "IU", descr)
+
+#define        SYSCTL_ADD_UINT(ctx, parent, nbr, name, access, ptr, val, 
descr) \
+       sysctl_add_oid(ctx, parent, nbr, name,                          \
+           CTLTYPE_UINT | CTLFLAG_MPSAFE | (access),                   \
+           SYSCTL_ADD_ASSERT_TYPE(UINT, ptr), val,                     \
+           sysctl_handle_int, "IU", __DESCR(descr))
+
+#define        SYSCTL_XINT(parent, nbr, name, access, ptr, val, descr)         
\
+       SYSCTL_ASSERT_TYPE(XINT, ptr, parent, name);                    \
+       SYSCTL_OID(parent, nbr, name,                                   \
+           CTLTYPE_UINT | CTLFLAG_MPSAFE | (access),                   \
+           ptr, val, sysctl_handle_int, "IX", descr)
+
+#define        SYSCTL_ADD_XINT(ctx, parent, nbr, name, access, ptr, val, 
descr) \
+       sysctl_add_oid(ctx, parent, nbr, name,                          \
+           CTLTYPE_UINT | CTLFLAG_MPSAFE | (access),                   \
+           SYSCTL_ADD_ASSERT_TYPE(XINT, ptr), val,                     \
+           sysctl_handle_int, "IX", __DESCR(descr))
 
 /* Oid for a long.  The pointer must be non NULL. */
-#define SYSCTL_LONG(parent, nbr, name, access, ptr, val, descr) \
-       SYSCTL_OID(parent, nbr, name, CTLTYPE_LONG|CTLFLAG_MPSAFE|(access), \
-               ptr, val, sysctl_handle_long, "L", descr)
-
-#define SYSCTL_ADD_LONG(ctx, parent, nbr, name, access, ptr, descr)        \
-       sysctl_add_oid(ctx, parent, nbr, name, 
CTLTYPE_LONG|CTLFLAG_MPSAFE|(access),        \
-       ptr, 0, sysctl_handle_long, "L", __DESCR(descr))
+#define        SYSCTL_LONG(parent, nbr, name, access, ptr, val, descr)         
\
+       SYSCTL_ASSERT_TYPE(LONG, ptr, parent, name);                    \
+       SYSCTL_OID(parent, nbr, name,                                   \
+           CTLTYPE_LONG | CTLFLAG_MPSAFE | (access),                   \
+           ptr, val, sysctl_handle_long, "L", descr)
+
+#define        SYSCTL_ADD_LONG(ctx, parent, nbr, name, access, ptr, descr)     
\
+       sysctl_add_oid(ctx, parent, nbr, name,                          \
+           CTLTYPE_LONG | CTLFLAG_MPSAFE | (access),                   \
+           SYSCTL_ADD_ASSERT_TYPE(LONG, ptr), 0,                       \
+           sysctl_handle_long, "L", __DESCR(descr))
 
 /* Oid for an unsigned long.  The pointer must be non NULL. */
-#define SYSCTL_ULONG(parent, nbr, name, access, ptr, val, descr) \
-       SYSCTL_OID(parent, nbr, name, CTLTYPE_ULONG|CTLFLAG_MPSAFE|(access), \
-               ptr, val, sysctl_handle_long, "LU", __DESCR(descr))
-
-#define SYSCTL_ADD_ULONG(ctx, parent, nbr, name, access, ptr, descr)       \
-       sysctl_add_oid(ctx, parent, nbr, name, 
CTLTYPE_ULONG|CTLFLAG_MPSAFE|(access),       \
-       ptr, 0, sysctl_handle_long, "LU", __DESCR(descr))
-
-#define SYSCTL_XLONG(parent, nbr, name, access, ptr, val, descr) \
-       SYSCTL_OID(parent, nbr, name, CTLTYPE_ULONG|CTLFLAG_MPSAFE|(access), \
-               ptr, val, sysctl_handle_long, "LX", __DESCR(descr))
-
-#define SYSCTL_ADD_XLONG(ctx, parent, nbr, name, access, ptr, descr)       \
-       sysctl_add_oid(ctx, parent, nbr, name, 
CTLTYPE_ULONG|CTLFLAG_MPSAFE|(access),       \
-       ptr, 0, sysctl_handle_long, "LX", __DESCR(descr))
+#define        SYSCTL_ULONG(parent, nbr, name, access, ptr, val, descr)        
\
+       SYSCTL_ASSERT_TYPE(ULONG, ptr, parent, name);                   \
+       SYSCTL_OID(parent, nbr, name,                                   \
+           CTLTYPE_ULONG | CTLFLAG_MPSAFE | (access),                  \
+           ptr, val, sysctl_handle_long, "LU", descr)
+
+#define        SYSCTL_ADD_ULONG(ctx, parent, nbr, name, access, ptr, descr)    
\
+       sysctl_add_oid(ctx, parent, nbr, name,                          \
+           CTLTYPE_ULONG | CTLFLAG_MPSAFE | (access),                  \
+           SYSCTL_ADD_ASSERT_TYPE(ULONG, ptr), 0,                      \
+           sysctl_handle_long, "LU", __DESCR(descr))
+
+#define        SYSCTL_XLONG(parent, nbr, name, access, ptr, val, descr)        
\
+       SYSCTL_ASSERT_TYPE(XLONG, ptr, parent, name);                   \
+       SYSCTL_OID(parent, nbr, name,                                   \
+           CTLTYPE_ULONG | CTLFLAG_MPSAFE | (access),                  \
+           ptr, val, sysctl_handle_long, "LX", descr)
+
+#define        SYSCTL_ADD_XLONG(ctx, parent, nbr, name, access, ptr, descr)    
\
+       sysctl_add_oid(ctx, parent, nbr, name,                          \
+           CTLTYPE_ULONG | CTLFLAG_MPSAFE | (access),                  \
+           SYSCTL_ADD_ASSERT_TYPE(XLONG, ptr), 0,                      \
+           sysctl_handle_long, "LX", __DESCR(descr))
+
+/* Oid for a quad.  The pointer must be non NULL. */
+#define        SYSCTL_QUAD(parent, nbr, name, access, ptr, val, descr)         
\
+       SYSCTL_ASSERT_TYPE(INT64, ptr, parent, name);                   \
+       SYSCTL_OID(parent, nbr, name,                                   \
+           CTLTYPE_QUAD | CTLFLAG_MPSAFE | (access),                   \
+           ptr, val, sysctl_handle_quad, "Q", descr)
+
+#define        SYSCTL_ADD_QUAD(ctx, parent, nbr, name, access, ptr, descr)     
\
+       sysctl_add_oid(ctx, parent, nbr, name,                          \
+           CTLTYPE_QUAD | CTLFLAG_MPSAFE | (access),                   \
+           SYSCTL_ADD_ASSERT_TYPE(INT64, ptr), 0,                      \
+           sysctl_handle_quad, "Q", __DESCR(descr))
 
 /* Oid for a quad.  The pointer must be non NULL. */
-#define SYSCTL_QUAD(parent, nbr, name, access, ptr, val, descr) \
-       SYSCTL_OID(parent, nbr, name, CTLTYPE_QUAD|CTLFLAG_MPSAFE|(access), \
-               ptr, val, sysctl_handle_quad, "Q", __DESCR(descr))
-
-#define SYSCTL_ADD_QUAD(ctx, parent, nbr, name, access, ptr, descr)        \
-       sysctl_add_oid(ctx, parent, nbr, name, 
CTLTYPE_QUAD|CTLFLAG_MPSAFE|(access),        \
-       ptr, 0, sysctl_handle_quad, "Q", __DESCR(descr))
+#define        SYSCTL_UQUAD(parent, nbr, name, access, ptr, val, descr)        
\
+       SYSCTL_ASSERT_TYPE(UINT64, ptr, parent, name);                  \
+       SYSCTL_OID(parent, nbr, name,                                   \
+           CTLTYPE_QUAD | CTLFLAG_MPSAFE | (access),   \
+           ptr, val, sysctl_handle_quad, "QU", descr)
+
+#define        SYSCTL_ADD_UQUAD(ctx, parent, nbr, name, access, ptr, descr)    
\
+       sysctl_add_oid(ctx, parent, nbr, name,                          \
+           CTLTYPE_QUAD | CTLFLAG_MPSAFE | (access),                   \
+           SYSCTL_ADD_ASSERT_TYPE(UINT64, ptr), 0,                     \
+           sysctl_handle_quad, "QU", __DESCR(descr))
 
 /* Oid for an opaque object.  Specified by a pointer and a length. */
 #define SYSCTL_OPAQUE(parent, nbr, name, access, ptr, len, fmt, descr) \
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to