This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.18-168-g6055173


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  6055173a0f2733ea4fc2825afd295156143fca79 (commit)
      from  39bf0bb44c07ab2cae5b813fc7c196abfdf411b3 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=6055173a0f2733ea4fc2825afd295156143fca79

commit 6055173a0f2733ea4fc2825afd295156143fca79
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Tue Sep 24 22:07:47 2013 +0000

    Add localedef --big-endian and --little-endian options.

diff --git a/ChangeLog b/ChangeLog
index 7bb059e..8126706 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+2013-09-24  Joseph Myers  <joseph@codesourcery.com>
+	    Richard Sandiford  <richard@codesourcery.com>
+
+	* locale/programs/locfile.h: Include <byteswap.h> and <stdbool.h>.
+	(swap_endianness_p): New extern variable.
+	(set_big_endian): New inline function.
+	(maybe_swap_uint32): Likewise.
+	(maybe_swap_uint32_array): Likewise.
+	(maybe_swap_uint32_obstack): Likewise.
+	* locale/programs/locfile.c: Include <stdbool.h>.
+	(swap_endianness_p): New variable.
+	(add_locale_uint32): Call maybe_swap_uint32.
+	(add_locale_uint32_array): Call maybe_swap_uint32_obstack.
+	(write_locale_data): Call maybe_swap_uint32_array.
+	* locale/programs/ld-collate.c (obstack_int32_grow): Call
+	maybe_swap_uint32.
+	(obstack_int32_grow_fast): Likewise.
+	(output_weightwc): Call maybe_swap_uint32_obstack.
+	(collate_output): Likewise.
+	* locale/programs/localedef.c (OPT_LITTLE_ENDIAN): New macro.
+	(OPT_LITTLE_ENDIAN): Likewise.
+	(options): Add --little-endian and --big-endian options.
+	(parse_opt): Handle OPT_LITTLE_ENDIAN and OPT_BIG_ENDIAN.
+	* locale/programs/locarchive.c: Include "locfile.h".
+	(GET): New macro.
+	(SET): Likewise.
+	(INC): Likewise.
+	(create_archive): Use the new macros to access fields of
+	structures directly mapped from or written to locale archives.
+	(oldlocrecentcmp): Likewise.
+	(enlarge_archive): Likewise.
+	(insert_name): Likewise.
+	(add_alias): Likewise.
+	(add_locale): Likewise.
+	(delete_locales_from_archive): Likewise.
+	(show_archive_content): Likewise.
+	(add_locale_to_archive): Likewise.  Use maybe_swap_uint32 on
+	locale data.
+
 2013-09-24  Roland McGrath  <roland@hack.frob.com>
 
 	* manual/freemanuals.texi: Updated from (newly) canonical copy at
diff --git a/NEWS b/NEWS
index 8753077..7f193a4 100644
--- a/NEWS
+++ b/NEWS
@@ -48,6 +48,10 @@ Version 2.19
 
 * ISO 1427 definitions were updated.
 
