Compare commits
17 Commits
feature/mu
...
feature/h5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81d197c1dd | ||
|
|
1a6d20b229 | ||
|
|
85c2171a17 | ||
|
|
066f824170 | ||
|
|
cbaeb279ae | ||
|
|
be65814cde | ||
|
|
0522b9fe5d | ||
|
|
b3d75b13db | ||
|
|
069f75648a | ||
|
|
e8bcb24e3f | ||
|
|
9e87536a29 | ||
|
|
a7d55c479d | ||
|
|
af884602f0 | ||
|
|
5be6c453ec | ||
|
|
8788414eec | ||
|
|
ccc6bd88b9 | ||
|
|
558e75a9b5 |
43
src/H5T.c
43
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_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;
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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_internal() < 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")
|
||||
|
||||
351
src/H5Tnative.c
351
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,324 @@ 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 TAG_ALIGNMENT(tag) (offsetof(alignments_t, tag.x) - offsetof(alignments_t, tag))
|
||||
|
||||
/* clang-format off */
|
||||
#define NATIVE_ENTRY_INITIALIZER(tag, type, precision, has_sign) { \
|
||||
.alignmentp = &H5T_NATIVE_##tag##_ALIGN_g \
|
||||
, .alignment = TAG_ALIGNMENT(tag) \
|
||||
, .hidp = &H5T_NATIVE_##tag##_g \
|
||||
, .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 \
|
||||
} \
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
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, ...).
|
||||
*
|
||||
* Also establish alignment for some miscellaneous types: pointers,
|
||||
* HDF5 references, and so on.
|
||||
*/
|
||||
herr_t
|
||||
H5T__init_native_internal(void)
|
||||
{
|
||||
/* Here we construct a type that lets us find alignment constraints
|
||||
* without using the alignof operator, which is not available in C99.
|
||||
*
|
||||
* Between each sub-struct's `char` member `c` and member `x`, the
|
||||
* compiler must insert padding to ensure proper alignment of `x`.
|
||||
* We can find the alignment constraint of each `x` by looking at
|
||||
* its offset from the beginning of its sub-struct.
|
||||
*/
|
||||
typedef 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;
|
||||
struct {
|
||||
char c;
|
||||
void *x;
|
||||
} pointer;
|
||||
struct {
|
||||
char c;
|
||||
hvl_t x;
|
||||
} hvl;
|
||||
struct {
|
||||
char c;
|
||||
hobj_ref_t x;
|
||||
} hobjref;
|
||||
struct {
|
||||
char c;
|
||||
hdset_reg_ref_t x;
|
||||
} hdsetregref;
|
||||
struct {
|
||||
char c;
|
||||
H5R_ref_t x;
|
||||
} ref;
|
||||
} alignments_t;
|
||||
|
||||
/* Describe a C99 type, `type`, and tell where to write its
|
||||
* H5T_t identifier and alignment. Tables of these descriptions
|
||||
* drive the initialization of `H5T_t`s.
|
||||
*/
|
||||
typedef struct {
|
||||
/* Pointer to the global variable that receives the
|
||||
* alignment of `type`:
|
||||
*/
|
||||
size_t *alignmentp;
|
||||
size_t alignment; // natural alignment of `type`
|
||||
/* Pointer to the global variable that receives the
|
||||
* identifier for `type`'s H5T_t:
|
||||
*/
|
||||
hid_t * hidp;
|
||||
size_t size; // sizeof(`type`)
|
||||
H5T_atomic_t atomic; // `type` facts such as signedness
|
||||
} 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 each C99 type in `table`, create its H5T_t,
|
||||
* register a hid_t for the H5T_t, and record the type's
|
||||
* alignment and hid_t in the variables named by the
|
||||
* table.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
H5T_POINTER_ALIGN_g = TAG_ALIGNMENT(pointer);
|
||||
H5T_HVL_ALIGN_g = TAG_ALIGNMENT(hvl);
|
||||
H5T_HOBJREF_ALIGN_g = TAG_ALIGNMENT(hobjref);
|
||||
H5T_HDSETREGREF_ALIGN_g = TAG_ALIGNMENT(hdsetregref);
|
||||
H5T_REF_ALIGN_g = TAG_ALIGNMENT(ref);
|
||||
|
||||
return SUCCEED;
|
||||
}
|
||||
|
||||
35
src/H5Tpkg.h
35
src/H5Tpkg.h
@@ -388,26 +388,22 @@ 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.
|
||||
*
|
||||
* This alignment info is only for H5Tget_native_type.
|
||||
*/
|
||||
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 +469,7 @@ H5FL_EXTERN(H5T_shared_t);
|
||||
|
||||
/* Common functions */
|
||||
H5_DLL herr_t H5T__init_native(void);
|
||||
H5_DLL herr_t H5T__init_native_internal(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);
|
||||
|
||||
687
src/H5detect.c
687
src/H5detect.c
@@ -49,11 +49,6 @@ static const char *FileHeader = "\n\
|
||||
#include "H5Tpublic.h"
|
||||
#include "H5Rpublic.h"
|
||||
|
||||
/* Disable warning about cast increasing the alignment of the target type,
|
||||
* that's _exactly_ what this code is probing. -QAK
|
||||
*/
|
||||
H5_GCC_CLANG_DIAG_OFF("cast-align")
|
||||
|
||||
#if defined(__has_attribute)
|
||||
#if __has_attribute(no_sanitize_address)
|
||||
#define HDF_NO_UBSAN __attribute__((no_sanitize_address))
|
||||
@@ -66,30 +61,6 @@ H5_GCC_CLANG_DIAG_OFF("cast-align")
|
||||
|
||||
#define MAXDETECT 64
|
||||
|
||||
/* The ALIGNMENT test code may generate the SIGBUS, SIGSEGV, or SIGILL signals.
|
||||
* We use setjmp/longjmp in the signal handlers for recovery. But setjmp/longjmp
|
||||
* do not necessary restore the signal blocking status while sigsetjmp/siglongjmp
|
||||
* do. If sigsetjmp/siglongjmp are not supported, need to use sigprocmask to
|
||||
* unblock the signal before doing longjmp.
|
||||
*/
|
||||
/* Define H5SETJMP/H5LONGJMP depending on if sigsetjmp/siglongjmp are */
|
||||
/* supported. */
|
||||
#if defined(H5_HAVE_SIGSETJMP) && defined(H5_HAVE_SIGLONGJMP)
|
||||
/* Always save blocked signals to be restored by siglongjmp. */
|
||||
#define H5JMP_BUF sigjmp_buf
|
||||
#define H5SETJMP(buf) HDsigsetjmp(buf, 1)
|
||||
#define H5LONGJMP(buf, val) HDsiglongjmp(buf, val)
|
||||
#define H5HAVE_SIGJMP /* sigsetjmp/siglongjmp are supported. */
|
||||
#else
|
||||
#define H5JMP_BUF jmp_buf
|
||||
#define H5SETJMP(buf) HDsetjmp(buf)
|
||||
#define H5LONGJMP(buf, val) HDlongjmp(buf, val)
|
||||
#endif
|
||||
|
||||
/* ALIGNMENT and signal-handling status codes */
|
||||
#define STA_NoALIGNMENT 0x0001 /* No ALIGNMENT Test */
|
||||
#define STA_NoHandlerVerify 0x0002 /* No signal handler Tests */
|
||||
|
||||
/*
|
||||
* This structure holds information about a type that
|
||||
* was detected.
|
||||
@@ -105,27 +76,18 @@ typedef struct detected_t {
|
||||
unsigned int mpos, msize, imp; /* information about mantissa */
|
||||
unsigned int epos, esize; /* information about exponent */
|
||||
unsigned long bias; /* exponent bias for floating pt */
|
||||
unsigned int align; /* required byte alignment */
|
||||
unsigned int comp_align; /* alignment for structure */
|
||||
} detected_t;
|
||||
|
||||
/* This structure holds structure alignment for pointers, vlen and reference
|
||||
* types. */
|
||||
typedef struct malign_t {
|
||||
const char * name;
|
||||
unsigned int comp_align; /* alignment for structure */
|
||||
} malign_t;
|
||||
|
||||
FILE *rawoutstream = NULL;
|
||||
|
||||
/* global variables types detection code */
|
||||
H5_GCC_DIAG_OFF("larger-than=")
|
||||
static detected_t d_g[MAXDETECT];
|
||||
H5_GCC_DIAG_ON("larger-than=")
|
||||
static malign_t m_g[MAXDETECT];
|
||||
static volatile int nd_g = 0, na_g = 0;
|
||||
static volatile int nd_g = 0;
|
||||
|
||||
static void print_results(int nd, detected_t *d, int na, malign_t *m);
|
||||
static void print_results(int nd, detected_t *d);
|
||||
static void iprint(detected_t *);
|
||||
static int byte_cmp(int, const void *, const void *, const unsigned char *);
|
||||
static unsigned int bit_cmp(unsigned int, int *, void *, void *, const unsigned char *);
|
||||
@@ -134,23 +96,8 @@ 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
|
||||
@@ -163,104 +110,11 @@ static H5JMP_BUF jbuf_g;
|
||||
static void
|
||||
precision(detected_t *d)
|
||||
{
|
||||
unsigned int n;
|
||||
|
||||
if (0 == d->msize) {
|
||||
/*
|
||||
* An integer. The permutation can have negative values at the
|
||||
* beginning or end which represent padding of bytes. We must adjust
|
||||
* the precision and offset accordingly.
|
||||
*/
|
||||
if (d->perm[0] < 0) {
|
||||
/*
|
||||
* Lower addresses are padded.
|
||||
*/
|
||||
for (n = 0; n < d->size && d->perm[n] < 0; n++)
|
||||
/*void*/;
|
||||
d->precision = 8 * (d->size - n);
|
||||
d->offset = 0;
|
||||
}
|
||||
else if (d->perm[d->size - 1] < 0) {
|
||||
/*
|
||||
* Higher addresses are padded.
|
||||
*/
|
||||
for (n = 0; n < d->size && d->perm[d->size - (n + 1)]; n++)
|
||||
/*void*/;
|
||||
d->precision = 8 * (d->size - n);
|
||||
d->offset = 8 * n;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* No padding.
|
||||
*/
|
||||
d->precision = 8 * d->size;
|
||||
d->offset = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* A floating point */
|
||||
d->offset = MIN3(d->mpos, d->epos, d->sign);
|
||||
d->precision = d->msize + d->esize + 1;
|
||||
}
|
||||
/* A floating point */
|
||||
d->offset = MIN3(d->mpos, d->epos, d->sign);
|
||||
d->precision = d->msize + d->esize + 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* 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
|
||||
*
|
||||
@@ -351,28 +205,12 @@ 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); \
|
||||
} \
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: DETECT_M
|
||||
*
|
||||
* Purpose: This macro takes only miscellaneous structures or pointer.
|
||||
* It constructs the names and decides the alignment in structure.
|
||||
*
|
||||
* Return: void
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#define DETECT_M(TYPE, VAR, INFO) \
|
||||
{ \
|
||||
INFO.name = #VAR; \
|
||||
COMP_ALIGNMENT(TYPE, INFO.comp_align); \
|
||||
}
|
||||
|
||||
/* Detect alignment for C structure */
|
||||
#define COMP_ALIGNMENT(TYPE, COMP_ALIGN) \
|
||||
{ \
|
||||
@@ -384,140 +222,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
|
||||
*
|
||||
@@ -527,7 +231,7 @@ sigill_handler(int H5_ATTR_UNUSED signo)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
print_results(int nd, detected_t *d, int na, malign_t *misc_align)
|
||||
print_results(int nd, detected_t *d)
|
||||
{
|
||||
int byte_order = 0; /*byte order of data types*/
|
||||
int i, j;
|
||||
@@ -645,10 +349,9 @@ H5T__init_native(void)\n\
|
||||
if(NULL == (dt = H5T__alloc()))\n\
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, \"datatype allocation failed\")\n\
|
||||
dt->shared->state = H5T_STATE_IMMUTABLE;\n\
|
||||
dt->shared->type = H5T_%s;\n\
|
||||
dt->shared->type = H5T_FLOAT;\n\
|
||||
dt->shared->size = %d;\n",
|
||||
d[i].msize ? "FLOAT" : "INTEGER", /*class */
|
||||
d[i].size); /*size */
|
||||
d[i].size); /*size */
|
||||
|
||||
if (byte_order == -1)
|
||||
fprintf(rawoutstream, "\
|
||||
@@ -669,46 +372,36 @@ H5T__init_native(void)\n\
|
||||
d[i].precision); /*precision */
|
||||
/*HDassert((d[i].perm[0]>0)==(byte_order>0));*/ /* Double-check that byte-order doesn't change */
|
||||
|
||||
if (0 == d[i].msize) {
|
||||
/* The part unique to fixed point types */
|
||||
fprintf(rawoutstream, "\
|
||||
dt->shared->u.atomic.u.i.sign = H5T_SGN_%s;\n",
|
||||
d[i].sign ? "2" : "NONE");
|
||||
}
|
||||
else {
|
||||
/* The part unique to floating point types */
|
||||
fprintf(rawoutstream, "\
|
||||
dt->shared->u.atomic.u.f.sign = %d;\n\
|
||||
dt->shared->u.atomic.u.f.epos = %d;\n\
|
||||
dt->shared->u.atomic.u.f.esize = %d;\n\
|
||||
dt->shared->u.atomic.u.f.ebias = 0x%08lx;\n\
|
||||
dt->shared->u.atomic.u.f.mpos = %d;\n\
|
||||
dt->shared->u.atomic.u.f.msize = %d;\n\
|
||||
dt->shared->u.atomic.u.f.norm = H5T_NORM_%s;\n\
|
||||
dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO;\n",
|
||||
d[i].sign, /*sign location */
|
||||
d[i].epos, /*exponent loc */
|
||||
d[i].esize, /*exponent size */
|
||||
(unsigned long)(d[i].bias), /*exponent bias */
|
||||
d[i].mpos, /*mantissa loc */
|
||||
d[i].msize, /*mantissa size */
|
||||
d[i].imp ? "IMPLIED" : "NONE"); /*normalization */
|
||||
}
|
||||
/* The part unique to floating point types */
|
||||
fprintf(rawoutstream, "\
|
||||
dt->shared->u.atomic.u.f.sign = %d;\n\
|
||||
dt->shared->u.atomic.u.f.epos = %d;\n\
|
||||
dt->shared->u.atomic.u.f.esize = %d;\n\
|
||||
dt->shared->u.atomic.u.f.ebias = 0x%08lx;\n\
|
||||
dt->shared->u.atomic.u.f.mpos = %d;\n\
|
||||
dt->shared->u.atomic.u.f.msize = %d;\n\
|
||||
dt->shared->u.atomic.u.f.norm = H5T_NORM_%s;\n\
|
||||
dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO;\n",
|
||||
d[i].sign, /*sign location */
|
||||
d[i].epos, /*exponent loc */
|
||||
d[i].esize, /*exponent size */
|
||||
(unsigned long)(d[i].bias), /*exponent bias */
|
||||
d[i].mpos, /*mantissa loc */
|
||||
d[i].msize, /*mantissa size */
|
||||
d[i].imp ? "IMPLIED" : "NONE"); /*normalization */
|
||||
|
||||
/* Register the type */
|
||||
fprintf(rawoutstream, "\
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -727,12 +420,6 @@ H5T__init_native(void)\n\
|
||||
"BE");
|
||||
}
|
||||
|
||||
/* 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,
|
||||
(unsigned long)(misc_align[j].comp_align));
|
||||
|
||||
fprintf(rawoutstream, "\
|
||||
\n\
|
||||
done:\n\
|
||||
@@ -745,42 +432,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() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@@ -820,7 +471,7 @@ iprint(detected_t *d)
|
||||
unsigned int j;
|
||||
|
||||
for (j = 8; j > 0; --j) {
|
||||
if (k == d->sign && d->msize) {
|
||||
if (k == d->sign) {
|
||||
HDfputc('S', rawoutstream);
|
||||
}
|
||||
else if (k >= d->epos && k < d->epos + d->esize) {
|
||||
@@ -829,14 +480,8 @@ iprint(detected_t *d)
|
||||
else if (k >= d->mpos && k < d->mpos + d->msize) {
|
||||
HDfputc('M', rawoutstream);
|
||||
}
|
||||
else if (d->msize) {
|
||||
HDfputc('?', rawoutstream); /*unknown floating point bit */
|
||||
}
|
||||
else if (d->sign) {
|
||||
HDfputc('I', rawoutstream);
|
||||
}
|
||||
else {
|
||||
HDfputc('U', rawoutstream);
|
||||
HDfputc('?', rawoutstream); /*unknown floating point bit */
|
||||
}
|
||||
--k;
|
||||
}
|
||||
@@ -853,22 +498,7 @@ iprint(detected_t *d)
|
||||
/*
|
||||
* Is there an implicit bit in the mantissa.
|
||||
*/
|
||||
if (d->msize) {
|
||||
fprintf(rawoutstream, " * Implicit bit? %s\n", d->imp ? "yes" : "no");
|
||||
}
|
||||
|
||||
/*
|
||||
* Alignment
|
||||
*/
|
||||
if (0 == d->align) {
|
||||
fprintf(rawoutstream, " * Alignment: NOT CALCULATED\n");
|
||||
}
|
||||
else if (1 == d->align) {
|
||||
fprintf(rawoutstream, " * Alignment: none\n");
|
||||
}
|
||||
else {
|
||||
fprintf(rawoutstream, " * Alignment: %lu\n", (unsigned long)(d->align));
|
||||
}
|
||||
fprintf(rawoutstream, " * Implicit bit? %s\n", d->imp ? "yes" : "no");
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@@ -1221,35 +851,6 @@ bit.\n";
|
||||
fprintf(rawoutstream, "\n */\n\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
|
||||
*
|
||||
@@ -1267,131 +868,6 @@ detect_C89_floats(void)
|
||||
nd_g++;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* 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
|
||||
*
|
||||
@@ -1418,87 +894,6 @@ detect_C99_floats(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: detect_alignments
|
||||
*
|
||||
* Purpose: Detect structure alignments
|
||||
*
|
||||
* Return: void
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void HDF_NO_UBSAN
|
||||
detect_alignments(void)
|
||||
{
|
||||
/* Detect structure alignment for pointers, vlen and reference types */
|
||||
DETECT_M(void *, POINTER, m_g[na_g]);
|
||||
na_g++;
|
||||
DETECT_M(hvl_t, HVL, m_g[na_g]);
|
||||
na_g++;
|
||||
DETECT_M(hobj_ref_t, HOBJREF, m_g[na_g]);
|
||||
na_g++;
|
||||
DETECT_M(hdset_reg_ref_t, HDSETREGREF, m_g[na_g]);
|
||||
na_g++;
|
||||
DETECT_M(H5R_ref_t, REF, m_g[na_g]);
|
||||
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,35 +922,15 @@ 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();
|
||||
|
||||
/* C99 floating point types */
|
||||
detect_C99_floats();
|
||||
|
||||
/* Detect structure alignment */
|
||||
detect_alignments();
|
||||
|
||||
print_results(nd_g, d_g, na_g, m_g);
|
||||
print_results(nd_g, d_g);
|
||||
|
||||
if (rawoutstream && rawoutstream != stdout) {
|
||||
if (HDfclose(rawoutstream))
|
||||
@@ -1566,5 +941,3 @@ main(int argc, char *argv[])
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
H5_GCC_CLANG_DIAG_ON("cast-align")
|
||||
|
||||
Reference in New Issue
Block a user