bz1311954 - multilib variations in LC_COLLATE files, with fixes

DJ Delorie dj@redhat.com
Wed Mar 20 18:25:00 GMT 2019


https://bugzilla.redhat.com/show_bug.cgi?id=1311954

Fedora BZ 1311954 saw that the locale archives were not the same
across all builds; partly that was due to big vs little endian, but
there were differences between 32 and 64-bit on both s390 and x86.

In locale/programs/ld-collate.c we see this:

  /* Add 40% and find the next prime number.  */
  elem_size = next_prime (elem_size * 1.4);

After debugging this for a week, it turned out that when elem_size is
120, "elem_size * 1.4" is 168 - but not exactly 168.  Since 1.4 isn't
exactly representable in IEEE, the result was either 168.00000001 or
167.9999999 - and it turns out that 167 *is prime* so the next_prime()
call returned completely different results depending on the FPU and
rounding.

The solution is to avoid floating point math.

Since elem_size is limited by locale limits, overflow isn't much of a
problem.  There are a couple of simple changes, but which to choose?

/* Same value as before, but "/10" isn't exact */
  elem_size = next_prime (elem_size * 14/10);

/* Slightly different value (37.5%) but now it's exact */
  elem_size = next_prime (elem_size * 11/8);

/* Same as above, but without extra chance of overflow */
  elem_size = next_prime (elem_size + (elem_size>>2) + (elem_size>>3));


Note this math also happens in ./iconv/iconvconfig.c:
  hash_size = next_prime (nnames * 1.4); 



More information about the Libc-alpha mailing list