Add libgmp 6.2.0 to third_party

Don't build it yet.  That will come in the next review.

Change-Id: Idf3266558165e5ab45f4a41c98cc8c838c8244d5
diff --git a/third_party/gmp/mini-gmp/tests/testutils.c b/third_party/gmp/mini-gmp/tests/testutils.c
new file mode 100644
index 0000000..b131a9e
--- /dev/null
+++ b/third_party/gmp/mini-gmp/tests/testutils.c
@@ -0,0 +1,181 @@
+/*
+
+Copyright 2013-2015, 2018 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "testutils.h"
+
+/* Include it here, so we we could tweak, e.g., how MPZ_REALLOC
+   works. */
+#include "../mini-gmp.c"
+#include "../mini-mpq.c"
+
+static size_t total_alloc = 0;
+
+/* Custom memory allocation to track memory usage, and add a small red
+   zone.
+
+   About alignment: In general, getting a block from malloc, and
+   incrementing it by sizeof(size_t), like we do here, might give a
+   pointer which is not properly aligned for all types. But the
+   largest type we allocate space for is unsigned long (mp_limb_t),
+   which shouldn't have stricter alignment requirements than
+   size_t. */
+
+static unsigned char block_end[8] =
+  { 0x7c, 0x37, 0xd6, 0x12, 0xa8, 0x6c, 0x01, 0xd1 };
+
+static void *
+block_init (size_t *block, size_t size)
+{
+  char *p;
+  *block++ = size;
+
+  p = (char *) block;
+  memcpy (p + size, block_end, sizeof(block_end));
+
+  total_alloc += size;
+  return p;
+}
+
+/* Check small redzone, return pointer to malloced block. */
+static size_t *
+block_check  (void *p)
+{
+  size_t *block = (size_t *) p - 1;
+  size_t size = block[0];
+
+  if (memcmp ((char *)p + size, block_end, sizeof(block_end)) != 0)
+    {
+      fprintf (stderr, "red zone overwritten.\n");
+      abort ();
+    }
+  total_alloc -= size;
+  return block;
+}
+
+static void *
+tu_alloc (size_t size)
+{
+  size_t *block = (size_t *) malloc (sizeof(size_t) + size + sizeof(block_end));
+  if (!block)
+    {
+      fprintf (stderr, "Virtual memory exhausted.\n");
+      abort ();
+    }
+
+  return block_init (block, size);
+}
+
+static void *
+tu_realloc (void *p, size_t old_size, size_t new_size)
+{
+  size_t *block = block_check (p);
+  block = (size_t *) realloc (block, sizeof(size_t) + new_size + sizeof(block_end));
+  if (!block)
+    {
+      fprintf (stderr, "Virtual memory exhausted.\n");
+      abort ();
+    }
+
+  return block_init (block, new_size);
+}
+
+static void
+tu_free (void *p, size_t old_size)
+{
+  free (block_check (p));
+}
+
+/* Free memory allocated via mini-gmp allocation function. */
+void
+testfree (void *p)
+{
+  void (*freefunc) (void *, size_t);
+  mp_get_memory_functions (NULL, NULL, &freefunc);
+
+  freefunc (p, 0);
+}
+
+int
+main (int argc, char **argv)
+{
+  hex_random_init ();
+
+  mp_set_memory_functions (tu_alloc, tu_realloc, tu_free);
+
+  /* Currently, t-comb seems to be the only program accepting any
+     arguments. It might make sense to parse common arguments here. */
+  testmain (argc, argv);
+
+  if (total_alloc != 0)
+    {
+      fprintf (stderr, "Memory leaked: %lu bytes.\n",
+	       (unsigned long) total_alloc);
+      abort ();
+    }
+  return 0;
+}
+
+void
+testhalves (int count, void (*tested_fun) (int))
+{
+  void (*freefunc) (void *, size_t);
+  void *(*reallocfunc) (void *, size_t, size_t);
+  void *(*allocfunc) (size_t);
+  size_t initial_alloc;
+
+  mp_get_memory_functions (&allocfunc, &reallocfunc, &freefunc);
+  initial_alloc = total_alloc;
+  (*tested_fun) (count / 2);
+  if (initial_alloc != total_alloc)
+    {
+      fprintf (stderr, "First half, memory leaked: %lu bytes.\n",
+	       (unsigned long) total_alloc - initial_alloc);
+      abort ();
+    }
+  mp_set_memory_functions (NULL, NULL, NULL);
+  (*tested_fun) (count / 2);
+  mp_set_memory_functions (allocfunc, reallocfunc, freefunc);
+}
+
+void
+dump (const char *label, const mpz_t x)
+{
+  char *buf = mpz_get_str (NULL, 16, x);
+  fprintf (stderr, "%s: %s\n", label, buf);
+  testfree (buf);
+}
+
+void
+mpz_set_str_or_abort (mpz_ptr z, const char *str, int base)
+{
+  if (mpz_set_str (z, str, base) != 0)
+    {
+      fprintf (stderr, "ERROR: mpz_set_str failed\n");
+      fprintf (stderr, "   str  = \"%s\"\n", str);
+      fprintf (stderr, "   base = %d\n", base);
+      abort();
+    }
+}
+
+int
+mpz_lucas_mod (mpz_t V, mpz_t Qk, long Q,
+	       mp_bitcnt_t b0, const mpz_t n)
+{
+  return gmp_lucas_mod (V, Qk, Q, b0, n);
+}