Index: lib/libc/locale/Makefile.inc =================================================================== --- lib/libc/locale/Makefile.inc +++ lib/libc/locale/Makefile.inc @@ -4,7 +4,8 @@ # locale sources .PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/locale ${LIBC_SRCTOP}/locale -SRCS+= ascii.c big5.c btowc.c collate.c collcmp.c euc.c fix_grouping.c \ +SRCS+= ascii.c big5.c btowc.c collate.c collcmp.c endian.c euc.c \ + fix_grouping.c \ gb18030.c gb2312.c gbk.c ctype.c isctype.c iswctype.c \ ldpart.c lmessages.c lmonetary.c lnumeric.c localeconv.c mblen.c \ mbrlen.c \ Index: lib/libc/locale/collate.h =================================================================== --- lib/libc/locale/collate.h +++ lib/libc/locale/collate.h @@ -53,7 +53,13 @@ #endif #define COLLATE_STR_LEN 24 /* should be 64-bit multiple */ -#define COLLATE_VERSION "BSD 1.0\n" +#define __COLLATE_VERSION_BE "BSD 1.0 (BE)\n" +#define __COLLATE_VERSION_LE "BSD 1.0 (LE)\n" +#if BYTE_ORDER == BIG_ENDIAN +#define COLLATE_VERSION __COLLATE_VERSION_BE +#else +#define COLLATE_VERSION __COLLATE_VERSION_LE +#endif #define COLLATE_MAX_PRIORITY (0x7fffffff) /* max signed value */ #define COLLATE_SUBST_PRIORITY (0x40000000) /* bit indicates subst table */ @@ -117,6 +123,7 @@ int __collate_load_error; char * map; size_t maplen; + int econv; collate_info_t *info; collate_char_t *char_pri_table; Index: lib/libc/locale/collate.c =================================================================== --- lib/libc/locale/collate.c +++ lib/libc/locale/collate.c @@ -119,6 +119,8 @@ collate_info_t *info; struct stat sbuf; int fd; + int econv; + table->__collate_load_error = 1; @@ -150,11 +152,15 @@ return (_LDP_ERROR); } - if (strncmp(TMP, COLLATE_VERSION, COLLATE_STR_LEN) != 0) { + econv = __check_endian(TMP, COLLATE_STR_LEN, + __COLLATE_VERSION_BE, __COLLATE_VERSION_LE); + if (econv == -1) { + printf("bad endian\n"); (void) munmap(map, sbuf.st_size); errno = EINVAL; return (_LDP_ERROR); } + table->econv = econv; TMP += COLLATE_STR_LEN; info = (void *)TMP; @@ -162,7 +168,7 @@ if ((info->directive_count < 1) || (info->directive_count >= COLL_WEIGHTS_MAX) || - ((chains = BSWAP(info->chain_count)) < 0)) { + ((chains = __fix_endian(econv, info->chain_count)) < 0)) { (void) munmap(map, sbuf.st_size); errno = EINVAL; return (_LDP_ERROR); @@ -170,9 +176,10 @@ i = (sizeof (collate_char_t) * (UCHAR_MAX + 1)) + (sizeof (collate_chain_t) * chains) + - (sizeof (collate_large_t) * BSWAP(info->large_count)); + (sizeof (collate_large_t) * __fix_endian(econv, info->large_count)); for (z = 0; z < info->directive_count; z++) { - i += sizeof (collate_subst_t) * BSWAP(info->subst_count[z]); + i += sizeof (collate_subst_t) * + __fix_endian(econv, info->subst_count[z]); } if (i != (sbuf.st_size - (TMP - map))) { (void) munmap(map, sbuf.st_size); @@ -185,9 +192,10 @@ TMP += sizeof (collate_char_t) * (UCHAR_MAX + 1); for (z = 0; z < info->directive_count; z++) { - if (BSWAP(info->subst_count[z]) > 0) { + if (__fix_endian(econv, info->subst_count[z]) > 0) { table->subst_table[z] = (void *)TMP; - TMP += BSWAP(info->subst_count[z]) * sizeof (collate_subst_t); + TMP += __fix_endian(econv, info->subst_count[z]) * + sizeof (collate_subst_t); } else { table->subst_table[z] = NULL; } @@ -198,7 +206,7 @@ TMP += chains * sizeof (collate_chain_t); } else table->chain_pri_table = NULL; - if (BSWAP(info->large_count) > 0) + if (__fix_endian(econv, info->large_count) > 0) table->large_pri_table = (void *)TMP; else table->large_pri_table = NULL; @@ -211,7 +219,7 @@ substsearch(struct xlocale_collate *table, const wchar_t key, int pass) { const collate_subst_t *p; - int n = BSWAP(table->info->subst_count[pass]); + int n = __fix_endian(table->econv, table->info->subst_count[pass]); if (n == 0) return (NULL); @@ -223,7 +231,7 @@ return (NULL); p = table->subst_table[pass] + (key & ~COLLATE_SUBST_PRIORITY); - assert(BSWAP(p->key) == key); + assert(__fix_endian(table->econv, p->key) == key); return (p->pri); } @@ -232,7 +240,7 @@ chainsearch(struct xlocale_collate *table, const wchar_t *key, int *len) { int low = 0; - int high = BSWAP(table->info->chain_count) - 1; + int high = __fix_endian(table->econv, table->info->chain_count) - 1; int next, compar, l; collate_chain_t *p; collate_chain_t *tab = table->chain_pri_table; @@ -264,7 +272,7 @@ largesearch(struct xlocale_collate *table, const wchar_t key) { int low = 0; - int high = BSWAP(table->info->large_count) - 1; + int high = __fix_endian(table->econv, table->info->large_count) - 1; int next, compar; collate_large_t *p; collate_large_t *tab = table->large_pri_table; @@ -275,7 +283,7 @@ while (low <= high) { next = (low + high) / 2; p = tab + next; - compar = key - BSWAP(p->val); + compar = key - __fix_endian(table->econv, p->val); if (compar == 0) return (p); if (compar > 0) @@ -340,15 +348,16 @@ * Character is a small (8-bit) character. * We just look these up directly for speed. */ - *pri = BSWAP(table->char_pri_table[*t].pri[which]); + *pri = __fix_endian(table->econv, + table->char_pri_table[*t].pri[which]); - } else if ((BSWAP(table->info->large_count) > 0) && + } else if ((__fix_endian(table->econv, table->info->large_count) > 0) && ((match = largesearch(table, *t)) != NULL)) { /* * Character was found in the extended table. */ - *pri = BSWAP(match->pri.pri[which]); + *pri = __fix_endian(table->econv, match->pri.pri[which]); } else { /* @@ -358,7 +367,8 @@ /* Mask off sign bit to prevent ordering confusion. */ *pri = (*t & COLLATE_MAX_PRIORITY); } else { - *pri = BSWAP(table->info->undef_pri[which]); + *pri = __fix_endian(table->econv, + table->info->undef_pri[which]); } /* No substitutions for undefined characters! */ return; @@ -377,9 +387,10 @@ * code ensures this for us. */ if ((sptr = substsearch(table, *pri, which)) != NULL) { - if ((*pri = BSWAP(*sptr)) > 0) { + if ((*pri = __fix_endian(table->econv, *sptr)) > 0) { sptr++; - *state = BSWAP(*sptr) ? sptr : NULL; + *state = __fix_endian(table->econv, *sptr) ? + sptr : NULL; } } @@ -521,7 +532,8 @@ xfrm(struct xlocale_collate *table, unsigned char *p, int pri, int pass) { /* we use unsigned to ensure zero fill on right shift */ - uint32_t val = BSWAP((uint32_t)table->info->pri_count[pass]); + uint32_t val = __fix_endian(table->econv, + (uint32_t)table->info->pri_count[pass]); int nc = 0; while (val) { @@ -681,7 +693,8 @@ e = -1; if (*str <= UCHAR_MAX) e = table->char_pri_table[*str].pri[0]; - else if (BSWAP(table->info->large_count) > 0) { + else if (__fix_endian(table->econv, + table->info->large_count) > 0) { collate_large_t *match_large; match_large = largesearch(table, *str); if (match_large) @@ -691,7 +704,7 @@ return (1); return (e > 0 ? e : 0); } - if (BSWAP(table->info->chain_count) > 0) { + if (__fix_endian(table->econv, table->info->chain_count) > 0) { wchar_t name[COLLATE_STR_LEN]; collate_chain_t *match_chain; int clen; Index: lib/libc/locale/endian.h =================================================================== --- lib/libc/locale/endian.h +++ lib/libc/locale/endian.h @@ -35,18 +35,7 @@ */ #include +#include -/* - * We assume locale files were generated on EL machine - * (e.g. during cross build on amd64 host), but used on EB - * machine (e.g. MIPS64EB), so convert it to host endianness. - * - * TODO: detect host endianness on the build machine and use - * correct macros here. - */ - -#if BYTE_ORDER == BIG_ENDIAN && defined(__mips__) -#define BSWAP(x) le32toh(x) -#else -#define BSWAP(x) x -#endif +int __check_endian(void *, size_t, const char *, const char *); +uint32_t __fix_endian(int, uint32_t); Index: lib/libc/locale/endian.c =================================================================== --- /dev/null +++ lib/libc/locale/endian.c @@ -0,0 +1,41 @@ +#include + +#include "endian.h" + +int +__check_endian(void *buf, size_t sz, const char *bemag, const char *lemag) +{ + int ret; + size_t len; + + ret = 0; + len = strnlen(bemag, sz); + + if (memcmp(buf, bemag, len) == 0) { +#if BYTE_ORDER == LITTLE_ENDIAN + ret = 1; +#endif + } else if (memcmp(buf, lemag, len) == 0) { +#if BYTE_ORDER == BIG_ENDIAN + ret = 1; +#endif + } else + ret = -1; + + return (ret); +} + +uint32_t +__fix_endian(int econv, uint32_t arg) +{ + uint32_t ret; + + if (econv == 1) +#if BYTE_ORDER == BIG_ENDIAN + ret = le32toh(arg); +#else + ret = be32toh(arg); +#endif + + return (ret); +} Index: lib/libc/locale/rune.c =================================================================== --- lib/libc/locale/rune.c +++ lib/libc/locale/rune.c @@ -74,6 +74,7 @@ _FileRuneEntry *mapupper_ext_ranges; int runetype_ext_len = 0; int fd; + int econv; if ((fd = _open(fname, O_RDONLY)) < 0) { errno = EINVAL; @@ -105,34 +106,39 @@ variable = frl + 1; - if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof (frl->magic))) { + econv = __check_endian(frl->magic, sizeof(frl->magic), + __FILE_RUNE_MAGIC_1_BE, __FILE_RUNE_MAGIC_1_LE); + if (econv == -1) goto invalid; - } runetype_ext_ranges = (_FileRuneEntry *)variable; - variable = runetype_ext_ranges + BSWAP(frl->runetype_ext_nranges); + variable = runetype_ext_ranges + + __fix_endian(econv, frl->runetype_ext_nranges); if (variable > lastp) { goto invalid; } maplower_ext_ranges = (_FileRuneEntry *)variable; - variable = maplower_ext_ranges + BSWAP(frl->maplower_ext_nranges); + variable = maplower_ext_ranges + + __fix_endian(econv, frl->maplower_ext_nranges); if (variable > lastp) { goto invalid; } mapupper_ext_ranges = (_FileRuneEntry *)variable; - variable = mapupper_ext_ranges + BSWAP(frl->mapupper_ext_nranges); + variable = mapupper_ext_ranges + + __fix_endian(econv, frl->mapupper_ext_nranges); if (variable > lastp) { goto invalid; } frr = runetype_ext_ranges; - for (x = 0; x < BSWAP(frl->runetype_ext_nranges); ++x) { + for (x = 0; x < __fix_endian(econv, frl->runetype_ext_nranges); ++x) { uint32_t *types; - if (BSWAP(frr[x].map) == 0) { - int len = BSWAP(frr[x].max) - BSWAP(frr[x].min) + 1; + if (__fix_endian(econv, frr[x].map) == 0) { + int len = __fix_endian(econv, frr[x].max) - + __fix_endian(econv, frr[x].min) + 1; types = variable; variable = types + len; runetype_ext_len += len; @@ -142,7 +148,8 @@ } } - if ((char *)variable + BSWAP(frl->variable_len) > (char *)lastp) { + if ((char *)variable + __fix_endian(econv, frl->variable_len) > + (char *)lastp) { goto invalid; } @@ -150,10 +157,11 @@ * Convert from disk format to host format. */ data = malloc(sizeof(_RuneLocale) + - (BSWAP(frl->runetype_ext_nranges) + BSWAP(frl->maplower_ext_nranges) + - BSWAP(frl->mapupper_ext_nranges)) * sizeof(_RuneEntry) + + (__fix_endian(econv, frl->runetype_ext_nranges) + + __fix_endian(econv, frl->maplower_ext_nranges) + + __fix_endian(econv, frl->mapupper_ext_nranges)) * sizeof(_RuneEntry) + runetype_ext_len * sizeof(*rr->__types) + - BSWAP(frl->variable_len)); + __fix_endian(econv, frl->variable_len)); if (data == NULL) { saverr = errno; munmap(fdata, sb.st_size); @@ -167,15 +175,18 @@ memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic)); memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding)); - rl->__variable_len = BSWAP(frl->variable_len); - rl->__runetype_ext.__nranges = BSWAP(frl->runetype_ext_nranges); - rl->__maplower_ext.__nranges = BSWAP(frl->maplower_ext_nranges); - rl->__mapupper_ext.__nranges = BSWAP(frl->mapupper_ext_nranges); + rl->__variable_len = __fix_endian(econv, frl->variable_len); + rl->__runetype_ext.__nranges = __fix_endian(econv, + frl->runetype_ext_nranges); + rl->__maplower_ext.__nranges = __fix_endian(econv, + frl->maplower_ext_nranges); + rl->__mapupper_ext.__nranges = __fix_endian(econv, + frl->mapupper_ext_nranges); for (x = 0; x < _CACHED_RUNES; ++x) { - rl->__runetype[x] = BSWAP(frl->runetype[x]); - rl->__maplower[x] = BSWAP(frl->maplower[x]); - rl->__mapupper[x] = BSWAP(frl->mapupper[x]); + rl->__runetype[x] = __fix_endian(econv, frl->runetype[x]); + rl->__maplower[x] = __fix_endian(econv, frl->maplower[x]); + rl->__mapupper[x] = __fix_endian(econv, frl->mapupper[x]); } rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable; @@ -190,15 +201,16 @@ rl->__variable = rl->__mapupper_ext.__ranges + rl->__mapupper_ext.__nranges; - variable = mapupper_ext_ranges + BSWAP(frl->mapupper_ext_nranges); + variable = mapupper_ext_ranges + + __fix_endian(econv, frl->mapupper_ext_nranges); frr = runetype_ext_ranges; rr = rl->__runetype_ext.__ranges; for (x = 0; x < rl->__runetype_ext.__nranges; ++x) { uint32_t *types; - rr[x].__min = BSWAP(frr[x].min); - rr[x].__max = BSWAP(frr[x].max); - rr[x].__map = BSWAP(frr[x].map); + rr[x].__min = __fix_endian(econv, frr[x].min); + rr[x].__max = __fix_endian(econv, frr[x].max); + rr[x].__map = __fix_endian(econv, frr[x].map); if (rr[x].__map == 0) { int len = rr[x].__max - rr[x].__min + 1; types = variable; @@ -214,17 +226,17 @@ frr = maplower_ext_ranges; rr = rl->__maplower_ext.__ranges; for (x = 0; x < rl->__maplower_ext.__nranges; ++x) { - rr[x].__min = BSWAP(frr[x].min); - rr[x].__max = BSWAP(frr[x].max); - rr[x].__map = BSWAP(frr[x].map); + rr[x].__min = __fix_endian(econv, frr[x].min); + rr[x].__max = __fix_endian(econv, frr[x].max); + rr[x].__map = __fix_endian(econv, frr[x].map); } frr = mapupper_ext_ranges; rr = rl->__mapupper_ext.__ranges; for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) { - rr[x].__min = BSWAP(frr[x].min); - rr[x].__max = BSWAP(frr[x].max); - rr[x].__map = BSWAP(frr[x].map); + rr[x].__min = __fix_endian(econv, frr[x].min); + rr[x].__max = __fix_endian(econv, frr[x].max); + rr[x].__map = __fix_endian(econv, frr[x].map); } memcpy(rl->__variable, variable, rl->__variable_len); Index: lib/libc/locale/runefile.h =================================================================== --- lib/libc/locale/runefile.h +++ lib/libc/locale/runefile.h @@ -44,7 +44,7 @@ } _FileRuneEntry; typedef struct { - char magic[8]; + char magic[10]; char encoding[32]; uint32_t runetype[_CACHED_RUNES]; @@ -58,6 +58,14 @@ int32_t variable_len; } _FileRuneLocale; -#define _FILE_RUNE_MAGIC_1 "RuneMag1" + +#define __FILE_RUNE_MAGIC_1_BE "RuneMag1BE" +#define __FILE_RUNE_MAGIC_1_LE "RuneMag1LE" + +#if BYTE_ORDER == BIG_ENDIAN +#define _FILE_RUNE_MAGIC_1 __FILE_RUNE_MAGIC_1_BE +#else +#define _FILE_RUNE_MAGIC_1 __FILE_RUNE_MAGIC_1_LE +#endif #endif /* !_RUNEFILE_H_ */ Index: usr.bin/localedef/ctype.c =================================================================== --- usr.bin/localedef/ctype.c +++ usr.bin/localedef/ctype.c @@ -305,7 +305,7 @@ if ((f = open_category()) == NULL) return; - (void) memcpy(rl.magic, _FILE_RUNE_MAGIC_1, 8); + (void) memcpy(rl.magic, _FILE_RUNE_MAGIC_1, sizeof(rl.magic)); (void) strlcpy(rl.encoding, get_wide_encoding(), sizeof (rl.encoding)); /*