summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Young <dyoung@hdfgroup.org>2022-01-28 17:21:08 (GMT)
committerDavid Young <dyoung@hdfgroup.org>2022-01-28 17:26:07 (GMT)
commit558e75a9b53919b38c9aa45764f0cf13b9478c03 (patch)
treec7c8e97f6bd7f78e0828493eedc051360c9e1a9d
parentb5eed1b56324fc07154c2e2d8251d2b87505ca23 (diff)
downloadhdf5-558e75a9b53919b38c9aa45764f0cf13b9478c03.zip
hdf5-558e75a9b53919b38c9aa45764f0cf13b9478c03.tar.gz
hdf5-558e75a9b53919b38c9aa45764f0cf13b9478c03.tar.bz2
Replace H5detect's build-time detection of C99 integer properties with a
table-driven routine, `H5T__init_native_int()`, that is run at library initialization time. Always respect the alignment used by the compiler for integers. The library invites trouble by using different alignment than the compiler expects. Here and there update a comment about alignment. Retire the H5detect code that tries to find the least permissible integer alignment by running experiments and catching any signals thrown or unexpected results.
-rw-r--r--src/H5T.c43
-rw-r--r--src/H5Tnative.c295
-rw-r--r--src/H5Tpkg.h33
-rw-r--r--src/H5detect.c476
4 files changed, 312 insertions, 535 deletions
diff --git a/src/H5T.c b/src/H5T.c
index bbe6ce7..1ba65ac 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -473,35 +473,21 @@ hid_t H5T_NATIVE_INT_FAST64_g = FAIL;
hid_t H5T_NATIVE_UINT_FAST64_g = FAIL;
/*
- * Alignment constraints for native types. These are initialized at run time
- * in H5Tinit.c. These alignments are mainly for offsets in HDF5 compound
- * datatype or C structures, which are different from the alignments for memory
- * address below this group of variables.
+ * Alignment constraints for HDF5 types. Accessing objects of these
+ * types with improper alignment invokes C undefined behavior, so the
+ * library lays out objects with correct alignment, always.
+ *
+ * A value of N indicates that the data must be aligned on an address
+ * ADDR such that 0 == ADDR mod N. When N=1 no alignment is required;
+ * N=0 implies that alignment constraints were not calculated. These
+ * values are used for structure alignment.
*/
-size_t H5T_NATIVE_SCHAR_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_UCHAR_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_SHORT_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_USHORT_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_INT_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_UINT_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_LONG_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_ULONG_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_LLONG_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_ULLONG_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_FLOAT_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_DOUBLE_COMP_ALIGN_g = 0;
-size_t H5T_NATIVE_LDOUBLE_COMP_ALIGN_g = 0;
-
-size_t H5T_POINTER_COMP_ALIGN_g = 0;
-size_t H5T_HVL_COMP_ALIGN_g = 0;
-size_t H5T_HOBJREF_COMP_ALIGN_g = 0;
-size_t H5T_HDSETREGREF_COMP_ALIGN_g = 0;
-size_t H5T_REF_COMP_ALIGN_g = 0;
+size_t H5T_POINTER_ALIGN_g = 0;
+size_t H5T_HVL_ALIGN_g = 0;
+size_t H5T_HOBJREF_ALIGN_g = 0;
+size_t H5T_HDSETREGREF_ALIGN_g = 0;
+size_t H5T_REF_ALIGN_g = 0;
-/*
- * Alignment constraints for native types. These are initialized at run time
- * in H5Tinit.c
- */
size_t H5T_NATIVE_SCHAR_ALIGN_g = 0;
size_t H5T_NATIVE_UCHAR_ALIGN_g = 0;
size_t H5T_NATIVE_SHORT_ALIGN_g = 0;
@@ -777,6 +763,9 @@ H5T_init(void)
if (H5T__init_native() < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize interface")
+ if (H5T__init_native_int() < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize integers")
+
/* Get the atomic datatype structures needed by the initialization code below */
if (NULL == (native_schar = (H5T_t *)H5I_object(H5T_NATIVE_SCHAR_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
diff --git a/src/H5Tnative.c b/src/H5Tnative.c
index 4529e57..99ea6c2 100644
--- a/src/H5Tnative.c
+++ b/src/H5Tnative.c
@@ -177,13 +177,13 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
if (H5T_IS_VL_STRING(dtype->shared)) {
/* Update size, offset and compound alignment for parent. */
- if (H5T__cmp_offset(comp_size, offset, sizeof(char *), (size_t)1, H5T_POINTER_COMP_ALIGN_g,
+ if (H5T__cmp_offset(comp_size, offset, sizeof(char *), (size_t)1, H5T_POINTER_ALIGN_g,
struct_align) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset")
} /* end if */
else {
/* Update size, offset and compound alignment for parent. */
- if (H5T__cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_COMP_ALIGN_g,
+ if (H5T__cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_ALIGN_g,
struct_align) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset")
} /* end else */
@@ -208,7 +208,7 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type")
/* Update size, offset and compound alignment for parent. */
- if (H5T__cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_COMP_ALIGN_g,
+ if (H5T__cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_ALIGN_g,
struct_align) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset")
break;
@@ -227,7 +227,7 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
/* Update size, offset and compound alignment for parent. */
if (0 == H5T_cmp(ret_value, dt, FALSE)) {
- align = H5T_HOBJREF_COMP_ALIGN_g;
+ align = H5T_HOBJREF_ALIGN_g;
ref_size = sizeof(hobj_ref_t);
} /* end if */
else {
@@ -236,12 +236,12 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type")
if (0 == H5T_cmp(ret_value, dt, FALSE)) {
- align = H5T_HDSETREGREF_COMP_ALIGN_g;
+ align = H5T_HDSETREGREF_ALIGN_g;
ref_size = sizeof(hdset_reg_ref_t);
} /* end if */
else {
/* Only pointers to underlying opaque reference types */
- align = H5T_REF_COMP_ALIGN_g;
+ align = H5T_REF_ALIGN_g;
ref_size = sizeof(H5R_ref_t);
} /* end else */
} /* end else */
@@ -479,7 +479,7 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype")
/* Update size, offset and compound alignment for parent compound type directly. */
- vl_align = H5T_HVL_COMP_ALIGN_g;
+ vl_align = H5T_HVL_ALIGN_g;
vl_size = sizeof(hvl_t);
if (H5T__cmp_offset(comp_size, offset, vl_size, (size_t)1, vl_align, struct_align) < 0)
@@ -625,7 +625,7 @@ H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
else
tid = H5T_NATIVE_UCHAR;
- align = H5T_NATIVE_SCHAR_COMP_ALIGN_g;
+ align = H5T_NATIVE_SCHAR_ALIGN_g;
break;
case H5T_NATIVE_INT_MATCH_SHORT:
@@ -633,7 +633,7 @@ H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
tid = H5T_NATIVE_SHORT;
else
tid = H5T_NATIVE_USHORT;
- align = H5T_NATIVE_SHORT_COMP_ALIGN_g;
+ align = H5T_NATIVE_SHORT_ALIGN_g;
break;
case H5T_NATIVE_INT_MATCH_INT:
@@ -642,7 +642,7 @@ H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
else
tid = H5T_NATIVE_UINT;
- align = H5T_NATIVE_INT_COMP_ALIGN_g;
+ align = H5T_NATIVE_INT_ALIGN_g;
break;
case H5T_NATIVE_INT_MATCH_LONG:
@@ -651,7 +651,7 @@ H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
else
tid = H5T_NATIVE_ULONG;
- align = H5T_NATIVE_LONG_COMP_ALIGN_g;
+ align = H5T_NATIVE_LONG_ALIGN_g;
break;
case H5T_NATIVE_INT_MATCH_LLONG:
@@ -660,7 +660,7 @@ H5T__get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
else
tid = H5T_NATIVE_ULLONG;
- align = H5T_NATIVE_LLONG_COMP_ALIGN_g;
+ align = H5T_NATIVE_LLONG_ALIGN_g;
break;
case H5T_NATIVE_INT_MATCH_UNKNOWN:
@@ -764,17 +764,17 @@ H5T__get_native_float(size_t size, H5T_direction_t direction, size_t *struct_ali
switch (match) {
case H5T_NATIVE_FLOAT_MATCH_FLOAT:
tid = H5T_NATIVE_FLOAT;
- align = H5T_NATIVE_FLOAT_COMP_ALIGN_g;
+ align = H5T_NATIVE_FLOAT_ALIGN_g;
break;
case H5T_NATIVE_FLOAT_MATCH_DOUBLE:
tid = H5T_NATIVE_DOUBLE;
- align = H5T_NATIVE_DOUBLE_COMP_ALIGN_g;
+ align = H5T_NATIVE_DOUBLE_ALIGN_g;
break;
case H5T_NATIVE_FLOAT_MATCH_LDOUBLE:
tid = H5T_NATIVE_LDOUBLE;
- align = H5T_NATIVE_LDOUBLE_COMP_ALIGN_g;
+ align = H5T_NATIVE_LDOUBLE_ALIGN_g;
break;
case H5T_NATIVE_FLOAT_MATCH_UNKNOWN:
@@ -940,3 +940,268 @@ H5T__cmp_offset(size_t *comp_size, size_t *offset, size_t elem_size, size_t nele
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5T__cmp_offset() */
+
+#define NATIVE_ENTRY_INITIALIZER(tag, type, precision, has_sign) { \
+ .alignmentp = &H5T_NATIVE_##tag##_ALIGN_g \
+ , .hidp = &H5T_NATIVE_##tag##_g \
+ , .alignment = (const char *)&alignments.tag.x - \
+ (const char *)&alignments.tag \
+ , .size = sizeof(type) \
+ , .atomic = { \
+ .offset = 0 \
+ , .prec = (precision != 0) ? precision : (sizeof(type) * 8) \
+ , .lsb_pad = H5T_PAD_ZERO \
+ , .msb_pad = H5T_PAD_ZERO \
+ , .u.i.sign = has_sign ? H5T_SGN_2 : H5T_SGN_NONE \
+ } \
+}
+
+static const struct {
+ struct {
+ char c;
+ signed char x;
+ } SCHAR;
+ struct {
+ char c;
+ unsigned char x;
+ } UCHAR;
+ struct {
+ char c;
+ short x;
+ } SHORT;
+ struct {
+ char c;
+ unsigned short x;
+ } USHORT;
+ struct {
+ char c;
+ int x;
+ } INT;
+ struct {
+ char c;
+ unsigned int x;
+ } UINT;
+ struct {
+ char c;
+ long x;
+ } LONG;
+ struct {
+ char c;
+ unsigned long x;
+ } ULONG;
+ struct {
+ char c;
+ long long x;
+ } LLONG;
+ struct {
+ char c;
+ unsigned long long x;
+ } ULLONG;
+ struct {
+ char c;
+ int8_t x;
+ } INT8;
+ struct {
+ char c;
+ uint8_t x;
+ } UINT8;
+ struct {
+ char c;
+ int_least8_t x;
+ } INT_LEAST8;
+ struct {
+ char c;
+ uint_least8_t x;
+ } UINT_LEAST8;
+ struct {
+ char c;
+ int_fast8_t x;
+ } INT_FAST8;
+ struct {
+ char c;
+ uint_fast8_t x;
+ } UINT_FAST8;
+ struct {
+ char c;
+ int16_t x;
+ } INT16;
+ struct {
+ char c;
+ uint16_t x;
+ } UINT16;
+ struct {
+ char c;
+ int_least16_t x;
+ } INT_LEAST16;
+ struct {
+ char c;
+ uint_least16_t x;
+ } UINT_LEAST16;
+ struct {
+ char c;
+ int_fast16_t x;
+ } INT_FAST16;
+ struct {
+ char c;
+ uint_fast16_t x;
+ } UINT_FAST16;
+ struct {
+ char c;
+ int32_t x;
+ } INT32;
+ struct {
+ char c;
+ uint32_t x;
+ } UINT32;
+ struct {
+ char c;
+ int_least32_t x;
+ } INT_LEAST32;
+ struct {
+ char c;
+ uint_least32_t x;
+ } UINT_LEAST32;
+ struct {
+ char c;
+ int_fast32_t x;
+ } INT_FAST32;
+ struct {
+ char c;
+ uint_fast32_t x;
+ } UINT_FAST32;
+ struct {
+ char c;
+ int64_t x;
+ } INT64;
+ struct {
+ char c;
+ uint64_t x;
+ } UINT64;
+ struct {
+ char c;
+ int_least64_t x;
+ } INT_LEAST64;
+ struct {
+ char c;
+ uint_least64_t x;
+ } UINT_LEAST64;
+ struct {
+ char c;
+ int_fast64_t x;
+ } INT_FAST64;
+ struct {
+ char c;
+ uint_fast64_t x;
+ } UINT_FAST64;
+} alignments;
+
+static H5T_order_t
+get_host_byte_order(void)
+{
+ static const union {
+ uint64_t u64;
+ char byte[8];
+ } endian_exemplar = {.byte = {1}};
+
+ return (endian_exemplar.u64 == 1) ? H5T_ORDER_LE : H5T_ORDER_BE;
+}
+
+/* Establish `H5T_t`s for C99 integer types including fixed- and
+ * minimum-width types (uint16_t, uint_least16_t, uint_fast16_t, ...).
+ */
+herr_t
+H5T__init_native_int(void)
+{
+ typedef struct {
+ size_t *alignmentp;
+ size_t alignment;
+ hid_t *hidp;
+ size_t size;
+ H5T_atomic_t atomic;
+ } native_int_t;
+
+ typedef struct {
+ const native_int_t *table;
+ size_t nelmts;
+ } native_int_table_t;
+
+ /* clang-format off */
+
+ /* The library compiles with a limit on `static` object size, so
+ * I broke this table into three.
+ */
+ static const native_int_t table1[] = {
+ NATIVE_ENTRY_INITIALIZER(SCHAR, signed char, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UCHAR, unsigned char, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(SHORT, short, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(USHORT, unsigned short, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT, int, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT, unsigned int, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT, int, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT, unsigned int, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(LONG, long, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(ULONG, unsigned long, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(LLONG, long long, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(ULLONG, unsigned long long, 0, false)
+ };
+ static const native_int_t table2[] = {
+ NATIVE_ENTRY_INITIALIZER(INT8, int8_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT8, uint8_t, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT_LEAST8, int_least8_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT_LEAST8, uint_least8_t, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT_FAST8, int_fast8_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT_FAST8, uint_fast8_t, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT16, int16_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT16, uint16_t, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT_LEAST16, int_least16_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT_LEAST16, uint_least16_t, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT_FAST16, int_fast16_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT_FAST16, uint_fast16_t, 0, false)
+ };
+ static const native_int_t table3[] = {
+ NATIVE_ENTRY_INITIALIZER(INT32, int32_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT32, uint32_t, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT_LEAST32, int_least32_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT_LEAST32, uint_least32_t, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT_FAST32, int_fast32_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT_FAST32, uint_fast32_t, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT64, int64_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT64, uint64_t, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT_LEAST64, int_least64_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT_LEAST64, uint_least64_t, 0, false)
+ , NATIVE_ENTRY_INITIALIZER(INT_FAST64, int_fast64_t, 0, true)
+ , NATIVE_ENTRY_INITIALIZER(UINT_FAST64, uint_fast64_t, 0, false)
+ };
+ static const native_int_table_t table_table[] = {
+ {table1, NELMTS(table1)}
+ , {table2, NELMTS(table2)}
+ , {table3, NELMTS(table3)}
+ };
+ /* clang-format on */
+
+ size_t i, j;
+ H5T_order_t byte_order = get_host_byte_order();
+
+ for (i = 0; i < NELMTS(table_table); i++) {
+ const native_int_t *table = table_table[i].table;
+ size_t nelmts = table_table[i].nelmts;
+ for (j = 0; j < nelmts; j++) {
+ H5T_t *dt;
+
+ if (NULL == (dt = H5T__alloc()))
+ return FAIL;
+
+ dt->shared->state = H5T_STATE_IMMUTABLE;
+ dt->shared->type = H5T_INTEGER;
+ dt->shared->size = table[j].size;
+ dt->shared->u.atomic = table[j].atomic;
+ dt->shared->u.atomic.order = byte_order;
+ *table[j].alignmentp = table[j].alignment;
+
+ if((*table[j].hidp = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0)
+ return FAIL;
+ }
+ }
+
+ return SUCCEED;
+}
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 4062cbe..ece0610 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -388,26 +388,20 @@ typedef herr_t (*H5T_operator_t)(H5T_t *dt, void *op_data /*in,out*/);
H5_DLLVAR const unsigned H5O_dtype_ver_bounds[H5F_LIBVER_NBOUNDS];
/*
- * Alignment information for native types. A value of N indicates that the
- * data must be aligned on an address ADDR such that 0 == ADDR mod N. When
- * N=1 no alignment is required; N=0 implies that alignment constraints were
- * not calculated. These alignment info is only for H5Tget_native_type.
- * These values are used for structure alignment.
+ * Alignment constraints for HDF5 types. Accessing objects of these
+ * types with improper alignment invokes C undefined behavior, so the
+ * library lays out objects with correct alignment, always.
+ *
+ * A value of N indicates that the data must be aligned on an address
+ * ADDR such that 0 == ADDR mod N. When N=1 no alignment is required;
+ * N=0 implies that alignment constraints were not calculated. These
+ * values are used for structure alignment.
*/
-H5_DLLVAR size_t H5T_NATIVE_SCHAR_COMP_ALIGN_g;
-H5_DLLVAR size_t H5T_NATIVE_SHORT_COMP_ALIGN_g;
-H5_DLLVAR size_t H5T_NATIVE_INT_COMP_ALIGN_g;
-H5_DLLVAR size_t H5T_NATIVE_LONG_COMP_ALIGN_g;
-H5_DLLVAR size_t H5T_NATIVE_LLONG_COMP_ALIGN_g;
-H5_DLLVAR size_t H5T_NATIVE_FLOAT_COMP_ALIGN_g;
-H5_DLLVAR size_t H5T_NATIVE_DOUBLE_COMP_ALIGN_g;
-H5_DLLVAR size_t H5T_NATIVE_LDOUBLE_COMP_ALIGN_g;
-
-H5_DLLVAR size_t H5T_POINTER_COMP_ALIGN_g;
-H5_DLLVAR size_t H5T_HVL_COMP_ALIGN_g;
-H5_DLLVAR size_t H5T_HOBJREF_COMP_ALIGN_g;
-H5_DLLVAR size_t H5T_HDSETREGREF_COMP_ALIGN_g;
-H5_DLLVAR size_t H5T_REF_COMP_ALIGN_g;
+H5_DLLVAR size_t H5T_POINTER_ALIGN_g;
+H5_DLLVAR size_t H5T_HVL_ALIGN_g;
+H5_DLLVAR size_t H5T_HOBJREF_ALIGN_g;
+H5_DLLVAR size_t H5T_HDSETREGREF_ALIGN_g;
+H5_DLLVAR size_t H5T_REF_ALIGN_g;
/*
* Alignment information for native types. A value of N indicates that the
@@ -473,6 +467,7 @@ H5FL_EXTERN(H5T_shared_t);
/* Common functions */
H5_DLL herr_t H5T__init_native(void);
+H5_DLL herr_t H5T__init_native_int(void);
H5_DLL H5T_t *H5T__create(H5T_class_t type, size_t size);
H5_DLL H5T_t *H5T__alloc(void);
H5_DLL herr_t H5T__free(H5T_t *dt);
diff --git a/src/H5detect.c b/src/H5detect.c
index e72d7a0..377dfd4 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -134,23 +134,9 @@ static unsigned int imp_bit(unsigned int, int *, void *, void *, const unsigned
static unsigned int find_bias(unsigned int, unsigned int, int *, void *);
static void precision(detected_t *);
static void print_header(void);
-static void detect_C89_integers(void);
static void detect_C89_floats(void);
-static void detect_C99_integers(void);
static void detect_C99_floats(void);
-static void detect_C99_integers8(void);
-static void detect_C99_integers16(void);
-static void detect_C99_integers32(void);
-static void detect_C99_integers64(void);
static void detect_alignments(void);
-static unsigned int align_g[] = {1, 2, 4, 8, 16};
-static int align_status_g = 0; /* ALIGNMENT Signal Status */
-static int sigbus_handler_called_g = 0; /* how many times called */
-static int sigsegv_handler_called_g = 0; /* how many times called */
-static int sigill_handler_called_g = 0; /* how many times called */
-static int signal_handler_tested_g = 0; /* how many times tested */
-static int verify_signal_handlers(int signum, void (*handler)(int));
-static H5JMP_BUF jbuf_g;
/*-------------------------------------------------------------------------
* Function: precision
@@ -205,63 +191,6 @@ precision(detected_t *d)
}
/*-------------------------------------------------------------------------
- * Function: DETECT_I/DETECT_BYTE
- *
- * Purpose: These macro takes a type like `int' and a base name like
- * `nati' and detects the byte order. The VAR is used to
- * construct the names of the C variables defined.
- *
- * DETECT_I is used for types that are larger than one byte,
- * DETECT_BYTE is used for types that are exactly one byte.
- *
- * Return: void
- *
- *-------------------------------------------------------------------------
- */
-#define DETECT_I_BYTE_CORE(TYPE, VAR, INFO, DETECT_TYPE) \
- { \
- DETECT_TYPE _v; \
- int _i, _j; \
- unsigned char *_x; \
- \
- HDmemset(&INFO, 0, sizeof(INFO)); \
- INFO.varname = #VAR; \
- INFO.size = sizeof(TYPE); \
- \
- for (_i = sizeof(DETECT_TYPE), _v = 0; _i > 0; --_i) \
- _v = (DETECT_TYPE)((DETECT_TYPE)(_v << 8) + (DETECT_TYPE)_i); \
- \
- for (_i = 0, _x = (unsigned char *)&_v; _i < (signed)sizeof(DETECT_TYPE); _i++) { \
- _j = (*_x++) - 1; \
- HDassert(_j < (signed)sizeof(DETECT_TYPE)); \
- INFO.perm[_i] = _j; \
- } /* end for */ \
- \
- INFO.sign = ('U' != *(#VAR)); \
- precision(&(INFO)); \
- ALIGNMENT(TYPE, INFO); \
- if (!HDstrcmp(INFO.varname, "SCHAR") || !HDstrcmp(INFO.varname, "SHORT") || \
- !HDstrcmp(INFO.varname, "INT") || !HDstrcmp(INFO.varname, "LONG") || \
- !HDstrcmp(INFO.varname, "LLONG")) { \
- COMP_ALIGNMENT(TYPE, INFO.comp_align); \
- } \
- }
-
-#define DETECT_BYTE(TYPE, VAR, INFO) \
- { \
- HDcompile_assert(sizeof(TYPE) == 1); \
- \
- DETECT_I_BYTE_CORE(TYPE, VAR, INFO, int) \
- }
-
-#define DETECT_I(TYPE, VAR, INFO) \
- { \
- HDcompile_assert(sizeof(TYPE) > 1); \
- \
- DETECT_I_BYTE_CORE(TYPE, VAR, INFO, TYPE) \
- }
-
-/*-------------------------------------------------------------------------
* Function: DETECT_F
*
* Purpose: This macro takes a floating point type like `double' and
@@ -351,7 +280,6 @@ precision(detected_t *d)
_v1 = (TYPE)1.0L; \
INFO.bias = find_bias(INFO.epos, INFO.esize, INFO.perm, &_v1); \
precision(&(INFO)); \
- ALIGNMENT(TYPE, INFO); \
if (!HDstrcmp(INFO.varname, "FLOAT") || !HDstrcmp(INFO.varname, "DOUBLE") || \
!HDstrcmp(INFO.varname, "LDOUBLE")) { \
COMP_ALIGNMENT(TYPE, INFO.comp_align); \
@@ -384,140 +312,6 @@ precision(detected_t *d)
COMP_ALIGN = (unsigned int)((char *)(&(s.x)) - (char *)(&s)); \
}
-#define ALIGNMENT(TYPE, INFO) \
- { \
- char *volatile _buf = NULL; \
- TYPE _val = 1, _val2; \
- volatile size_t _ano = 0; \
- void (*_handler)(int) = HDsignal(SIGBUS, sigbus_handler); \
- void (*_handler2)(int) = HDsignal(SIGSEGV, sigsegv_handler); \
- void (*_handler3)(int) = HDsignal(SIGILL, sigill_handler); \
- \
- _buf = (char *)HDmalloc(sizeof(TYPE) + align_g[NELMTS(align_g) - 1]); \
- if (H5SETJMP(jbuf_g)) \
- _ano++; \
- if (_ano < NELMTS(align_g)) { \
- *((TYPE *)(_buf + align_g[_ano])) = _val; /*possible SIGBUS or SEGSEGV*/ \
- _val2 = *((TYPE *)(_buf + align_g[_ano])); /*possible SIGBUS or SEGSEGV*/ \
- /* Cray Check: This section helps detect alignment on Cray's */ \
- /* vector machines (like the SV1) which mask off */ \
- /* pointer values when pointing to non-word aligned */ \
- /* locations with pointers that are supposed to be */ \
- /* word aligned. -QAK */ \
- HDmemset(_buf, 0xff, sizeof(TYPE) + align_g[NELMTS(align_g) - 1]); \
- /*How to handle VAX types?*/ \
- if (INFO.perm[0]) /* Big-Endian */ \
- HDmemcpy(_buf + align_g[_ano] + (INFO.size - ((INFO.offset + INFO.precision) / 8)), \
- ((char *)&_val) + (INFO.size - ((INFO.offset + INFO.precision) / 8)), \
- (size_t)(INFO.precision / 8)); \
- else /* Little-Endian */ \
- HDmemcpy(_buf + align_g[_ano] + (INFO.offset / 8), ((char *)&_val) + (INFO.offset / 8), \
- (size_t)(INFO.precision / 8)); \
- _val2 = *((TYPE *)(_buf + align_g[_ano])); \
- H5_GCC_CLANG_DIAG_OFF("float-equal") \
- if (_val != _val2) \
- H5LONGJMP(jbuf_g, 1); \
- H5_GCC_CLANG_DIAG_ON("float-equal") \
- /* End Cray Check */ \
- (INFO.align) = align_g[_ano]; \
- } \
- else { \
- (INFO.align) = 0; \
- fprintf(stderr, "unable to calculate alignment for %s\n", #TYPE); \
- } \
- HDfree(_buf); \
- HDsignal(SIGBUS, _handler); /*restore original handler*/ \
- HDsignal(SIGSEGV, _handler2); /*restore original handler*/ \
- HDsignal(SIGILL, _handler3); /*restore original handler*/ \
- }
-
-/*-------------------------------------------------------------------------
- * Function: sigsegv_handler
- *
- * Purpose: Handler for SIGSEGV. We use signal() instead of sigaction()
- * because it's more portable to non-Posix systems. Although
- * it's not nearly as nice to work with, it does the job for
- * this simple stuff.
- *
- * Return: Returns via H5LONGJMP to jbuf_g.
- *-------------------------------------------------------------------------
- */
-static void
-sigsegv_handler(int H5_ATTR_UNUSED signo)
-{
-#if !defined(H5HAVE_SIGJMP) && defined(H5_HAVE_SIGPROCMASK)
- /* Use sigprocmask to unblock the signal if sigsetjmp/siglongjmp are not */
- /* supported. */
- sigset_t set;
-
- HDsigemptyset(&set);
- HDsigaddset(&set, SIGSEGV);
- HDsigprocmask(SIG_UNBLOCK, &set, NULL);
-#endif
-
- sigsegv_handler_called_g++;
- HDsignal(SIGSEGV, sigsegv_handler);
- H5LONGJMP(jbuf_g, SIGSEGV);
-}
-
-/*-------------------------------------------------------------------------
- * Function: sigbus_handler
- *
- * Purpose: Handler for SIGBUS. We use signal() instead of sigaction()
- * because it's more portable to non-Posix systems. Although
- * it's not nearly as nice to work with, it does the job for
- * this simple stuff.
- *
- * Return: Returns via H5LONGJMP to jbuf_g.
- *-------------------------------------------------------------------------
- */
-static void
-sigbus_handler(int H5_ATTR_UNUSED signo)
-{
-#if !defined(H5HAVE_SIGJMP) && defined(H5_HAVE_SIGPROCMASK)
- /* Use sigprocmask to unblock the signal if sigsetjmp/siglongjmp are not */
- /* supported. */
- sigset_t set;
-
- HDsigemptyset(&set);
- HDsigaddset(&set, SIGBUS);
- HDsigprocmask(SIG_UNBLOCK, &set, NULL);
-#endif
-
- sigbus_handler_called_g++;
- HDsignal(SIGBUS, sigbus_handler);
- H5LONGJMP(jbuf_g, SIGBUS);
-}
-
-/*-------------------------------------------------------------------------
- * Function: sigill_handler
- *
- * Purpose: Handler for SIGILL. We use signal() instead of sigaction()
- * because it's more portable to non-Posix systems. Although
- * it's not nearly as nice to work with, it does the job for
- * this simple stuff.
- *
- * Return: Returns via H5LONGJMP to jbuf_g.
- *-------------------------------------------------------------------------
- */
-static void
-sigill_handler(int H5_ATTR_UNUSED signo)
-{
-#if !defined(H5HAVE_SIGJMP) && defined(H5_HAVE_SIGPROCMASK)
- /* Use sigprocmask to unblock the signal if sigsetjmp/siglongjmp are not */
- /* supported. */
- sigset_t set;
-
- HDsigemptyset(&set);
- HDsigaddset(&set, SIGILL);
- HDsigprocmask(SIG_UNBLOCK, &set, NULL);
-#endif
-
- sigill_handler_called_g++;
- HDsignal(SIGILL, sigill_handler);
- H5LONGJMP(jbuf_g, SIGILL);
-}
-
/*-------------------------------------------------------------------------
* Function: print_results
*
@@ -700,15 +494,13 @@ H5T__init_native(void)\n\
if((H5T_NATIVE_%s_g = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0)\n\
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \"can't register ID for built-in datatype\")\n",
d[i].varname);
- fprintf(rawoutstream, " H5T_NATIVE_%s_ALIGN_g = %lu;\n", d[i].varname,
- (unsigned long)(d[i].align));
/* Variables for alignment of compound datatype */
if (!HDstrcmp(d[i].varname, "SCHAR") || !HDstrcmp(d[i].varname, "SHORT") ||
!HDstrcmp(d[i].varname, "INT") || !HDstrcmp(d[i].varname, "LONG") ||
!HDstrcmp(d[i].varname, "LLONG") || !HDstrcmp(d[i].varname, "FLOAT") ||
!HDstrcmp(d[i].varname, "DOUBLE") || !HDstrcmp(d[i].varname, "LDOUBLE")) {
- fprintf(rawoutstream, " H5T_NATIVE_%s_COMP_ALIGN_g = %lu;\n", d[i].varname,
+ fprintf(rawoutstream, " H5T_NATIVE_%s_ALIGN_g = %lu;\n", d[i].varname,
(unsigned long)(d[i].comp_align));
}
}
@@ -730,7 +522,7 @@ H5T__init_native(void)\n\
/* Structure alignment for pointers, vlen and reference types */
fprintf(rawoutstream, "\n /* Structure alignment for pointers, vlen and reference types */\n");
for (j = 0; j < na; j++)
- fprintf(rawoutstream, " H5T_%s_COMP_ALIGN_g = %lu;\n", misc_align[j].name,
+ fprintf(rawoutstream, " H5T_%s_ALIGN_g = %lu;\n", misc_align[j].name,
(unsigned long)(misc_align[j].comp_align));
fprintf(rawoutstream, "\
@@ -745,42 +537,6 @@ done:\n\
\n\
FUNC_LEAVE_NOAPI(ret_value);\n} /* end H5T__init_native() */\n");
- /* Print the ALIGNMENT and signal-handling status as comments */
- fprintf(rawoutstream, "\n"
- "/****************************************/\n"
- "/* ALIGNMENT and signal-handling status */\n"
- "/****************************************/\n");
- if (align_status_g & STA_NoALIGNMENT)
- fprintf(rawoutstream, "/* ALIGNAMENT test is not available */\n");
- if (align_status_g & STA_NoHandlerVerify)
- fprintf(rawoutstream, "/* Signal handlers verify test is not available */\n");
- /* The following is available in H5pubconf.h. Printing them here for */
- /* convenience. */
-#ifdef H5_HAVE_SIGSETJMP
- fprintf(rawoutstream, "/* sigsetjmp() support: yes */\n");
-#else
- fprintf(rawoutstream, "/* sigsetjmp() support: no */\n");
-#endif
-#ifdef H5_HAVE_SIGLONGJMP
- fprintf(rawoutstream, "/* siglongjmp() support: yes */\n");
-#else
- fprintf(rawoutstream, "/* siglongjmp() support: no */\n");
-#endif
-#ifdef H5_HAVE_SIGPROCMASK
- fprintf(rawoutstream, "/* sigprocmask() support: yes */\n");
-#else
- fprintf(rawoutstream, "/* sigprocmask() support: no */\n");
-#endif
-
- /* Print the statistics of signal handlers called for debugging */
- fprintf(rawoutstream, "\n"
- "/******************************/\n"
- "/* signal handlers statistics */\n"
- "/******************************/\n");
- fprintf(rawoutstream, "/* signal_handlers tested: %d times */\n", signal_handler_tested_g);
- fprintf(rawoutstream, "/* sigbus_handler called: %d times */\n", sigbus_handler_called_g);
- fprintf(rawoutstream, "/* sigsegv_handler called: %d times */\n", sigsegv_handler_called_g);
- fprintf(rawoutstream, "/* sigill_handler called: %d times */\n", sigill_handler_called_g);
} /* end print_results() */
/*-------------------------------------------------------------------------
@@ -1222,35 +978,6 @@ bit.\n";
}
/*-------------------------------------------------------------------------
- * Function: detect_C89_integers
- *
- * Purpose: Detect C89 integer types
- *
- * Return: void
- *-------------------------------------------------------------------------
- */
-static void HDF_NO_UBSAN
-detect_C89_integers(void)
-{
- DETECT_BYTE(signed char, SCHAR, d_g[nd_g]);
- nd_g++;
- DETECT_BYTE(unsigned char, UCHAR, d_g[nd_g]);
- nd_g++;
- DETECT_I(short, SHORT, d_g[nd_g]);
- nd_g++;
- DETECT_I(unsigned short, USHORT, d_g[nd_g]);
- nd_g++;
- DETECT_I(int, INT, d_g[nd_g]);
- nd_g++;
- DETECT_I(unsigned int, UINT, d_g[nd_g]);
- nd_g++;
- DETECT_I(long, LONG, d_g[nd_g]);
- nd_g++;
- DETECT_I(unsigned long, ULONG, d_g[nd_g]);
- nd_g++;
-}
-
-/*-------------------------------------------------------------------------
* Function: detect_C89_floats
*
* Purpose: Detect C89 floating point types
@@ -1268,131 +995,6 @@ detect_C89_floats(void)
}
/*-------------------------------------------------------------------------
- * Function: detect_C99_integers8
- *
- * Purpose: Detect C99 8 bit integer types
- *
- * Return: void
- *-------------------------------------------------------------------------
- */
-static void HDF_NO_UBSAN
-detect_C99_integers8(void)
-{
- DETECT_BYTE(int8_t, INT8, d_g[nd_g]);
- nd_g++;
- DETECT_BYTE(uint8_t, UINT8, d_g[nd_g]);
- nd_g++;
- DETECT_BYTE(int_least8_t, INT_LEAST8, d_g[nd_g]);
- nd_g++;
- DETECT_BYTE(uint_least8_t, UINT_LEAST8, d_g[nd_g]);
- nd_g++;
- DETECT_BYTE(int_fast8_t, INT_FAST8, d_g[nd_g]);
- nd_g++;
- DETECT_BYTE(uint_fast8_t, UINT_FAST8, d_g[nd_g]);
- nd_g++;
-}
-
-/*-------------------------------------------------------------------------
- * Function: detect_C99_integers16
- *
- * Purpose: Detect C99 16 bit integer types
- *
- * Return: void
- *-------------------------------------------------------------------------
- */
-static void HDF_NO_UBSAN
-detect_C99_integers16(void)
-{
- DETECT_I(int16_t, INT16, d_g[nd_g]);
- nd_g++;
- DETECT_I(uint16_t, UINT16, d_g[nd_g]);
- nd_g++;
- DETECT_I(int_least16_t, INT_LEAST16, d_g[nd_g]);
- nd_g++;
- DETECT_I(uint_least16_t, UINT_LEAST16, d_g[nd_g]);
- nd_g++;
- DETECT_I(int_fast16_t, INT_FAST16, d_g[nd_g]);
- nd_g++;
- DETECT_I(uint_fast16_t, UINT_FAST16, d_g[nd_g]);
- nd_g++;
-}
-
-/*-------------------------------------------------------------------------
- * Function: detect_C99_integers32
- *
- * Purpose: Detect C99 32 bit integer types
- *
- * Return: void
- *-------------------------------------------------------------------------
- */
-static void HDF_NO_UBSAN
-detect_C99_integers32(void)
-{
- DETECT_I(int32_t, INT32, d_g[nd_g]);
- nd_g++;
- DETECT_I(uint32_t, UINT32, d_g[nd_g]);
- nd_g++;
- DETECT_I(int_least32_t, INT_LEAST32, d_g[nd_g]);
- nd_g++;
- DETECT_I(uint_least32_t, UINT_LEAST32, d_g[nd_g]);
- nd_g++;
- DETECT_I(int_fast32_t, INT_FAST32, d_g[nd_g]);
- nd_g++;
- DETECT_I(uint_fast32_t, UINT_FAST32, d_g[nd_g]);
- nd_g++;
-}
-
-/*-------------------------------------------------------------------------
- * Function: detect_C99_integers64
- *
- * Purpose: Detect C99 64 bit integer types
- *
- * Return: void
- *
- *-------------------------------------------------------------------------
- */
-static void HDF_NO_UBSAN
-detect_C99_integers64(void)
-{
- DETECT_I(int64_t, INT64, d_g[nd_g]);
- nd_g++;
- DETECT_I(uint64_t, UINT64, d_g[nd_g]);
- nd_g++;
- DETECT_I(int_least64_t, INT_LEAST64, d_g[nd_g]);
- nd_g++;
- DETECT_I(uint_least64_t, UINT_LEAST64, d_g[nd_g]);
- nd_g++;
- DETECT_I(int_fast64_t, INT_FAST64, d_g[nd_g]);
- nd_g++;
- DETECT_I(uint_fast64_t, UINT_FAST64, d_g[nd_g]);
- nd_g++;
-
- DETECT_I(long long, LLONG, d_g[nd_g]);
- nd_g++;
- DETECT_I(unsigned long long, ULLONG, d_g[nd_g]);
- nd_g++;
-}
-
-/*-------------------------------------------------------------------------
- * Function: detect_C99_integers
- *
- * Purpose: Detect C99 integer types
- *
- * Return: void
- *-------------------------------------------------------------------------
- */
-static void HDF_NO_UBSAN
-detect_C99_integers(void)
-{
- /* break it down to more subroutines so that each module subroutine */
- /* is smaller and takes less time to compile with optimization on. */
- detect_C99_integers8();
- detect_C99_integers16();
- detect_C99_integers32();
- detect_C99_integers64();
-}
-
-/*-------------------------------------------------------------------------
* Function: detect_C99_floats
*
* Purpose: Detect C99 floating point types
@@ -1442,63 +1044,6 @@ detect_alignments(void)
na_g++;
}
-/* Verify the signal handler for signal signum works correctly multiple times.
- * One possible cause of failure is that the signal handling is blocked or
- * changed to SIG_DFL after H5LONGJMP.
- * Return 0 for success, -1 for failure.
- */
-static int
-verify_signal_handlers(int signum, void (*handler)(int))
-{
-#if defined(__has_feature) /* Clang */
-#if __has_feature(address_sanitizer) || __has_feature(thread_sanitizer)
- /* Under the address and thread sanitizers, don't raise any signals. */
- return 0;
-#endif
-#elif defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_THREAD__) /* GCC */
- return 0;
-#endif
- void (*save_handler)(int) = HDsignal(signum, handler);
- volatile int i, val;
- int ntries = 5;
- volatile int nfailures = 0;
- volatile int nsuccesses = 0;
-
- for (i = 0; i < ntries; i++) {
- val = H5SETJMP(jbuf_g);
- if (val == 0) {
- /* send self the signal to trigger the handler */
- signal_handler_tested_g++;
- HDraise(signum);
- /* Should not reach here. Record error. */
- nfailures++;
- }
- else {
- if (val == signum) {
- /* return from signum handler. Record a success. */
- nsuccesses++;
- }
- else {
- fprintf(stderr, "Unknown return value (%d) from H5SETJMP", val);
- nfailures++;
- }
- }
- }
- /* restore save handler, check results and report failures */
- HDsignal(signum, save_handler);
- if (nfailures > 0 || nsuccesses != ntries) {
- fprintf(stderr,
- "verify_signal_handlers for signal %d did %d tries. "
- "Found %d failures and %d successes\n",
- signum, ntries, nfailures, nsuccesses);
- return -1;
- }
- else {
- /* all succeeded */
- return 0;
- }
-}
-
/*-------------------------------------------------------------------------
* Function: main
*
@@ -1527,25 +1072,8 @@ main(int argc, char *argv[])
if (!rawoutstream)
rawoutstream = stdout;
- /* verify the SIGBUS and SIGSEGV handlers work properly */
- if (verify_signal_handlers(SIGBUS, sigbus_handler) != 0) {
- fprintf(stderr, "Signal handler %s for signal %d failed\n", "sigbus_handler", SIGBUS);
- }
- if (verify_signal_handlers(SIGSEGV, sigsegv_handler) != 0) {
- fprintf(stderr, "Signal handler %s for signal %d failed\n", "sigsegv_handler", SIGSEGV);
- }
- if (verify_signal_handlers(SIGILL, sigill_handler) != 0) {
- fprintf(stderr, "Signal handler %s for signal %d failed\n", "sigill_handler", SIGILL);
- }
-
print_header();
- /* C89 integer types */
- detect_C89_integers();
-
- /* C99 integer types */
- detect_C99_integers();
-
/* C89 floating point types */
detect_C89_floats();