+* The localedef utility now supports --big-endian and --little-endian
+  command-line options to generate locales for a different system from that
+  for which the C library was built.
+
 * The configure option --disable-versioning has been removed.  Builds with
   --disable-versioning had not worked for several years.
 
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
index c4d7e3d..e610389 100644
--- a/locale/programs/ld-collate.c
+++ b/locale/programs/ld-collate.c
@@ -44,6 +44,7 @@ static inline void
 __attribute ((always_inline))
 obstack_int32_grow (struct obstack *obstack, int32_t data)
 {
+  data = maybe_swap_uint32 (data);
   if (sizeof (int32_t) == sizeof (int))
     obstack_int_grow (obstack, data);
   else
@@ -54,6 +55,7 @@ static inline void
 __attribute ((always_inline))
 obstack_int32_grow_fast (struct obstack *obstack, int32_t data)
 {
+  data = maybe_swap_uint32 (data);
   if (sizeof (int32_t) == sizeof (int))
     obstack_int_grow_fast (obstack, data);
   else
@@ -1955,6 +1957,7 @@ output_weightwc (struct obstack *pool, struct locale_collate_t *collate,
       obstack_int32_grow (pool, j);
 
       obstack_grow (pool, buf, j * sizeof (int32_t));
+      maybe_swap_uint32_obstack (pool, j);
     }
 
   return retval | ((elem->section->ruleidx & 0x7f) << 24);
@@ -2479,6 +2482,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
 	  obstack_int32_grow (&extrapool, runp->nwcs);
 	  obstack_grow (&extrapool, runp->wcs,
 			runp->nwcs * sizeof (uint32_t));
+	  maybe_swap_uint32_obstack (&extrapool, runp->nwcs);
 
 	  obstack_int32_grow (&extrapool, runp->wcseqorder);
 	}
diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
index 5a14f2c..8b9866a 100644
--- a/locale/programs/localedef.c
+++ b/locale/programs/localedef.c
@@ -112,6 +112,8 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
 #define OPT_REPLACE 307
 #define OPT_DELETE_FROM_ARCHIVE 308
 #define OPT_LIST_ARCHIVE 309
+#define OPT_LITTLE_ENDIAN 400
+#define OPT_BIG_ENDIAN 401
 
 /* Definitions of arguments for argp functions.  */
 static const struct argp_option options[] =
@@ -144,6 +146,10 @@ static const struct argp_option options[] =
   { "list-archive", OPT_LIST_ARCHIVE, NULL, 0, N_("List content of archive") },
   { "alias-file", 'A', N_("FILE"), 0,
     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") },
   { NULL, 0, NULL, 0, NULL }
 };
 
@@ -326,6 +332,12 @@ parse_opt (int key, char *arg, struct argp_state *state)
     case OPT_LIST_ARCHIVE:
       list_archive = true;
       break;
+    case OPT_LITTLE_ENDIAN:
+      set_big_endian (false);
+      break;
+    case OPT_BIG_ENDIAN:
+      set_big_endian (true);
+      break;
     case 'c':
       force_output = 1;
       break;
diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c
index d8df39a..13dba0f 100644
--- a/locale/programs/locarchive.c
+++ b/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 */
@@ -819,7 +843,7 @@ add_locale (struct locarhandle *ah,
 
   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 +901,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 +914,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 +959,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 +1029,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 +1053,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 +1082,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 +1163,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 +1527,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 +1539,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 +1626,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 +1648,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 +1674,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 +1708,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/locale/programs/locfile.c b/locale/programs/locfile.c
index cb53bbc..4969391 100644
--- a/locale/programs/locfile.c
+++ b/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>
@@ -538,6 +539,10 @@ compare_files (const char *filename1, const char *filename2, size_t size,
   return ret;
 }
 
+/* True if the locale files use the opposite endianness to the
+   machine running localedef.  */
+bool swap_endianness_p;
+
 /* When called outside a start_locale_structure/end_locale_structure
    or start_locale_prelude/end_locale_prelude block, record that the
    next byte in FILE's obstack will be the first byte of a new element.
@@ -624,6 +629,7 @@ add_locale_uint32 (struct locale_file *file, uint32_t value)
 {
   align_locale_data (file, sizeof (uint32_t));
   record_offset (file);
+  value = maybe_swap_uint32 (value);
   obstack_grow (&file->data, &value, sizeof (value));
 }
 
@@ -636,6 +642,7 @@ add_locale_uint32_array (struct locale_file *file,
   align_locale_data (file, sizeof (uint32_t));
   record_offset (file);
   obstack_grow (&file->data, data, n_elems * sizeof (uint32_t));
+  maybe_swap_uint32_obstack (&file->data, n_elems);
 }
 
 /* Record that FILE's next element is the single byte given by VALUE.  */
@@ -708,6 +715,8 @@ write_locale_data (const char *output_path, int catidx, const char *category,
   vec[1].iov_base = file->offsets;
   vec[2].iov_len = obstack_object_size (&file->data);
   vec[2].iov_base = obstack_finish (&file->data);
+  maybe_swap_uint32_array (vec[0].iov_base, 2);
+  maybe_swap_uint32_array (vec[1].iov_base, file->n_elements);
   n_elem = 3;
   if (! no_archive)
     {
diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h
index bdd87cc..cb3e22f 100644
--- a/locale/programs/locfile.h
+++ b/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,6 +69,41 @@ extern void write_all_categories (struct localedef_t *definitions,
 				  const char *locname,
 				  const char *output_path);
 
+extern bool swap_endianness_p;
+
+/* Change the output to be big-endian if BIG_ENDIAN is true and
+   little-endian otherwise.  */
+static inline void
+set_big_endian (bool big_endian)
+{
+  swap_endianness_p = (big_endian != (__BYTE_ORDER == __BIG_ENDIAN));
+}
+
+/* Munge VALUE so that, when stored, it has the correct byte order
+   for the output files.  */
+static inline uint32_t
+maybe_swap_uint32 (uint32_t value)
+{
+  return swap_endianness_p ? bswap_32 (value) : value;
+}
+
+/* Likewise, but munge an array of N uint32_ts starting at ARRAY.  */
+static inline void
+maybe_swap_uint32_array (uint32_t *array, size_t n)
+{
+  if (swap_endianness_p)
+    while (n-- > 0)
+      array[n] = bswap_32 (array[n]);
+}
+
+/* Like maybe_swap_uint32_array, but the array of N elements is at
+   the end of OBSTACK's current object.  */
+static inline void
+maybe_swap_uint32_obstack (struct obstack *obstack, size_t n)
+{
+  maybe_swap_uint32_array ((uint32_t *) obstack_next_free (obstack) - n, n);
+}
+
 /* Write out the data.  */
 extern void init_locale_data (struct locale_file *file, size_t n_elements);
 extern void align_locale_data (struct locale_file *file, size_t boundary);

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                    |   39 ++++
 NEWS                         |    4 +
 locale/programs/ld-collate.c |    4 +
 locale/programs/localedef.c  |   12 ++
 locale/programs/locarchive.c |  420 +++++++++++++++++++++++-------------------
 locale/programs/locfile.c    |    9 +
 locale/programs/locfile.h    |   37 ++++
 7 files changed, 335 insertions(+), 190 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]