diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5detect.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/src/H5detect.c b/src/H5detect.c index fb11322..eb8f9ac 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -112,14 +112,14 @@ precision (detected_t *d) */ for (n=0; n<d->size && d->perm[n]<0; n++) /*void*/; d->precision = 8*(d->size-n); - d->offset = 0; + d->offset = 8*n; } 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; + d->offset = 0; } else { /* * No padding. @@ -179,13 +179,13 @@ precision (detected_t *d) INFO.perm[_i] = _j; \ } \ INFO.sign = ('U'!=*(#VAR)); \ - ALIGNMENT(TYPE, INFO.align); \ + precision (&(INFO)); \ + ALIGNMENT(TYPE, INFO); \ if(!strcmp(INFO.varname, "SCHAR") || !strcmp(INFO.varname, "SHORT") || \ !strcmp(INFO.varname, "INT") || !strcmp(INFO.varname, "LONG") || \ !strcmp(INFO.varname, "LLONG")) { \ COMP_ALIGNMENT(TYPE,INFO.comp_align); \ } \ - precision (&(INFO)); \ } /*------------------------------------------------------------------------- @@ -267,12 +267,12 @@ precision (detected_t *d) \ _v1 = 1.0; \ INFO.bias = find_bias (INFO.epos, INFO.esize, INFO.perm, &_v1); \ - ALIGNMENT(TYPE, INFO.align); \ + precision (&(INFO)); \ + ALIGNMENT(TYPE, INFO); \ if(!strcmp(INFO.varname, "FLOAT") || !strcmp(INFO.varname, "DOUBLE") || \ !strcmp(INFO.varname, "LDOUBLE")) { \ COMP_ALIGNMENT(TYPE,INFO.comp_align); \ } \ - precision (&(INFO)); \ } @@ -309,21 +309,33 @@ precision (detected_t *d) } #if defined(H5_HAVE_LONGJMP) && defined(H5_HAVE_SIGNAL) -#define ALIGNMENT(TYPE,ALIGN) { \ +#define ALIGNMENT(TYPE,INFO) { \ char *volatile _buf=NULL; \ volatile TYPE _val=0; \ + volatile TYPE _val2; \ volatile size_t _ano=0; \ void (*_handler)(int) = signal(SIGBUS, sigbus_handler); \ - void (*_handler2)(int) = signal(SIGSEGV, sigsegv_handler); \ + void (*_handler2)(int) = signal(SIGSEGV, sigsegv_handler); \ \ _buf = malloc(sizeof(TYPE)+align_g[NELMTS(align_g)-1]); \ if (setjmp(jbuf_g)) _ano++; \ if (_ano<NELMTS(align_g)) { \ - *((TYPE*)(_buf+align_g[_ano])) = _val; /*possible SIGBUS or SEGSEGV*/ \ - _val = *((TYPE*)(_buf+align_g[_ano])); /*possible SIGBUS or SEGSEGV*/ \ - (ALIGN)=align_g[_ano]; \ + *((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 */ \ + memset(_buf, 0xff, sizeof(TYPE)+align_g[NELMTS(align_g)-1]); \ + memcpy(_buf+align_g[_ano]+(INFO.offset/8),((char *)&_val)+(INFO.offset/8),(INFO.precision/8)); \ + _val2 = *((TYPE*)(_buf+align_g[_ano])); \ + if(_val!=_val2) \ + longjmp(jbuf_g, 1); \ + /* End Cray Check */ \ + (INFO.align)=align_g[_ano]; \ } else { \ - (ALIGN)=0; \ + (INFO.align)=0; \ fprintf(stderr, "unable to calculate alignment for %s\n", #TYPE); \ } \ free(_buf); \ @@ -331,12 +343,12 @@ precision (detected_t *d) signal(SIGSEGV, _handler2); /*restore original handler*/ \ } #else -#define ALIGNMENT(TYPE,ALIGN) (ALIGN)=0 +#define ALIGNMENT(TYPE,INFO) (INFO.align)=0 #endif #if 0 #if defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID) -#define ALIGNMENT(TYPE,ALIGN) { \ +#define ALIGNMENT(TYPE,INFO) { \ char *_buf; \ TYPE _val=0; \ size_t _ano; \ @@ -362,7 +374,7 @@ precision (detected_t *d) exit(1); \ } \ if (WIFEXITED(_status) && 0==WEXITSTATUS(_status)) { \ - ALIGN=align_g[_ano]; \ + INFO.align=align_g[_ano]; \ break; \ } \ if (WIFSIGNALED(_status) && SIGBUS==WTERMSIG(_status)) { \ @@ -372,12 +384,12 @@ precision (detected_t *d) break; \ } \ if (_ano>=NELMTS(align_g)) { \ - ALIGN=0; \ + INFO.align=0; \ fprintf(stderr, "unable to calculate alignment for %s\n", #TYPE); \ } \ } #else -#define ALIGNMENT(TYPE,ALIGN) (ALIGN)=0 +#define ALIGNMENT(TYPE,INFO) (INFO.align)=0 #endif #endif |