diff options
author | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2013-10-18 21:33:25 +0000 |
---|---|---|
committer | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2013-10-18 21:33:25 +0000 |
commit | fe2ed5aaa408e1ab996a9fe1595a05634208a79c (patch) | |
tree | e1027fbc9d8a4a8c33f8149b2b42e8cde89c74f6 /libc/locale | |
parent | 571c782b982d888565e7d06bfc2f3d47582fe829 (diff) |
Merge changes between r23946 and r24305 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@24306 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/locale')
-rw-r--r-- | libc/locale/hashval.h | 2 | ||||
-rw-r--r-- | libc/locale/iso-3166.def | 12 | ||||
-rw-r--r-- | libc/locale/iso-639.def | 17 | ||||
-rw-r--r-- | libc/locale/loadlocale.c | 2 | ||||
-rw-r--r-- | libc/locale/localeinfo.h | 10 | ||||
-rw-r--r-- | libc/locale/programs/3level.h | 4 | ||||
-rw-r--r-- | libc/locale/programs/ld-collate.c | 44 | ||||
-rw-r--r-- | libc/locale/programs/ld-ctype.c | 4 | ||||
-rw-r--r-- | libc/locale/programs/localedef.c | 7 | ||||
-rw-r--r-- | libc/locale/programs/locarchive.c | 427 | ||||
-rw-r--r-- | libc/locale/programs/locfile.c | 7 | ||||
-rw-r--r-- | libc/locale/programs/locfile.h | 22 | ||||
-rw-r--r-- | libc/locale/setlocale.c | 2 | ||||
-rw-r--r-- | libc/locale/weight.h | 16 |
14 files changed, 324 insertions, 252 deletions
diff --git a/libc/locale/hashval.h b/libc/locale/hashval.h index 737162f6b..88e783938 100644 --- a/libc/locale/hashval.h +++ b/libc/locale/hashval.h @@ -37,7 +37,7 @@ compute_hashval (const void *key, size_t keylen) while (cnt < keylen) { hval = (hval << 9) | (hval >> (sizeof hval * CHAR_BIT - 9)); - hval += (hashval_t) *(((char *) key) + cnt++); + hval += (hashval_t) ((const unsigned char *) key)[cnt++]; } return hval != 0 ? hval : ~((hashval_t) 0); } diff --git a/libc/locale/iso-3166.def b/libc/locale/iso-3166.def index a9e1422cb..52997b4bf 100644 --- a/libc/locale/iso-3166.def +++ b/libc/locale/iso-3166.def @@ -33,6 +33,7 @@ DEFINE_COUNTRY_CODE ("BENIN", BJ, BEN, 204) DEFINE_COUNTRY_CODE ("BERMUDA", BM, BMU, 60) DEFINE_COUNTRY_CODE ("BHUTAN", BT, BTN, 64) DEFINE_COUNTRY_CODE ("BOLIVIA", BO, BOL, 68) +DEFINE_COUNTRY_CODE ("BONAIRE, SINT EUSTATIUS AND SABA", BQ, BES, 535) DEFINE_COUNTRY_CODE ("BOSNIA AND HERZEGOVINA", BA, BIH, 70) DEFINE_COUNTRY_CODE ("BOTSWANA", BW, BWA, 72) DEFINE_COUNTRY_CODE ("BOUVET ISLAND", BV, BVT, 74) @@ -62,13 +63,13 @@ DEFINE_COUNTRY_CODE ("COSTA RICA", CR, CRI, 188) DEFINE_COUNTRY_CODE ("COTE D'IVOIRE", CI, CIV, 384) DEFINE_COUNTRY_CODE ("CROATIA", HR, HRV, 191) DEFINE_COUNTRY_CODE ("CUBA", CU, CUB, 192) +DEFINE_COUNTRY_CODE ("CURACAO", CW, CUW, 531) DEFINE_COUNTRY_CODE ("CYPRUS", CY, CYP, 196) DEFINE_COUNTRY_CODE ("CZECH REPUBLIC", CZ, CZE, 203) DEFINE_COUNTRY_CODE ("DENMARK", DK, DNK, 208) DEFINE_COUNTRY_CODE ("DJIBOUTI", DJ, DJI, 262) DEFINE_COUNTRY_CODE ("DOMINICA", DM, DMA, 212) DEFINE_COUNTRY_CODE ("DOMINICAN REPUBLIC", DO, DOM, 214) -DEFINE_COUNTRY_CODE ("EAST TIMOR", TP, TMP, 626) DEFINE_COUNTRY_CODE ("ECUADOR", EC, ECU, 218) DEFINE_COUNTRY_CODE ("EGYPT", EG, EGY, 818) DEFINE_COUNTRY_CODE ("EL SALVADOR", SV, SLV, 222) @@ -175,7 +176,7 @@ DEFINE_COUNTRY_CODE ("NORWAY", NO, NOR, 578) DEFINE_COUNTRY_CODE ("OMAN", OM, OMN, 512) DEFINE_COUNTRY_CODE ("PAKISTAN", PK, PAK, 586) DEFINE_COUNTRY_CODE ("PALAU", PW, PLW, 585) -DEFINE_COUNTRY_CODE ("PALESTINIAN TERRITORY, OCCUPIED", PS, PSE, 275) +DEFINE_COUNTRY_CODE ("PALESTINE, STATE OF", PS, PSE, 275) DEFINE_COUNTRY_CODE ("PANAMA", PA, PAN, 591) DEFINE_COUNTRY_CODE ("PAPUA NEW GUINEA", PG, PNG, 598) DEFINE_COUNTRY_CODE ("PARAGUAY", PY, PRY, 600) @@ -190,9 +191,11 @@ DEFINE_COUNTRY_CODE ("REUNION", RE, REU, 638) DEFINE_COUNTRY_CODE ("ROMANIA", RO, ROU, 642) DEFINE_COUNTRY_CODE ("RUSSIAN FEDERATION", RU, RUS, 643) DEFINE_COUNTRY_CODE ("RWANDA", RW, RWA, 646) +DEFINE_COUNTRY_CODE ("SAINT BARTHELEMY", BL, BLM, 652) DEFINE_COUNTRY_CODE ("SAINT HELENA", SH, SHN, 654) DEFINE_COUNTRY_CODE ("SAINT KITTS AND NEVIS", KN, KNA, 659) DEFINE_COUNTRY_CODE ("SAINT LUCIA", LC, LCA, 662) +DEFINE_COUNTRY_CODE ("SAINT MARTIN (FRENCH PART)", MF, MAF, 663) DEFINE_COUNTRY_CODE ("SAINT PIERRE AND MIQUELON", PM, SPM, 666) DEFINE_COUNTRY_CODE ("SAINT VINCENT AND THE GRENADINES", VC, VCT, 670) DEFINE_COUNTRY_CODE ("SAMOA", WS, WSM, 882) @@ -204,15 +207,17 @@ DEFINE_COUNTRY_CODE ("SERBIA", RS, SRB, 688) DEFINE_COUNTRY_CODE ("SEYCHELLES", SC, SYC, 690) DEFINE_COUNTRY_CODE ("SIERRA LEONE", SL, SLE, 694) DEFINE_COUNTRY_CODE ("SINGAPORE", SG, SGP, 702) +DEFINE_COUNTRY_CODE ("SINT MAARTEN (DUTCH PART)", SX, SXM, 534) DEFINE_COUNTRY_CODE ("SLOVAKIA", SK, SVK, 703) DEFINE_COUNTRY_CODE ("SLOVENIA", SI, SVN, 705) DEFINE_COUNTRY_CODE ("SOLOMON ISLANDS", SB, SLB, 90) DEFINE_COUNTRY_CODE ("SOMALIA", SO, SOM, 706) DEFINE_COUNTRY_CODE ("SOUTH AFRICA", ZA, ZAF, 710) DEFINE_COUNTRY_CODE ("SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS", GS, SGS, 239) +DEFINE_COUNTRY_CODE ("SOUTH SUDAN", SS, SSD, 728) DEFINE_COUNTRY_CODE ("SPAIN", ES, ESP, 724) DEFINE_COUNTRY_CODE ("SRI LANKA", LK, LKA, 144) -DEFINE_COUNTRY_CODE ("SUDAN", SD, SDN, 736) +DEFINE_COUNTRY_CODE ("SUDAN", SD, SDN, 729) DEFINE_COUNTRY_CODE ("SURINAME", SR, SUR, 740) DEFINE_COUNTRY_CODE ("SVALBARD AND JAN MAYEN", SJ, SJM, 744) DEFINE_COUNTRY_CODE ("SWAZILAND", SZ, SWZ, 748) @@ -223,6 +228,7 @@ DEFINE_COUNTRY_CODE ("TAIWAN, PROVINCE OF CHINA", TW, TWN, 158) DEFINE_COUNTRY_CODE ("TAJIKISTAN", TJ, TJK, 762) DEFINE_COUNTRY_CODE ("TANZANIA, UNITED REPUBLIC OF", TZ, TZA, 834) DEFINE_COUNTRY_CODE ("THAILAND", TH, THA, 764) +DEFINE_COUNTRY_CODE ("TIMOR-LESTE", TL, TLS, 626) DEFINE_COUNTRY_CODE ("TOGO", TG, TGO, 768) DEFINE_COUNTRY_CODE ("TOKELAU", TK, TKL, 772) DEFINE_COUNTRY_CODE ("TONGA", TO, TON, 776) diff --git a/libc/locale/iso-639.def b/libc/locale/iso-639.def index 50b5a52f5..83cd7643a 100644 --- a/libc/locale/iso-639.def +++ b/libc/locale/iso-639.def @@ -46,6 +46,7 @@ DEFINE_LANGUAGE_CODE3 ("Austronesian (Other)", map, map) DEFINE_LANGUAGE_CODE ("Avaric", av, ava, ava) DEFINE_LANGUAGE_CODE ("Avestan", ae, ave, ave) DEFINE_LANGUAGE_CODE3 ("Awadhi", awa, awa) +DEFINE_LANGUAGE_CODE ("Aymara, Southern", ay, ayc, ayc) DEFINE_LANGUAGE_CODE ("Aymara", ay, aym, aym) DEFINE_LANGUAGE_CODE ("Azerbaijani", az, aze, aze) DEFINE_LANGUAGE_CODE3 ("Balinese", ban, ban) @@ -95,6 +96,7 @@ DEFINE_LANGUAGE_CODE3 ("Cheyenne", chy, chy) DEFINE_LANGUAGE_CODE2 ("Chhattisgarhi", hne) /* ISO 639-3 */ DEFINE_LANGUAGE_CODE3 ("Chibcha", chb, chb) DEFINE_LANGUAGE_CODE ("Chichewa; Chewa; Nyanja", ny, nya, nya) +DEFINE_LANGUAGE_CODE3 ("Chiga", cgg, cgg) DEFINE_LANGUAGE_CODE ("Chinese", zh, zho, chi) DEFINE_LANGUAGE_CODE3 ("Chinook jargon", chn, chn) DEFINE_LANGUAGE_CODE3 ("Chipewyan", chp, chp) @@ -161,6 +163,7 @@ DEFINE_LANGUAGE_CODE3 ("Friulian", fur, fur) DEFINE_LANGUAGE_CODE ("Fulah", ff, ful, ful) DEFINE_LANGUAGE_CODE ("Gaelic; Scottish Gaelic", gd, gla, gla) DEFINE_LANGUAGE_CODE ("Galician", gl, glg, glg) +DEFINE_LANGUAGE_CODE3 ("Gan Chinese", gan, gan) DEFINE_LANGUAGE_CODE ("Ganda", lg, lug, lug) DEFINE_LANGUAGE_CODE3 ("Gayo", gay, gay) DEFINE_LANGUAGE_CODE3 ("Ga", gaa, gaa) @@ -184,6 +187,7 @@ DEFINE_LANGUAGE_CODE ("Gujarati", gu, guj, guj) DEFINE_LANGUAGE_CODE3 ("Gwich´in", gwi, gwi) DEFINE_LANGUAGE_CODE3 ("Haida", hai, hai) DEFINE_LANGUAGE_CODE ("Haitian; Haitian Creole", ht, hat, hat) +DEFINE_LANGUAGE_CODE3 ("Hakka Chinese", hak, hak) DEFINE_LANGUAGE_CODE ("Hausa", ha, hau, hau) DEFINE_LANGUAGE_CODE3 ("Hawaiian", haw, haw) DEFINE_LANGUAGE_CODE ("Hebrew", he, heb, heb) @@ -194,6 +198,7 @@ DEFINE_LANGUAGE_CODE ("Hindi", hi, hin, hin) DEFINE_LANGUAGE_CODE ("Hiri Motu", ho, hmo, hmo) DEFINE_LANGUAGE_CODE3 ("Hittite", hit, hit) DEFINE_LANGUAGE_CODE3 ("Hmong", hmn, hmn) +DEFINE_LANGUAGE_CODE3 ("Huizhou Chinese", czh, czh) DEFINE_LANGUAGE_CODE ("Hungarian", hu, hun, hun) DEFINE_LANGUAGE_CODE3 ("Hupa", hup, hup) DEFINE_LANGUAGE_CODE3 ("Iban", iba, iba) @@ -219,6 +224,7 @@ DEFINE_LANGUAGE_CODE3 ("Iroquoian languages", iro, iro) DEFINE_LANGUAGE_CODE ("Italian", it, ita, ita) DEFINE_LANGUAGE_CODE ("Japanese", ja, jpn, jpn) DEFINE_LANGUAGE_CODE ("Javanese", jv, jav, jav) +DEFINE_LANGUAGE_CODE3 ("Jinyu Chinese", cjy, cjy) DEFINE_LANGUAGE_CODE3 ("Judeo-Arabic", jrb, jrb) DEFINE_LANGUAGE_CODE3 ("Judeo-Persian", jpr, jpr) DEFINE_LANGUAGE_CODE3 ("Kabardian", kbd, kbd) @@ -267,6 +273,7 @@ DEFINE_LANGUAGE_CODE ("Latvian", lv, lav, lav) DEFINE_LANGUAGE_CODE3 ("Lezghian", lez, lez) DEFINE_LANGUAGE_CODE ("Limburgan; Limburger; Limburgish", li, lim, lim) DEFINE_LANGUAGE_CODE ("Lingala", ln, lin, lin) +DEFINE_LANGUAGE_CODE3 ("Literary Chinese", lzh, lzh) DEFINE_LANGUAGE_CODE ("Lithuanian", lt, lit, lit) DEFINE_LANGUAGE_CODE3 ("Lojban", jbo, jbo) DEFINE_LANGUAGE_CODE3 ("Low German; Low Saxon; German, Low; Saxon, Low", nds, nds) @@ -290,6 +297,7 @@ DEFINE_LANGUAGE_CODE ("Malayalam", ml, mal, mal) DEFINE_LANGUAGE_CODE ("Malay", ms, msa, may) DEFINE_LANGUAGE_CODE ("Maltese", mt, mlt, mlt) DEFINE_LANGUAGE_CODE3 ("Manchu", mnc, mnc) +DEFINE_LANGUAGE_CODE3 ("Mandarin Chinese", cmn, cmn) DEFINE_LANGUAGE_CODE3 ("Mandar", mdr, mdr) DEFINE_LANGUAGE_CODE3 ("Mandingo", man, man) DEFINE_LANGUAGE_CODE3 ("Manipuri", mni, mni) @@ -305,7 +313,10 @@ DEFINE_LANGUAGE_CODE3 ("Mayan languages", myn, myn) DEFINE_LANGUAGE_CODE3 ("Mende", men, men) DEFINE_LANGUAGE_CODE3 ("Mi'kmaq; Micmac", mic, mic) DEFINE_LANGUAGE_CODE3 ("Minangkabau", min, min) -DEFINE_LANGUAGE_CODE3 ("Min Nan", nan, nan) +DEFINE_LANGUAGE_CODE3 ("Min Bei Chinese", mnp, mnp) +DEFINE_LANGUAGE_CODE3 ("Min Dong Chinese", cdo, cdo) +DEFINE_LANGUAGE_CODE3 ("Min Nan Chinese", nan, nan) +DEFINE_LANGUAGE_CODE3 ("Min Zhong Chinese", czo, czo) DEFINE_LANGUAGE_CODE3 ("Mirandese", mwl, mwl) DEFINE_LANGUAGE_CODE3 ("Miscellaneous languages", mis, mis) DEFINE_LANGUAGE_CODE3 ("Mohawk", moh, moh) @@ -369,6 +380,7 @@ DEFINE_LANGUAGE_CODE ("Polish", pl, pol, pol) DEFINE_LANGUAGE_CODE ("Portuguese", pt, por, por) DEFINE_LANGUAGE_CODE3 ("Prakrit languages", pra, pra) DEFINE_LANGUAGE_CODE3 ("Provençal, Old (to 1500)", pro, pro) +DEFINE_LANGUAGE_CODE3 ("Pu-Xian Chinese", cpx, cpx) DEFINE_LANGUAGE_CODE ("Pushto", ps, pus, pus) DEFINE_LANGUAGE_CODE ("Quechua", qu, que, que) DEFINE_LANGUAGE_CODE ("Raeto-Romance", rm, roh, roh) @@ -486,12 +498,15 @@ DEFINE_LANGUAGE_CODE3 ("Waray", war, war) DEFINE_LANGUAGE_CODE3 ("Washo", was, was) DEFINE_LANGUAGE_CODE ("Welsh", cy, cym, wel) DEFINE_LANGUAGE_CODE ("Wolof", wo, wol, wol) +DEFINE_LANGUAGE_CODE3 ("Wu Chinese", wuu, wuu) DEFINE_LANGUAGE_CODE ("Xhosa", xh, xho, xho) +DEFINE_LANGUAGE_CODE3 ("Xiang Chinese", hsn, hsn) DEFINE_LANGUAGE_CODE3 ("Yakut", sah, sah) DEFINE_LANGUAGE_CODE3 ("Yao", yao, yao) DEFINE_LANGUAGE_CODE3 ("Yapese", yap, yap) DEFINE_LANGUAGE_CODE ("Yiddish", yi, yid, yid) DEFINE_LANGUAGE_CODE ("Yoruba", yo, yor, yor) +DEFINE_LANGUAGE_CODE3 ("Yue Chinese", yue, yue) DEFINE_LANGUAGE_CODE3 ("Yupik languages", ypk, ypk) DEFINE_LANGUAGE_CODE3 ("Zande", znd, znd) DEFINE_LANGUAGE_CODE3 ("Zapotec", zap, zap) diff --git a/libc/locale/loadlocale.c b/libc/locale/loadlocale.c index de7e3d01d..45162f136 100644 --- a/libc/locale/loadlocale.c +++ b/libc/locale/loadlocale.c @@ -148,7 +148,7 @@ _nl_intern_locale_data (int category, const void *data, size_t datasize) newdata->values[cnt].string = newdata->filedata + idx; else { - if (idx % __alignof__ (u_int32_t) != 0) + if (!LOCFILE_ALIGNED_P (idx)) goto puntdata; newdata->values[cnt].word = *((const u_int32_t *) (newdata->filedata + idx)); diff --git a/libc/locale/localeinfo.h b/libc/locale/localeinfo.h index 0c40ebe78..b3e078535 100644 --- a/libc/locale/localeinfo.h +++ b/libc/locale/localeinfo.h @@ -87,6 +87,16 @@ struct __locale_data values __flexarr; /* Items, usually pointers into `filedata'. */ }; +/* This alignment is used for 32-bit integers in locale files, both + those that are explicitly int32_t or uint32_t and those that are + wchar_t, regardless of the (possibly smaller) alignment required + for such integers on a particular host. */ +#define LOCFILE_ALIGN sizeof (int32_t) +#define LOCFILE_ALIGN_MASK (LOCFILE_ALIGN - 1) +#define LOCFILE_ALIGN_UP(x) (((x) + LOCFILE_ALIGN - 1) \ + & ~LOCFILE_ALIGN_MASK) +#define LOCFILE_ALIGNED_P(x) (((x) & LOCFILE_ALIGN_MASK) == 0) + /* We know three kinds of collation sorting rules. */ enum coll_sort_rule { diff --git a/libc/locale/programs/3level.h b/libc/locale/programs/3level.h index b8d6ca023..c5f024fe3 100644 --- a/libc/locale/programs/3level.h +++ b/libc/locale/programs/3level.h @@ -270,7 +270,7 @@ CONCAT(add_locale_,TABLE) (struct locale_file *file, struct TABLE *t) + t->level1_size * sizeof (uint32_t) + (t->level2_size << t->q) * sizeof (uint32_t) + (t->level3_size << t->p) * sizeof (ELEMENT); - t->result_size = (last_offset + 3) & ~3ul; + t->result_size = LOCFILE_ALIGN_UP (last_offset); level2_offset = 5 * sizeof (uint32_t) @@ -308,7 +308,7 @@ CONCAT(add_locale_,TABLE) (struct locale_file *file, struct TABLE *t) t->level3_size << t->p); else abort (); - align_locale_data (file, 4); + align_locale_data (file, LOCFILE_ALIGN); end_locale_structure (file); if (t->level1_alloc > 0) diff --git a/libc/locale/programs/ld-collate.c b/libc/locale/programs/ld-collate.c index 04f6e22cd..57742326f 100644 --- a/libc/locale/programs/ld-collate.c +++ b/libc/locale/programs/ld-collate.c @@ -44,9 +44,9 @@ static inline void __attribute ((always_inline)) obstack_int32_grow (struct obstack *obstack, int32_t data) { + assert (LOCFILE_ALIGNED_P (obstack_object_size (obstack))); data = maybe_swap_uint32 (data); - if (sizeof (int32_t) == sizeof (int) - && (obstack_object_size (obstack) & (__alignof__ (int) - 1)) == 0) + if (sizeof (int32_t) == sizeof (int)) obstack_int_grow (obstack, data); else obstack_grow (obstack, &data, sizeof (int32_t)); @@ -56,9 +56,9 @@ static inline void __attribute ((always_inline)) obstack_int32_grow_fast (struct obstack *obstack, int32_t data) { + assert (LOCFILE_ALIGNED_P (obstack_object_size (obstack))); data = maybe_swap_uint32 (data); - if (sizeof (int32_t) == sizeof (int) - && (obstack_object_size (obstack) & (__alignof__ (int) - 1)) == 0) + if (sizeof (int32_t) == sizeof (int)) obstack_int_grow_fast (obstack, data); else obstack_grow (obstack, &data, sizeof (int32_t)); @@ -2080,6 +2080,7 @@ add_to_tablewc (uint32_t ch, struct element_t *runp) weightidx = output_weightwc (atwc.weightpool, atwc.collate, runp); + assert (runp->nwcs > 0); added = (1 + 1 + runp->nwcs - 1) * sizeof (int32_t); if (sizeof (int) == sizeof (int32_t)) obstack_make_room (atwc.extrapool, added); @@ -2157,6 +2158,12 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, obstack_1grow_fast (&weightpool, sect->rules[j]); ++i; } + /* And align the output. */ + i = (nrules * i) % LOCFILE_ALIGN; + if (i > 0) + do + obstack_1grow (&weightpool, '\0'); + while (++i < LOCFILE_ALIGN); add_locale_raw_obstack (&file, &weightpool); @@ -2202,7 +2209,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, struct element_t *runp = collate->mbheads[ch]; struct element_t *lastp; - assert ((obstack_object_size (&extrapool) & uint32_align_mask) == 0); + assert (LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))); tablemb[ch] = -obstack_object_size (&extrapool); @@ -2227,11 +2234,9 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, struct element_t *curp; /* Compute how much space we will need. */ - added = ((sizeof (int32_t) + 1 + 2 * (runp->nmbs - 1) - + uint32_align_mask) - & ~uint32_align_mask); - assert ((obstack_object_size (&extrapool) - & uint32_align_mask) == 0); + added = LOCFILE_ALIGN_UP (sizeof (int32_t) + 1 + + 2 * (runp->nmbs - 1)); + assert (LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))); obstack_make_room (&extrapool, added); /* More than one consecutive entry. We mark this by having @@ -2288,11 +2293,9 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, /* Output the weight info. */ weightidx = output_weight (&weightpool, collate, runp); - added = ((sizeof (int32_t) + 1 + runp->nmbs - 1 - + uint32_align_mask) - & ~uint32_align_mask); - assert ((obstack_object_size (&extrapool) - & uint32_align_mask) == 0); + added = LOCFILE_ALIGN_UP (sizeof (int32_t) + 1 + + runp->nmbs - 1); + assert (LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))); obstack_make_room (&extrapool, added); obstack_int32_grow_fast (&extrapool, weightidx); @@ -2304,7 +2307,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, } /* Add alignment bytes if necessary. */ - while ((obstack_object_size (&extrapool) & uint32_align_mask) != 0) + while (!LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))) obstack_1grow_fast (&extrapool, '\0'); /* Next entry. */ @@ -2313,14 +2316,13 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, } while (runp != NULL); - assert ((obstack_object_size (&extrapool) & uint32_align_mask) == 0); + assert (LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))); /* If the final entry in the list is not a single character we add an UNDEFINED entry here. */ if (lastp->nmbs != 1) { - int added = ((sizeof (int32_t) + 1 + 1 + uint32_align_mask) - & ~uint32_align_mask); + int added = LOCFILE_ALIGN_UP (sizeof (int32_t) + 1 + 1); obstack_make_room (&extrapool, added); obstack_int32_grow_fast (&extrapool, 0); @@ -2330,13 +2332,13 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, obstack_1grow_fast (&extrapool, 0); /* Add alignment bytes if necessary. */ - while ((obstack_object_size (&extrapool) & uint32_align_mask) != 0) + while (!LOCFILE_ALIGNED_P (obstack_object_size (&extrapool))) obstack_1grow_fast (&extrapool, '\0'); } } /* Add padding to the tables if necessary. */ - while ((obstack_object_size (&weightpool) & uint32_align_mask) != 0) + while (!LOCFILE_ALIGNED_P (obstack_object_size (&weightpool))) obstack_1grow (&weightpool, 0); /* Now add the four tables. */ diff --git a/libc/locale/programs/ld-ctype.c b/libc/locale/programs/ld-ctype.c index cbedc78d8..91c5e78b2 100644 --- a/libc/locale/programs/ld-ctype.c +++ b/libc/locale/programs/ld-ctype.c @@ -1032,7 +1032,7 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap, for (cnt = 0; cnt < ctype->nr_charclass; ++cnt) add_locale_string (&file, ctype->classnames[cnt]); add_locale_char (&file, 0); - align_locale_data (&file, 4); + align_locale_data (&file, LOCFILE_ALIGN); end_locale_structure (&file); break; @@ -1042,7 +1042,7 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap, for (cnt = 0; cnt < ctype->map_collection_nr; ++cnt) add_locale_string (&file, ctype->mapnames[cnt]); add_locale_char (&file, 0); - align_locale_data (&file, 4); + align_locale_data (&file, LOCFILE_ALIGN); end_locale_structure (&file); break; diff --git a/libc/locale/programs/localedef.c b/libc/locale/programs/localedef.c index 7af399d7d..51927173a 100644 --- a/libc/locale/programs/localedef.c +++ b/libc/locale/programs/localedef.c @@ -149,7 +149,8 @@ static const struct argp_option options[] = N_("locale.alias file to consult when making archive")}, { "little-endian", OPT_LITTLE_ENDIAN, NULL, 0, N_("Generate little-endian output") }, - { "big-endian", OPT_BIG_ENDIAN, NULL, 0, N_("Generate big-endian output") }, + { "big-endian", OPT_BIG_ENDIAN, NULL, 0, + N_("Generate big-endian output") }, { "uint32-align", OPT_UINT32_ALIGN, "ALIGNMENT", 0, N_("Set the target's uint32_t alignment in bytes (default 4)") }, { NULL, 0, NULL, 0, NULL } @@ -337,10 +338,10 @@ parse_opt (int key, char *arg, struct argp_state *state) list_archive = true; break; case OPT_LITTLE_ENDIAN: - set_big_endian (0); + set_big_endian (false); break; case OPT_BIG_ENDIAN: - set_big_endian (1); + set_big_endian (true); break; case OPT_UINT32_ALIGN: uint32_align_mask = strtol (arg, NULL, 0) - 1; diff --git a/libc/locale/programs/locarchive.c b/libc/locale/programs/locarchive.c index d8df39a8e..e2a30b568 100644 --- a/libc/locale/programs/locarchive.c +++ b/libc/locale/programs/locarchive.c @@ -46,6 +46,7 @@ #include "../localeinfo.h" #include "../locarchive.h" #include "localedef.h" +#include "locfile.h" /* Define the hash function. We define the function as static inline. We must change the name so as not to conflict with simple-hash.h. */ @@ -74,6 +75,13 @@ static const char *locnames[] = #define INITIAL_NUM_SUMS 2000 +/* Get and set values (possibly endian-swapped) in structures mapped + from or written directly to locale archives. */ +#define GET(FIELD) maybe_swap_uint32 (FIELD) +#define SET(FIELD, VALUE) ((FIELD) = maybe_swap_uint32 (VALUE)) +#define INC(FIELD, INCREMENT) SET (FIELD, GET (FIELD) + (INCREMENT)) + + /* Size of the reserved address space area. */ #define RESERVE_MMAP_SIZE 512 * 1024 * 1024 @@ -125,27 +133,31 @@ create_archive (const char *archivefname, struct locarhandle *ah) error (EXIT_FAILURE, errno, _("cannot create temporary file: %s"), fname); /* Create the initial content of the archive. */ - head.magic = AR_MAGIC; - head.serial = 0; - head.namehash_offset = sizeof (struct locarhead); - head.namehash_used = 0; - head.namehash_size = next_prime (INITIAL_NUM_NAMES); - - head.string_offset = (head.namehash_offset - + head.namehash_size * sizeof (struct namehashent)); - head.string_used = 0; - head.string_size = INITIAL_SIZE_STRINGS; - - head.locrectab_offset = head.string_offset + head.string_size; - head.locrectab_used = 0; - head.locrectab_size = INITIAL_NUM_LOCREC; - - head.sumhash_offset = (head.locrectab_offset - + head.locrectab_size * sizeof (struct locrecent)); - head.sumhash_used = 0; - head.sumhash_size = next_prime (INITIAL_NUM_SUMS); - - total = head.sumhash_offset + head.sumhash_size * sizeof (struct sumhashent); + SET (head.magic, AR_MAGIC); + SET (head.serial, 0); + SET (head.namehash_offset, sizeof (struct locarhead)); + SET (head.namehash_used, 0); + SET (head.namehash_size, next_prime (INITIAL_NUM_NAMES)); + + SET (head.string_offset, + (GET (head.namehash_offset) + + GET (head.namehash_size) * sizeof (struct namehashent))); + SET (head.string_used, 0); + SET (head.string_size, INITIAL_SIZE_STRINGS); + + SET (head.locrectab_offset, + GET (head.string_offset) + GET (head.string_size)); + SET (head.locrectab_used, 0); + SET (head.locrectab_size, INITIAL_NUM_LOCREC); + + SET (head.sumhash_offset, + (GET (head.locrectab_offset) + + GET (head.locrectab_size) * sizeof (struct locrecent))); + SET (head.sumhash_used, 0); + SET (head.sumhash_size, next_prime (INITIAL_NUM_SUMS)); + + total = (GET (head.sumhash_offset) + + GET (head.sumhash_size) * sizeof (struct sumhashent)); /* Write out the header and create room for the other data structures. */ if (TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head))) != sizeof (head)) @@ -240,10 +252,10 @@ oldlocrecentcmp (const void *a, const void *b) for (cnt = 0; cnt < __LC_LAST; ++cnt) if (cnt != LC_ALL) { - if (la->record[cnt].offset < start_a) - start_a = la->record[cnt].offset; - if (la->record[cnt].offset + la->record[cnt].len > end_a) - end_a = la->record[cnt].offset + la->record[cnt].len; + if (GET (la->record[cnt].offset) < start_a) + start_a = GET (la->record[cnt].offset); + if (GET (la->record[cnt].offset) + GET (la->record[cnt].len) > end_a) + end_a = GET (la->record[cnt].offset) + GET (la->record[cnt].len); } assert (start_a != (uint32_t)-1); assert (end_a != 0); @@ -251,10 +263,10 @@ oldlocrecentcmp (const void *a, const void *b) for (cnt = 0; cnt < __LC_LAST; ++cnt) if (cnt != LC_ALL) { - if (lb->record[cnt].offset < start_b) - start_b = lb->record[cnt].offset; - if (lb->record[cnt].offset + lb->record[cnt].len > end_b) - end_b = lb->record[cnt].offset + lb->record[cnt].len; + if (GET (lb->record[cnt].offset) < start_b) + start_b = GET (lb->record[cnt].offset); + if (GET (lb->record[cnt].offset) + GET (lb->record[cnt].len) > end_b) + end_b = GET (lb->record[cnt].offset) + GET (lb->record[cnt].len); } assert (start_b != (uint32_t)-1); assert (end_b != 0); @@ -371,38 +383,42 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head) /* Create the new archive header. The sizes of the various tables should be double from what is currently used. */ - newhead.namehash_size = MAX (next_prime (2 * newhead.namehash_used), - newhead.namehash_size); + SET (newhead.namehash_size, + MAX (next_prime (2 * GET (newhead.namehash_used)), + GET (newhead.namehash_size))); if (verbose) printf ("name: size: %u, used: %d, new: size: %u\n", - head->namehash_size, head->namehash_used, newhead.namehash_size); + GET (head->namehash_size), + GET (head->namehash_used), GET (newhead.namehash_size)); - newhead.string_offset = (newhead.namehash_offset - + (newhead.namehash_size - * sizeof (struct namehashent))); + SET (newhead.string_offset, (GET (newhead.namehash_offset) + + (GET (newhead.namehash_size) + * sizeof (struct namehashent)))); /* Keep the string table size aligned to 4 bytes, so that all the struct { uint32_t } types following are happy. */ - newhead.string_size = MAX ((2 * newhead.string_used + 3) & -4, - newhead.string_size); + SET (newhead.string_size, MAX ((2 * GET (newhead.string_used) + 3) & -4, + GET (newhead.string_size))); - newhead.locrectab_offset = newhead.string_offset + newhead.string_size; - newhead.locrectab_size = MAX (2 * newhead.locrectab_used, - newhead.locrectab_size); + SET (newhead.locrectab_offset, + GET (newhead.string_offset) + GET (newhead.string_size)); + SET (newhead.locrectab_size, MAX (2 * GET (newhead.locrectab_used), + GET (newhead.locrectab_size))); - newhead.sumhash_offset = (newhead.locrectab_offset - + (newhead.locrectab_size - * sizeof (struct locrecent))); - newhead.sumhash_size = MAX (next_prime (2 * newhead.sumhash_used), - newhead.sumhash_size); + SET (newhead.sumhash_offset, (GET (newhead.locrectab_offset) + + (GET (newhead.locrectab_size) + * sizeof (struct locrecent)))); + SET (newhead.sumhash_size, + MAX (next_prime (2 * GET (newhead.sumhash_used)), + GET (newhead.sumhash_size))); - total = (newhead.sumhash_offset - + newhead.sumhash_size * sizeof (struct sumhashent)); + total = (GET (newhead.sumhash_offset) + + GET (newhead.sumhash_size) * sizeof (struct sumhashent)); /* The new file is empty now. */ - newhead.namehash_used = 0; - newhead.string_used = 0; - newhead.locrectab_used = 0; - newhead.sumhash_used = 0; + SET (newhead.namehash_used, 0); + SET (newhead.string_used, 0); + SET (newhead.locrectab_used, 0); + SET (newhead.sumhash_used, 0); /* Write out the header and create room for the other data structures. */ if (TEMP_FAILURE_RETRY (write (fd, &newhead, sizeof (newhead))) @@ -453,17 +469,17 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head) /* Walk through the hash name hash table to find out what data is still referenced and transfer it into the new file. */ oldnamehashtab = (struct namehashent *) ((char *) ah->addr - + head->namehash_offset); + + GET (head->namehash_offset)); /* Sort the old locrec table in order of data position. */ - struct oldlocrecent oldlocrecarray[head->namehash_size]; - for (cnt = 0, loccnt = 0; cnt < head->namehash_size; ++cnt) - if (oldnamehashtab[cnt].locrec_offset != 0) + struct oldlocrecent oldlocrecarray[GET (head->namehash_size)]; + for (cnt = 0, loccnt = 0; cnt < GET (head->namehash_size); ++cnt) + if (GET (oldnamehashtab[cnt].locrec_offset) != 0) { oldlocrecarray[loccnt].cnt = cnt; oldlocrecarray[loccnt++].locrec = (struct locrecent *) ((char *) ah->addr - + oldnamehashtab[cnt].locrec_offset); + + GET (oldnamehashtab[cnt].locrec_offset)); } qsort (oldlocrecarray, loccnt, sizeof (struct oldlocrecent), oldlocrecentcmp); @@ -479,9 +495,9 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head) for (idx = 0; idx < __LC_LAST; ++idx) if (idx != LC_ALL) { - old_data[idx].size = oldlocrec->record[idx].len; + old_data[idx].size = GET (oldlocrec->record[idx].len); old_data[idx].addr - = ((char *) ah->addr + oldlocrec->record[idx].offset); + = ((char *) ah->addr + GET (oldlocrec->record[idx].offset)); __md5_buffer (old_data[idx].addr, old_data[idx].size, old_data[idx].sum); @@ -491,20 +507,23 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head) { const char *oldname = ((char *) ah->addr - + oldnamehashtab[oldlocrecarray[cnt - 1].cnt].name_offset); - - add_alias (&new_ah, - ((char *) ah->addr - + oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset), - 0, oldname, &last_locrec_offset); + + GET (oldnamehashtab[oldlocrecarray[cnt + - 1].cnt].name_offset)); + + add_alias + (&new_ah, + ((char *) ah->addr + + GET (oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset)), + 0, oldname, &last_locrec_offset); continue; } last_locrec_offset = - add_locale (&new_ah, - ((char *) ah->addr - + oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset), - old_data, 0); + add_locale + (&new_ah, + ((char *) ah->addr + + GET (oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset)), + old_data, 0); if (last_locrec_offset == 0) error (EXIT_FAILURE, 0, _("cannot extend locale archive file")); } @@ -672,26 +691,28 @@ insert_name (struct locarhandle *ah, { const struct locarhead *const head = ah->addr; struct namehashent *namehashtab - = (struct namehashent *) ((char *) ah->addr + head->namehash_offset); + = (struct namehashent *) ((char *) ah->addr + + GET (head->namehash_offset)); unsigned int insert_idx, idx, incr; /* Hash value of the locale name. */ uint32_t hval = archive_hashval (name, name_len); insert_idx = -1; - idx = hval % head->namehash_size; - incr = 1 + hval % (head->namehash_size - 2); + idx = hval % GET (head->namehash_size); + incr = 1 + hval % (GET (head->namehash_size) - 2); /* If the name_offset field is zero this means this is a deleted entry and therefore no entry can be found. */ - while (namehashtab[idx].name_offset != 0) + while (GET (namehashtab[idx].name_offset) != 0) { - if (namehashtab[idx].hashval == hval - && strcmp (name, - (char *) ah->addr + namehashtab[idx].name_offset) == 0) + if (GET (namehashtab[idx].hashval) == hval + && (strcmp (name, + (char *) ah->addr + GET (namehashtab[idx].name_offset)) + == 0)) { /* Found the entry. */ - if (namehashtab[idx].locrec_offset != 0 && ! replace) + if (GET (namehashtab[idx].locrec_offset) != 0 && ! replace) { if (! be_quiet) error (0, 0, _("locale '%s' already exists"), name); @@ -701,26 +722,27 @@ insert_name (struct locarhandle *ah, break; } - if (namehashtab[idx].hashval == hval && ! be_quiet) + if (GET (namehashtab[idx].hashval) == hval && ! be_quiet) { error (0, 0, "hash collision (%u) %s, %s", - hval, name, (char *) ah->addr + namehashtab[idx].name_offset); + hval, name, + (char *) ah->addr + GET (namehashtab[idx].name_offset)); } /* Remember the first place we can insert the new entry. */ - if (namehashtab[idx].locrec_offset == 0 && insert_idx == -1) + if (GET (namehashtab[idx].locrec_offset) == 0 && insert_idx == -1) insert_idx = idx; idx += incr; - if (idx >= head->namehash_size) - idx -= head->namehash_size; + if (idx >= GET (head->namehash_size)) + idx -= GET (head->namehash_size); } /* Add as early as possible. */ if (insert_idx != -1) idx = insert_idx; - namehashtab[idx].hashval = hval; /* no-op if replacing an old entry. */ + SET (namehashtab[idx].hashval, hval); /* no-op if replacing an old entry. */ return &namehashtab[idx]; } @@ -736,12 +758,13 @@ add_alias (struct locarhandle *ah, const char *alias, bool replace, if (namehashent == NULL && ! replace) return; - if (namehashent->name_offset == 0) + if (GET (namehashent->name_offset) == 0) { /* We are adding a new hash entry for this alias. Determine whether we have to resize the file. */ - if (head->string_used + name_len + 1 > head->string_size - || 100 * head->namehash_used > 75 * head->namehash_size) + if (GET (head->string_used) + name_len + 1 > GET (head->string_size) + || (100 * GET (head->namehash_used) + > 75 * GET (head->namehash_size))) { /* The current archive is not large enough. */ enlarge_archive (ah, head); @@ -749,9 +772,9 @@ add_alias (struct locarhandle *ah, const char *alias, bool replace, /* The locrecent might have moved, so we have to look up the old name afresh. */ namehashent = insert_name (ah, oldname, strlen (oldname), true); - assert (namehashent->name_offset != 0); - assert (namehashent->locrec_offset != 0); - *locrec_offset_p = namehashent->locrec_offset; + assert (GET (namehashent->name_offset) != 0); + assert (GET (namehashent->locrec_offset) != 0); + *locrec_offset_p = GET (namehashent->locrec_offset); /* Tail call to try the whole thing again. */ add_alias (ah, alias, replace, oldname, locrec_offset_p); @@ -759,26 +782,27 @@ add_alias (struct locarhandle *ah, const char *alias, bool replace, } /* Add the name string. */ - memcpy (ah->addr + head->string_offset + head->string_used, + memcpy (ah->addr + GET (head->string_offset) + GET (head->string_used), alias, name_len + 1); - namehashent->name_offset = head->string_offset + head->string_used; - head->string_used += name_len + 1; + SET (namehashent->name_offset, + GET (head->string_offset) + GET (head->string_used)); + INC (head->string_used, name_len + 1); - ++head->namehash_used; + INC (head->namehash_used, 1); } - if (namehashent->locrec_offset != 0) + if (GET (namehashent->locrec_offset) != 0) { /* Replacing an existing entry. Mark that we are no longer using the old locrecent. */ struct locrecent *locrecent = (struct locrecent *) ((char *) ah->addr - + namehashent->locrec_offset); - --locrecent->refs; + + GET (namehashent->locrec_offset)); + INC (locrecent->refs, -1); } /* Point this entry at the locrecent installed for the main name. */ - namehashent->locrec_offset = locrec_offset; + SET (namehashent->locrec_offset, locrec_offset); } static int /* qsort comparator used below */ @@ -814,12 +838,17 @@ add_locale (struct locarhandle *ah, off64_t lastoffset; char *ptr; struct locale_category_data *size_order[__LC_LAST]; - const size_t pagesz = getpagesize (); + /* Page size alignment is a minor optimization for locality; use a + common value here rather than making the localedef output depend + on the page size of the system on which localedef is run. See + <https://sourceware.org/glibc/wiki/Development_Todo/Master#Locale_archive_alignment> + for more discussion. */ + const size_t pagesz = 4096; int small_mask; head = ah->addr; sumhashtab = (struct sumhashent *) ((char *) ah->addr - + head->sumhash_offset); + + GET (head->sumhash_offset)); memset (file_offsets, 0, sizeof (file_offsets)); @@ -877,10 +906,10 @@ add_locale (struct locarhandle *ah, table. */ hval = archive_hashval (data[cnt].sum, 16); - idx = hval % head->sumhash_size; - incr = 1 + hval % (head->sumhash_size - 2); + idx = hval % GET (head->sumhash_size); + incr = 1 + hval % (GET (head->sumhash_size) - 2); - while (sumhashtab[idx].file_offset != 0) + while (GET (sumhashtab[idx].file_offset) != 0) { if (memcmp (data[cnt].sum, sumhashtab[idx].sum, 16) == 0) { @@ -890,40 +919,42 @@ add_locale (struct locarhandle *ah, Unfortunately the sumhashent record does not include the size of the stored data. So we have to search for it. */ - locrecent = (struct locrecent *) ((char *) ah->addr - + head->locrectab_offset); + locrecent + = (struct locrecent *) ((char *) ah->addr + + GET (head->locrectab_offset)); size_t iloc; - for (iloc = 0; iloc < head->locrectab_used; ++iloc) - if (locrecent[iloc].refs != 0 - && (locrecent[iloc].record[cnt].offset - == sumhashtab[idx].file_offset)) + for (iloc = 0; iloc < GET (head->locrectab_used); ++iloc) + if (GET (locrecent[iloc].refs) != 0 + && (GET (locrecent[iloc].record[cnt].offset) + == GET (sumhashtab[idx].file_offset))) break; - if (iloc != head->locrectab_used - && data[cnt].size == locrecent[iloc].record[cnt].len + if (iloc != GET (head->locrectab_used) + && data[cnt].size == GET (locrecent[iloc].record[cnt].len) /* We have to compare the content. Either we can have the data mmaped or we have to read from the file. */ - && (file_data_available_p (ah, sumhashtab[idx].file_offset, - data[cnt].size) + && (file_data_available_p + (ah, GET (sumhashtab[idx].file_offset), + data[cnt].size) ? memcmp (data[cnt].addr, (char *) ah->addr - + sumhashtab[idx].file_offset, + + GET (sumhashtab[idx].file_offset), data[cnt].size) == 0 : compare_from_file (ah, data[cnt].addr, - sumhashtab[idx].file_offset, + GET (sumhashtab[idx].file_offset), data[cnt].size) == 0)) { /* Found it. */ - file_offsets[cnt] = sumhashtab[idx].file_offset; + file_offsets[cnt] = GET (sumhashtab[idx].file_offset); --num_new_offsets; break; } } idx += incr; - if (idx >= head->sumhash_size) - idx -= head->sumhash_size; + if (idx >= GET (head->sumhash_size)) + idx -= GET (head->sumhash_size); } } @@ -933,11 +964,14 @@ add_locale (struct locarhandle *ah, return 0; /* Determine whether we have to resize the file. */ - if (100 * (head->sumhash_used + num_new_offsets) > 75 * head->sumhash_size - || (namehashent->locrec_offset == 0 - && (head->locrectab_used == head->locrectab_size - || head->string_used + name_len + 1 > head->string_size - || 100 * head->namehash_used > 75 * head->namehash_size))) + if ((100 * (GET (head->sumhash_used) + num_new_offsets) + > 75 * GET (head->sumhash_size)) + || (GET (namehashent->locrec_offset) == 0 + && (GET (head->locrectab_used) == GET (head->locrectab_size) + || (GET (head->string_used) + name_len + 1 + > GET (head->string_size)) + || (100 * GET (head->namehash_used) + > 75 * GET (head->namehash_size))))) { /* The current archive is not large enough. */ enlarge_archive (ah, head); @@ -1000,20 +1034,20 @@ add_locale (struct locarhandle *ah, /* Add the hash value to the hash table. */ md5hval = archive_hashval (data[cnt].sum, 16); - idx = md5hval % head->sumhash_size; - incr = 1 + md5hval % (head->sumhash_size - 2); + idx = md5hval % GET (head->sumhash_size); + incr = 1 + md5hval % (GET (head->sumhash_size) - 2); - while (sumhashtab[idx].file_offset != 0) + while (GET (sumhashtab[idx].file_offset) != 0) { idx += incr; - if (idx >= head->sumhash_size) - idx -= head->sumhash_size; + if (idx >= GET (head->sumhash_size)) + idx -= GET (head->sumhash_size); } memcpy (sumhashtab[idx].sum, data[cnt].sum, 16); - sumhashtab[idx].file_offset = file_offsets[cnt]; + SET (sumhashtab[idx].file_offset, file_offsets[cnt]); - ++head->sumhash_used; + INC (head->sumhash_used, 1); } lastoffset = file_offsets[LC_ALL]; @@ -1024,25 +1058,28 @@ add_locale (struct locarhandle *ah, lastoffset += (data[cnt].size + 15) & -16; } - if (namehashent->name_offset == 0) + if (GET (namehashent->name_offset) == 0) { /* Add the name string. */ - memcpy ((char *) ah->addr + head->string_offset + head->string_used, + memcpy ((char *) ah->addr + GET (head->string_offset) + + GET (head->string_used), name, name_len + 1); - namehashent->name_offset = head->string_offset + head->string_used; - head->string_used += name_len + 1; - ++head->namehash_used; + SET (namehashent->name_offset, + GET (head->string_offset) + GET (head->string_used)); + INC (head->string_used, name_len + 1); + INC (head->namehash_used, 1); } - if (namehashent->locrec_offset == 0) + if (GET (namehashent->locrec_offset == 0)) { /* Allocate a name location record. */ - namehashent->locrec_offset = (head->locrectab_offset - + (head->locrectab_used++ - * sizeof (struct locrecent))); + SET (namehashent->locrec_offset, (GET (head->locrectab_offset) + + (GET (head->locrectab_used) + * sizeof (struct locrecent)))); + INC (head->locrectab_used, 1); locrecent = (struct locrecent *) ((char *) ah->addr - + namehashent->locrec_offset); - locrecent->refs = 1; + + GET (namehashent->locrec_offset)); + SET (locrecent->refs, 1); } else { @@ -1050,27 +1087,29 @@ add_locale (struct locarhandle *ah, we still need a new one. If not, reuse the old one. */ locrecent = (struct locrecent *) ((char *) ah->addr - + namehashent->locrec_offset); - if (locrecent->refs > 1) + + GET (namehashent->locrec_offset)); + if (GET (locrecent->refs) > 1) { - --locrecent->refs; - namehashent->locrec_offset = (head->locrectab_offset - + (head->locrectab_used++ - * sizeof (struct locrecent))); - locrecent = (struct locrecent *) ((char *) ah->addr - + namehashent->locrec_offset); - locrecent->refs = 1; + INC (locrecent->refs, -1); + SET (namehashent->locrec_offset, (GET (head->locrectab_offset) + + (GET (head->locrectab_used) + * sizeof (struct locrecent)))); + INC (head->locrectab_used, 1); + locrecent + = (struct locrecent *) ((char *) ah->addr + + GET (namehashent->locrec_offset)); + SET (locrecent->refs, 1); } } /* Fill in the table with the locations of the locale data. */ for (cnt = 0; cnt < __LC_LAST; ++cnt) { - locrecent->record[cnt].offset = file_offsets[cnt]; - locrecent->record[cnt].len = data[cnt].size; + SET (locrecent->record[cnt].offset, file_offsets[cnt]); + SET (locrecent->record[cnt].len, data[cnt].size); } - return namehashent->locrec_offset; + return GET (namehashent->locrec_offset); } @@ -1129,7 +1168,8 @@ add_locale_to_archive (ah, name, data, replace) unsigned int strindex[0]; } *filedata = data[LC_CTYPE].addr; codeset = (char *) filedata - + filedata->strindex[_NL_ITEM_INDEX (_NL_CTYPE_CODESET_NAME)]; + + maybe_swap_uint32 (filedata->strindex[_NL_ITEM_INDEX + (_NL_CTYPE_CODESET_NAME)]); char *normalized_codeset_name = NULL; normalized_codeset = _nl_normalize_codeset (codeset, strlen (codeset)); @@ -1492,7 +1532,7 @@ delete_locales_from_archive (nlist, list) head = ah.addr; namehashtab = (struct namehashent *) ((char *) ah.addr - + head->namehash_offset); + + GET (head->namehash_offset)); while (nlist-- > 0) { @@ -1504,30 +1544,31 @@ delete_locales_from_archive (nlist, list) /* Search for this locale in the archive. */ hval = archive_hashval (locname, strlen (locname)); - idx = hval % head->namehash_size; - incr = 1 + hval % (head->namehash_size - 2); + idx = hval % GET (head->namehash_size); + incr = 1 + hval % (GET (head->namehash_size) - 2); /* If the name_offset field is zero this means this is no deleted entry and therefore no entry can be found. */ - while (namehashtab[idx].name_offset != 0) + while (GET (namehashtab[idx].name_offset) != 0) { - if (namehashtab[idx].hashval == hval + if (GET (namehashtab[idx].hashval) == hval && (strcmp (locname, - (char *) ah.addr + namehashtab[idx].name_offset) + ((char *) ah.addr + + GET (namehashtab[idx].name_offset))) == 0)) { /* Found the entry. Now mark it as removed by zero-ing the reference to the locale record. */ - namehashtab[idx].locrec_offset = 0; + SET (namehashtab[idx].locrec_offset, 0); break; } idx += incr; - if (idx >= head->namehash_size) - idx -= head->namehash_size; + if (idx >= GET (head->namehash_size)) + idx -= GET (head->namehash_size); } - if (namehashtab[idx].name_offset == 0 && ! be_quiet) + if (GET (namehashtab[idx].name_offset) == 0 && ! be_quiet) error (0, 0, _("locale \"%s\" not in archive"), locname); } @@ -1590,17 +1631,17 @@ show_archive_content (int verbose) head = ah.addr; - names = (struct nameent *) xmalloc (head->namehash_used + names = (struct nameent *) xmalloc (GET (head->namehash_used) * sizeof (struct nameent)); namehashtab = (struct namehashent *) ((char *) ah.addr - + head->namehash_offset); - for (cnt = used = 0; cnt < head->namehash_size; ++cnt) - if (namehashtab[cnt].locrec_offset != 0) + + GET (head->namehash_offset)); + for (cnt = used = 0; cnt < GET (head->namehash_size); ++cnt) + if (GET (namehashtab[cnt].locrec_offset) != 0) { - assert (used < head->namehash_used); - names[used].name = ah.addr + namehashtab[cnt].name_offset; - names[used++].locrec_offset = namehashtab[cnt].locrec_offset; + assert (used < GET (head->namehash_used)); + names[used].name = ah.addr + GET (namehashtab[cnt].name_offset); + names[used++].locrec_offset = GET (namehashtab[cnt].locrec_offset); } /* Sort the names. */ @@ -1612,17 +1653,17 @@ show_archive_content (int verbose) struct sumhashent *sumhashtab; int sumused; - files = (struct dataent *) xmalloc (head->sumhash_used + files = (struct dataent *) xmalloc (GET (head->sumhash_used) * sizeof (struct dataent)); sumhashtab = (struct sumhashent *) ((char *) ah.addr - + head->sumhash_offset); - for (cnt = sumused = 0; cnt < head->sumhash_size; ++cnt) - if (sumhashtab[cnt].file_offset != 0) + + GET (head->sumhash_offset)); + for (cnt = sumused = 0; cnt < GET (head->sumhash_size); ++cnt) + if (GET (sumhashtab[cnt].file_offset) != 0) { - assert (sumused < head->sumhash_used); + assert (sumused < GET (head->sumhash_used)); files[sumused].sum = (const unsigned char *) sumhashtab[cnt].sum; - files[sumused].file_offset = sumhashtab[cnt].file_offset; + files[sumused].file_offset = GET (sumhashtab[cnt].file_offset); files[sumused++].nlink = 0; } @@ -1638,18 +1679,19 @@ show_archive_content (int verbose) locrec = (struct locrecent *) ((char *) ah.addr + names[cnt].locrec_offset); for (idx = 0; idx < __LC_LAST; ++idx) - if (locrec->record[LC_ALL].offset != 0 + if (GET (locrec->record[LC_ALL].offset) != 0 ? (idx == LC_ALL - || (locrec->record[idx].offset - < locrec->record[LC_ALL].offset) - || (locrec->record[idx].offset + locrec->record[idx].len - > (locrec->record[LC_ALL].offset - + locrec->record[LC_ALL].len))) + || (GET (locrec->record[idx].offset) + < GET (locrec->record[LC_ALL].offset)) + || ((GET (locrec->record[idx].offset) + + GET (locrec->record[idx].len)) + > (GET (locrec->record[LC_ALL].offset) + + GET (locrec->record[LC_ALL].len)))) : idx != LC_ALL) { struct dataent *data, dataent; - dataent.file_offset = locrec->record[idx].offset; + dataent.file_offset = GET (locrec->record[idx].offset); data = (struct dataent *) bsearch (&dataent, files, sumused, sizeof (struct dataent), dataentcmp); @@ -1671,21 +1713,24 @@ show_archive_content (int verbose) { struct dataent *data, dataent; - dataent.file_offset = locrec->record[idx].offset; - if (locrec->record[LC_ALL].offset != 0 - && dataent.file_offset >= locrec->record[LC_ALL].offset - && (dataent.file_offset + locrec->record[idx].len - <= (locrec->record[LC_ALL].offset - + locrec->record[LC_ALL].len))) - dataent.file_offset = locrec->record[LC_ALL].offset; + dataent.file_offset = GET (locrec->record[idx].offset); + if (GET (locrec->record[LC_ALL].offset) != 0 + && (dataent.file_offset + >= GET (locrec->record[LC_ALL].offset)) + && (dataent.file_offset + GET (locrec->record[idx].len) + <= (GET (locrec->record[LC_ALL].offset) + + GET (locrec->record[LC_ALL].len)))) + dataent.file_offset = GET (locrec->record[LC_ALL].offset); data = (struct dataent *) bsearch (&dataent, files, sumused, sizeof (struct dataent), dataentcmp); printf ("%6d %7x %3d%c ", - locrec->record[idx].len, locrec->record[idx].offset, + GET (locrec->record[idx].len), + GET (locrec->record[idx].offset), data->nlink, - dataent.file_offset == locrec->record[LC_ALL].offset + (dataent.file_offset + == GET (locrec->record[LC_ALL].offset)) ? '+' : ' '); for (i = 0; i < 16; i += 4) printf ("%02x%02x%02x%02x", diff --git a/libc/locale/programs/locfile.c b/libc/locale/programs/locfile.c index f9b26493a..f12ca0725 100644 --- a/libc/locale/programs/locfile.c +++ b/libc/locale/programs/locfile.c @@ -22,6 +22,7 @@ #include <dirent.h> #include <errno.h> #include <fcntl.h> +#include <stdbool.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -540,7 +541,7 @@ compare_files (const char *filename1, const char *filename2, size_t size, /* True if the locale files use the opposite endianness to the machine running localedef. */ -int swap_endianness_p; +bool swap_endianness_p; /* The target's value of __align__(uint32_t) - 1. */ unsigned int uint32_align_mask = 3; @@ -629,7 +630,7 @@ add_locale_wstring (struct locale_file *file, const uint32_t *string) void add_locale_uint32 (struct locale_file *file, uint32_t value) { - align_locale_data (file, sizeof (uint32_t)); + align_locale_data (file, LOCFILE_ALIGN); record_offset (file); value = maybe_swap_uint32 (value); obstack_grow (&file->data, &value, sizeof (value)); @@ -641,7 +642,7 @@ void add_locale_uint32_array (struct locale_file *file, const uint32_t *data, size_t n_elems) { - align_locale_data (file, sizeof (uint32_t)); + align_locale_data (file, LOCFILE_ALIGN); record_offset (file); obstack_grow (&file->data, data, n_elems * sizeof (uint32_t)); maybe_swap_uint32_obstack (&file->data, n_elems); diff --git a/libc/locale/programs/locfile.h b/libc/locale/programs/locfile.h index 372bbd402..c784b2a31 100644 --- a/libc/locale/programs/locfile.h +++ b/libc/locale/programs/locfile.h @@ -18,6 +18,8 @@ #ifndef _LOCFILE_H #define _LOCFILE_H 1 +#include <byteswap.h> +#include <stdbool.h> #include <stdint.h> #include <sys/uio.h> @@ -67,26 +69,16 @@ extern void write_all_categories (struct localedef_t *definitions, const char *locname, const char *output_path); -extern int swap_endianness_p; +extern bool swap_endianness_p; extern unsigned int uint32_align_mask; /* Change the output to be big-endian if BIG_ENDIAN is true and little-endian otherwise. */ static inline void -set_big_endian (int big_endian) +set_big_endian (bool big_endian) { - swap_endianness_p = ((big_endian != 0) != (__BYTE_ORDER == __BIG_ENDIAN)); -} - -/* Swap the order of the bytes in VALUE. */ -static inline uint32_t -swap_uint32 (uint32_t value) -{ - return (((value & 0x000000ff) << 24) - | ((value & 0x0000ff00) << 8) - | ((value & 0x00ff0000) >> 8) - | ((value & 0xff000000) >> 24)); + swap_endianness_p = (big_endian != (__BYTE_ORDER == __BIG_ENDIAN)); } /* Munge VALUE so that, when stored, it has the correct byte order @@ -94,7 +86,7 @@ swap_uint32 (uint32_t value) static inline uint32_t maybe_swap_uint32 (uint32_t value) { - return swap_endianness_p ? swap_uint32 (value) : value; + return swap_endianness_p ? bswap_32 (value) : value; } /* Likewise, but munge an array of N uint32_ts starting at ARRAY. */ @@ -103,7 +95,7 @@ maybe_swap_uint32_array (uint32_t *array, size_t n) { if (swap_endianness_p) while (n-- > 0) - array[n] = swap_uint32 (array[n]); + array[n] = bswap_32 (array[n]); } /* Like maybe_swap_uint32_array, but the array of N elements is at diff --git a/libc/locale/setlocale.c b/libc/locale/setlocale.c index f92faee31..ece27a915 100644 --- a/libc/locale/setlocale.c +++ b/libc/locale/setlocale.c @@ -382,7 +382,7 @@ setlocale (int category, const char *locale) /* We must not simply free a global locale since we have no control over the usage. So we mark it as un-deletable. - Note: do not remove the `if', it's necessary to copy with + Note: do not remove the `if', it's necessary to cope with the builtin locale data. */ if (newdata->usage_count != UNDELETABLE) newdata->usage_count = UNDELETABLE; diff --git a/libc/locale/weight.h b/libc/locale/weight.h index 645eda2fe..b097aaca0 100644 --- a/libc/locale/weight.h +++ b/libc/locale/weight.h @@ -69,8 +69,8 @@ findidx (const unsigned char **cpp, size_t len) /* Up to the next entry. */ cp += nhere; - if ((1 + nhere) % __alignof__ (int32_t) != 0) - cp += __alignof__ (int32_t) - (1 + nhere) % __alignof__ (int32_t); + if (!LOCFILE_ALIGNED_P (1 + nhere)) + cp += LOCFILE_ALIGN - (1 + nhere) % LOCFILE_ALIGN; } else { @@ -89,9 +89,9 @@ findidx (const unsigned char **cpp, size_t len) { /* Cannot be in this range. */ cp += 2 * nhere; - if ((1 + 2 * nhere) % __alignof__ (int32_t) != 0) - cp += (__alignof__ (int32_t) - - (1 + 2 * nhere) % __alignof__ (int32_t)); + if (!LOCFILE_ALIGNED_P (1 + 2 * nhere)) + cp += (LOCFILE_ALIGN + - (1 + 2 * nhere) % LOCFILE_ALIGN); continue; } @@ -104,9 +104,9 @@ findidx (const unsigned char **cpp, size_t len) { /* Cannot be in this range. */ cp += 2 * nhere; - if ((1 + 2 * nhere) % __alignof__ (int32_t) != 0) - cp += (__alignof__ (int32_t) - - (1 + 2 * nhere) % __alignof__ (int32_t)); + if (!LOCFILE_ALIGNED_P (1 + 2 * nhere)) + cp += (LOCFILE_ALIGN + - (1 + 2 * nhere) % LOCFILE_ALIGN); continue; } |