summaryrefslogtreecommitdiff
path: root/debian/patches
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/configure.diff115
-rw-r--r--debian/patches/cpu-frequency.diff54
-rw-r--r--debian/patches/disable-double-double-tests.diff489
-rw-r--r--debian/patches/endian-hash.diff111
-rw-r--r--debian/patches/endian-random.diff249
-rw-r--r--debian/patches/fix-hppa.diff26
-rw-r--r--debian/patches/fma-contraction.diff63
-rw-r--r--debian/patches/latomic.diff20
-rw-r--r--debian/patches/nan-narrowing.diff25
-rw-r--r--debian/patches/ppc-float-conversion.diff268
-rw-r--r--debian/patches/series11
-rw-r--r--debian/patches/std-hash.diff46
12 files changed, 1477 insertions, 0 deletions
diff --git a/debian/patches/configure.diff b/debian/patches/configure.diff
new file mode 100644
index 00000000..5c47b152
--- /dev/null
+++ b/debian/patches/configure.diff
@@ -0,0 +1,115 @@
+From: Benjamin Barenblat <bbaren@google.com>
+Subject: Set package configuration options
+Forwarded: not-needed
+
+Configure Abseil for Debian.
+
+ - Set the SONAME appropriately.
+
+ - To minimize the possibility of future ABI breakage, treat absl::any,
+ absl::optional, absl::string_view, and absl::variant as their own types
+ (rather than aliases for the std:: versions), and compile everything in an
+ inline namespace.
+
+ - Enable upstream's hardened build mode.
+
+ - Disable Intel SSE2 on i386, since Debian supports some i386 processors
+ without that extension. Keep it enabled on amd64, since all amd64 processors
+ have it.
+
+ - Disable Intel SSSE3 entirely, since no i386 processor supports it and Debian
+ supports amd64 processors without it.
+
+--- a/CMake/AbseilHelpers.cmake
++++ b/CMake/AbseilHelpers.cmake
+@@ -217,6 +217,9 @@
+ OUTPUT_NAME "absl_${_NAME}"
+ )
+ endif()
++
++ set_property(TARGET ${_NAME} PROPERTY SOVERSION 20200923)
++ set_property(TARGET ${_NAME} PROPERTY VERSION "20200923.0.1")
+ else()
+ # Generating header-only library
+ add_library(${_NAME} INTERFACE)
+--- a/absl/base/options.h
++++ b/absl/base/options.h
+@@ -100,7 +100,7 @@
+ // User code should not inspect this macro. To check in the preprocessor if
+ // absl::any is a typedef of std::any, use the feature macro ABSL_USES_STD_ANY.
+
+-#define ABSL_OPTION_USE_STD_ANY 2
++#define ABSL_OPTION_USE_STD_ANY 0
+
+
+ // ABSL_OPTION_USE_STD_OPTIONAL
+@@ -127,7 +127,7 @@
+ // absl::optional is a typedef of std::optional, use the feature macro
+ // ABSL_USES_STD_OPTIONAL.
+
+-#define ABSL_OPTION_USE_STD_OPTIONAL 2
++#define ABSL_OPTION_USE_STD_OPTIONAL 0
+
+
+ // ABSL_OPTION_USE_STD_STRING_VIEW
+@@ -154,7 +154,7 @@
+ // absl::string_view is a typedef of std::string_view, use the feature macro
+ // ABSL_USES_STD_STRING_VIEW.
+
+-#define ABSL_OPTION_USE_STD_STRING_VIEW 2
++#define ABSL_OPTION_USE_STD_STRING_VIEW 0
+
+ // ABSL_OPTION_USE_STD_VARIANT
+ //
+@@ -180,7 +180,7 @@
+ // absl::variant is a typedef of std::variant, use the feature macro
+ // ABSL_USES_STD_VARIANT.
+
+-#define ABSL_OPTION_USE_STD_VARIANT 2
++#define ABSL_OPTION_USE_STD_VARIANT 0
+
+
+ // ABSL_OPTION_USE_INLINE_NAMESPACE
+@@ -206,7 +206,7 @@
+ // allowed.
+
+ #define ABSL_OPTION_USE_INLINE_NAMESPACE 1
+-#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_2020_09_23
++#define ABSL_OPTION_INLINE_NAMESPACE_NAME debian1
+
+ // ABSL_OPTION_HARDENED
+ //
+@@ -233,6 +233,6 @@
+ // checks enabled by this option may abort the program in a different way and
+ // log additional information when `NDEBUG` is not defined.
+
+-#define ABSL_OPTION_HARDENED 0
++#define ABSL_OPTION_HARDENED 1
+
+ #endif // ABSL_BASE_OPTIONS_H_
+--- a/absl/container/internal/have_sse.h
++++ b/absl/container/internal/have_sse.h
+@@ -17,22 +17,14 @@
+ #define ABSL_CONTAINER_INTERNAL_HAVE_SSE_H_
+
+ #ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
+-#if defined(__SSE2__) || \
+- (defined(_MSC_VER) && \
+- (defined(_M_X64) || (defined(_M_IX86) && _M_IX86_FP >= 2)))
++#if defined(__x86_64__) || (defined(_MSC_VER) && defined(_M_X64))
+ #define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 1
+ #else
+ #define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 0
+ #endif
+ #endif
+
+-#ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3
+-#ifdef __SSSE3__
+-#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 1
+-#else
+ #define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 0
+-#endif
+-#endif
+
+ #if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 && \
+ !ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
diff --git a/debian/patches/cpu-frequency.diff b/debian/patches/cpu-frequency.diff
new file mode 100644
index 00000000..adfba7e0
--- /dev/null
+++ b/debian/patches/cpu-frequency.diff
@@ -0,0 +1,54 @@
+From: Benjamin Barenblat <bbaren@google.com>
+Subject: Ignore missing CPU frequency on more architectures
+Forwarded: yes
+Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/1918ad2ae38aa32c74b558b322479a8efdd76363
+
+Linux on MIPS, PA-RISC, RISC-V, and SystemZ doesn’t expose the nominal CPU
+frequency via /sys, so don’t worry if `NominalCPUFrequency` returns 1.0 on those
+platforms.
+
+Some POWER machines expose the CPU frequency; others do not. Since we can’t
+predict which type of machine the tests will run on, simply disable testing for
+`NominalCPUFrequency` on POWER.
+
+The author works at Google. Upstream applied this patch as Piper revision
+347079873 and exported it to GitHub; the Applied-Upstream URL above points to
+the exported commit.
+
+--- a/absl/base/internal/sysinfo_test.cc
++++ b/absl/base/internal/sysinfo_test.cc
+@@ -37,17 +37,28 @@ TEST(SysinfoTest, NumCPUs) {
+ << "NumCPUs() should not have the default value of 0";
+ }
+
++// Ensure that NominalCPUFrequency returns a reasonable value, or 1.00 on
++// platforms where the CPU frequency is not available through sysfs.
++//
++// POWER is particularly problematic here; some Linux kernels expose the CPU
++// frequency, while others do not. Since we can't predict a priori what a given
++// machine is going to do, just disable this test on POWER on Linux.
++#if !(defined(__linux) && (defined(__ppc64__) || defined(__PPC64__)))
+ TEST(SysinfoTest, NominalCPUFrequency) {
+-#if !(defined(__aarch64__) && defined(__linux__)) && !defined(__EMSCRIPTEN__)
+- EXPECT_GE(NominalCPUFrequency(), 1000.0)
+- << "NominalCPUFrequency() did not return a reasonable value";
+-#else
+- // Aarch64 cannot read the CPU frequency from sysfs, so we get back 1.0.
+- // Emscripten does not have a sysfs to read from at all.
++ // Linux only exposes the CPU frequency on certain architectures, and
++ // Emscripten doesn't expose it at all.
++#if defined(__linux__) && \
++ (defined(__aarch64__) || defined(__hppa__) || defined(__mips__) || \
++ defined(__riscv) || defined(__s390x__)) || \
++ defined(__EMSCRIPTEN__)
+ EXPECT_EQ(NominalCPUFrequency(), 1.0)
+ << "CPU frequency detection was fixed! Please update unittest.";
++#else
++ EXPECT_GE(NominalCPUFrequency(), 1000.0)
++ << "NominalCPUFrequency() did not return a reasonable value";
+ #endif
+ }
++#endif
+
+ TEST(SysinfoTest, GetTID) {
+ EXPECT_EQ(GetTID(), GetTID()); // Basic compile and equality test.
diff --git a/debian/patches/disable-double-double-tests.diff b/debian/patches/disable-double-double-tests.diff
new file mode 100644
index 00000000..e80a8a78
--- /dev/null
+++ b/debian/patches/disable-double-double-tests.diff
@@ -0,0 +1,489 @@
+From: Benjamin Barenblat <bbaren@google.com>
+Subject: Stop testing with double-double random variables
+Forwarded: yes
+Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/ab21820d47e4f83875dda008b600514d3520fd35
+
+On POWER, long double is often represented as a pair of doubles added
+together (double-double arithmetic). We’ve already special-cased
+double-double arithmetic in a number of tests, but compiler
+bugs [1, 2, 3] have now triggered both false positives and false
+negatives, which suggests testing with double doubles is unlikely to
+yield useful signal. Remove the special casing and detect if we’re on a
+double-double system; if so, just don’t test long doubles.
+
+[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048
+[2] https://bugs.llvm.org/show_bug.cgi?id=49131
+[3] https://bugs.llvm.org/show_bug.cgi?id=49132
+
+The author works at Google. Upstream applied this patch as Piper
+revision 360793161 and exported it to GitHub; the the Applied-Upstream
+URL above points to the exported commit.
+
+--- a/CMake/AbseilDll.cmake
++++ b/CMake/AbseilDll.cmake
+@@ -126,6 +126,7 @@ set(ABSL_INTERNAL_DLL_FILES
+ "meta/type_traits.h"
+ "numeric/int128.cc"
+ "numeric/int128.h"
++ "numeric/internal/representation.h"
+ "random/bernoulli_distribution.h"
+ "random/beta_distribution.h"
+ "random/bit_gen_ref.h"
+--- a/absl/numeric/BUILD.bazel
++++ b/absl/numeric/BUILD.bazel
+@@ -72,3 +72,15 @@
+ "@com_github_google_benchmark//:benchmark_main",
+ ],
+ )
++
++cc_library(
++ name = "representation",
++ hdrs = [
++ "internal/representation.h",
++ ],
++ copts = ABSL_DEFAULT_COPTS,
++ linkopts = ABSL_DEFAULT_LINKOPTS,
++ deps = [
++ "//absl/base:config",
++ ],
++)
+--- a/absl/numeric/CMakeLists.txt
++++ b/absl/numeric/CMakeLists.txt
+@@ -59,3 +59,15 @@
+ absl::int128
+ PUBLIC
+ )
++
++absl_cc_library(
++ NAME
++ numeric_representation
++ HDRS
++ "internal/representation.h"
++ COPTS
++ ${ABSL_DEFAULT_COPTS}
++ DEPS
++ absl::config
++ PUBLIC
++)
+--- /dev/null
++++ b/absl/numeric/internal/representation.h
+@@ -0,0 +1,55 @@
++// Copyright 2021 The Abseil Authors
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// https://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++
++#ifndef ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_
++#define ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_
++
++#include <limits>
++
++#include "absl/base/config.h"
++
++namespace absl {
++ABSL_NAMESPACE_BEGIN
++namespace numeric_internal {
++
++// Returns true iff long double is represented as a pair of doubles added
++// together.
++inline constexpr bool IsDoubleDouble() {
++ // A double-double value always has exactly twice the precision of a double
++ // value--one double carries the high digits and one double carries the low
++ // digits. This property is not shared with any other common floating-point
++ // representation, so this test won't trigger false positives. For reference,
++ // this table gives the number of bits of precision of each common
++ // floating-point representation:
++ //
++ // type precision
++ // IEEE single 24 b
++ // IEEE double 53
++ // x86 long double 64
++ // double-double 106
++ // IEEE quadruple 113
++ //
++ // Note in particular that a quadruple-precision float has greater precision
++ // than a double-double float despite taking up the same amount of memory; the
++ // quad has more of its bits allocated to the mantissa than the double-double
++ // has.
++ return std::numeric_limits<long double>::digits ==
++ 2 * std::numeric_limits<double>::digits;
++}
++
++} // namespace numeric_internal
++ABSL_NAMESPACE_END
++} // namespace absl
++
++#endif // ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_
+--- a/absl/random/BUILD.bazel
++++ b/absl/random/BUILD.bazel
+@@ -187,6 +187,7 @@ cc_test(name = "beta_distribution_test",
+ ":distributions",
+ ":random",
+ "//absl/base:raw_logging_internal",
++ "//absl/numeric:representation",
+ "//absl/random/internal:distribution_test_util",
+ "//absl/random/internal:pcg_engine",
+ "//absl/random/internal:sequence_urbg",
+@@ -307,6 +308,7 @@ cc_test(name = "exponential_distribution_test",
+ ":random",
+ "//absl/base:core_headers",
+ "//absl/base:raw_logging_internal",
++ "//absl/numeric:representation",
+ "//absl/random/internal:distribution_test_util",
+ "//absl/random/internal:pcg_engine",
+ "//absl/random/internal:sequence_urbg",
+@@ -330,6 +332,7 @@ cc_test(name = "gaussian_distribution_test",
+ ":random",
+ "//absl/base:core_headers",
+ "//absl/base:raw_logging_internal",
++ "//absl/numeric:representation",
+ "//absl/random/internal:distribution_test_util",
+ "//absl/random/internal:sequence_urbg",
+ "//absl/strings",
+@@ -376,6 +379,7 @@ cc_test(name = "uniform_real_distribution_test",
+ ":distributions",
+ ":random",
+ "//absl/base:raw_logging_internal",
++ "//absl/numeric:representation",
+ "//absl/random/internal:distribution_test_util",
+ "//absl/random/internal:pcg_engine",
+ "//absl/random/internal:sequence_urbg",
+--- a/absl/random/CMakeLists.txt
++++ b/absl/random/CMakeLists.txt
+@@ -259,6 +259,7 @@ absl_cc_test(NAME random_beta_distribution_test
+ LINKOPTS
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
++ absl::numeric_representation
+ absl::random_distributions
+ absl::random_random
+ absl::random_internal_distribution_test_util
+@@ -381,6 +382,7 @@ absl_cc_test(NAME random_exponential_distribution_test
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
+ absl::core_headers
++ absl::numeric_representation
+ absl::random_distributions
+ absl::random_internal_distribution_test_util
+ absl::random_internal_pcg_engine
+@@ -404,6 +406,7 @@ absl_cc_test(NAME random_gaussian_distribution_test
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
+ absl::core_headers
++ absl::numeric_representation
+ absl::random_distributions
+ absl::random_internal_distribution_test_util
+ absl::random_internal_sequence_urbg
+@@ -446,6 +449,7 @@ absl_cc_test(NAME random_uniform_real_distribution_test
+ LINKOPTS
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
++ absl::numeric_representation
+ absl::random_distributions
+ absl::random_internal_distribution_test_util
+ absl::random_internal_pcg_engine
+--- a/absl/random/beta_distribution_test.cc
++++ b/absl/random/beta_distribution_test.cc
+@@ -21,12 +21,14 @@
+ #include <random>
+ #include <sstream>
+ #include <string>
++#include <type_traits>
+ #include <unordered_map>
+ #include <vector>
+
+ #include "gmock/gmock.h"
+ #include "gtest/gtest.h"
+ #include "absl/base/internal/raw_logging.h"
++#include "absl/numeric/internal/representation.h"
+ #include "absl/random/internal/chi_square.h"
+ #include "absl/random/internal/distribution_test_util.h"
+ #include "absl/random/internal/pcg_engine.h"
+@@ -42,7 +44,15 @@
+ template <typename IntType>
+ class BetaDistributionInterfaceTest : public ::testing::Test {};
+
+-using RealTypes = ::testing::Types<float, double, long double>;
++// double-double arithmetic is not supported well by either GCC or Clang; see
++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
++// https://bugs.llvm.org/show_bug.cgi?id=49131, and
++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
++// with double doubles until compiler support is better.
++using RealTypes =
++ std::conditional<absl::numeric_internal::IsDoubleDouble(),
++ ::testing::Types<float, double>,
++ ::testing::Types<float, double, long double>>::type;
+ TYPED_TEST_CASE(BetaDistributionInterfaceTest, RealTypes);
+
+ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest) {
+@@ -53,9 +63,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest {
+ const TypeParam kLargeA =
+ std::exp(std::log((std::numeric_limits<TypeParam>::max)()) -
+ std::log(std::log((std::numeric_limits<TypeParam>::max)())));
+- const TypeParam kLargeAPPC = std::exp(
+- std::log((std::numeric_limits<TypeParam>::max)()) -
+- std::log(std::log((std::numeric_limits<TypeParam>::max)())) - 10.0f);
+ using param_type = typename absl::beta_distribution<TypeParam>::param_type;
+
+ constexpr int kCount = 1000;
+@@ -76,9 +83,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest {
+ kLargeA, //
+ std::nextafter(kLargeA, TypeParam(0)), //
+ std::nextafter(kLargeA, std::numeric_limits<TypeParam>::max()),
+- kLargeAPPC, //
+- std::nextafter(kLargeAPPC, TypeParam(0)),
+- std::nextafter(kLargeAPPC, std::numeric_limits<TypeParam>::max()),
+ // Boundary cases.
+ std::numeric_limits<TypeParam>::max(),
+ std::numeric_limits<TypeParam>::epsilon(),
+@@ -125,28 +129,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest {
+
+ ss >> after;
+
+-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
+- defined(__ppc__) || defined(__PPC__)
+- if (std::is_same<TypeParam, long double>::value) {
+- // Roundtripping floating point values requires sufficient precision
+- // to reconstruct the exact value. It turns out that long double
+- // has some errors doing this on ppc.
+- if (alpha <= std::numeric_limits<double>::max() &&
+- alpha >= std::numeric_limits<double>::lowest()) {
+- EXPECT_EQ(static_cast<double>(before.alpha()),
+- static_cast<double>(after.alpha()))
+- << ss.str();
+- }
+- if (beta <= std::numeric_limits<double>::max() &&
+- beta >= std::numeric_limits<double>::lowest()) {
+- EXPECT_EQ(static_cast<double>(before.beta()),
+- static_cast<double>(after.beta()))
+- << ss.str();
+- }
+- continue;
+- }
+-#endif
+-
+ EXPECT_EQ(before.alpha(), after.alpha());
+ EXPECT_EQ(before.beta(), after.beta());
+ EXPECT_EQ(before, after) //
+--- a/absl/random/exponential_distribution_test.cc
++++ b/absl/random/exponential_distribution_test.cc
+@@ -30,6 +30,7 @@
+ #include "gtest/gtest.h"
+ #include "absl/base/internal/raw_logging.h"
+ #include "absl/base/macros.h"
++#include "absl/numeric/internal/representation.h"
+ #include "absl/random/internal/chi_square.h"
+ #include "absl/random/internal/distribution_test_util.h"
+ #include "absl/random/internal/pcg_engine.h"
+@@ -50,7 +51,15 @@
+ #if defined(__EMSCRIPTEN__)
+ using RealTypes = ::testing::Types<float, double>;
+ #else
+-using RealTypes = ::testing::Types<float, double, long double>;
++// double-double arithmetic is not supported well by either GCC or Clang; see
++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
++// https://bugs.llvm.org/show_bug.cgi?id=49131, and
++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
++// with double doubles until compiler support is better.
++using RealTypes =
++ std::conditional<absl::numeric_internal::IsDoubleDouble(),
++ ::testing::Types<float, double>,
++ ::testing::Types<float, double, long double>>::type;
+ #endif // defined(__EMSCRIPTEN__)
+ TYPED_TEST_CASE(ExponentialDistributionTypedTest, RealTypes);
+
+@@ -130,23 +139,6 @@ TYPED_TEST(ExponentialDistributionTypedTest, SerializeTest) {
+
+ ss >> after;
+
+-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
+- defined(__ppc__) || defined(__PPC__)
+- if (std::is_same<TypeParam, long double>::value) {
+- // Roundtripping floating point values requires sufficient precision to
+- // reconstruct the exact value. It turns out that long double has some
+- // errors doing this on ppc, particularly for values
+- // near {1.0 +/- epsilon}.
+- if (lambda <= std::numeric_limits<double>::max() &&
+- lambda >= std::numeric_limits<double>::lowest()) {
+- EXPECT_EQ(static_cast<double>(before.lambda()),
+- static_cast<double>(after.lambda()))
+- << ss.str();
+- }
+- continue;
+- }
+-#endif
+-
+ EXPECT_EQ(before.lambda(), after.lambda()) //
+ << ss.str() << " " //
+ << (ss.good() ? "good " : "") //
+--- a/absl/random/gaussian_distribution_test.cc
++++ b/absl/random/gaussian_distribution_test.cc
+@@ -21,12 +21,14 @@
+ #include <iterator>
+ #include <random>
+ #include <string>
++#include <type_traits>
+ #include <vector>
+
+ #include "gmock/gmock.h"
+ #include "gtest/gtest.h"
+ #include "absl/base/internal/raw_logging.h"
+ #include "absl/base/macros.h"
++#include "absl/numeric/internal/representation.h"
+ #include "absl/random/internal/chi_square.h"
+ #include "absl/random/internal/distribution_test_util.h"
+ #include "absl/random/internal/sequence_urbg.h"
+@@ -43,7 +45,15 @@
+ template <typename RealType>
+ class GaussianDistributionInterfaceTest : public ::testing::Test {};
+
+-using RealTypes = ::testing::Types<float, double, long double>;
++// double-double arithmetic is not supported well by either GCC or Clang; see
++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
++// https://bugs.llvm.org/show_bug.cgi?id=49131, and
++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
++// with double doubles until compiler support is better.
++using RealTypes =
++ std::conditional<absl::numeric_internal::IsDoubleDouble(),
++ ::testing::Types<float, double>,
++ ::testing::Types<float, double, long double>>::type;
+ TYPED_TEST_CASE(GaussianDistributionInterfaceTest, RealTypes);
+
+ TYPED_TEST(GaussianDistributionInterfaceTest, SerializeTest) {
+@@ -129,32 +139,6 @@ TYPED_TEST(GaussianDistributionInterfaceTest, SerializeTest) {
+
+ ss >> after;
+
+-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
+- defined(__ppc__) || defined(__PPC__) || defined(__EMSCRIPTEN__)
+- if (std::is_same<TypeParam, long double>::value) {
+- // Roundtripping floating point values requires sufficient precision
+- // to reconstruct the exact value. It turns out that long double
+- // has some errors doing this on ppc, particularly for values
+- // near {1.0 +/- epsilon}.
+- //
+- // Emscripten is even worse, implementing long double as a 128-bit
+- // type, but shipping with a strtold() that doesn't support that.
+- if (mean <= std::numeric_limits<double>::max() &&
+- mean >= std::numeric_limits<double>::lowest()) {
+- EXPECT_EQ(static_cast<double>(before.mean()),
+- static_cast<double>(after.mean()))
+- << ss.str();
+- }
+- if (stddev <= std::numeric_limits<double>::max() &&
+- stddev >= std::numeric_limits<double>::lowest()) {
+- EXPECT_EQ(static_cast<double>(before.stddev()),
+- static_cast<double>(after.stddev()))
+- << ss.str();
+- }
+- continue;
+- }
+-#endif
+-
+ EXPECT_EQ(before.mean(), after.mean());
+ EXPECT_EQ(before.stddev(), after.stddev()) //
+ << ss.str() << " " //
+--- a/absl/random/uniform_real_distribution_test.cc
++++ b/absl/random/uniform_real_distribution_test.cc
+@@ -20,11 +20,13 @@
+ #include <random>
+ #include <sstream>
+ #include <string>
++#include <type_traits>
+ #include <vector>
+
+ #include "gmock/gmock.h"
+ #include "gtest/gtest.h"
+ #include "absl/base/internal/raw_logging.h"
++#include "absl/numeric/internal/representation.h"
+ #include "absl/random/internal/chi_square.h"
+ #include "absl/random/internal/distribution_test_util.h"
+ #include "absl/random/internal/pcg_engine.h"
+@@ -58,7 +60,15 @@
+ #if defined(__EMSCRIPTEN__)
+ using RealTypes = ::testing::Types<float, double>;
+ #else
+-using RealTypes = ::testing::Types<float, double, long double>;
++// double-double arithmetic is not supported well by either GCC or Clang; see
++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
++// https://bugs.llvm.org/show_bug.cgi?id=49131, and
++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
++// with double doubles until compiler support is better.
++using RealTypes =
++ std::conditional<absl::numeric_internal::IsDoubleDouble(),
++ ::testing::Types<float, double>,
++ ::testing::Types<float, double, long double>>::type;
+ #endif // defined(__EMSCRIPTEN__)
+
+ TYPED_TEST_SUITE(UniformRealDistributionTest, RealTypes);
+--- a/absl/strings/BUILD.bazel
++++ b/absl/strings/BUILD.bazel
+@@ -645,6 +645,7 @@ cc_library(name = "str_format_internal",
+ "//absl/functional:function_ref",
+ "//absl/meta:type_traits",
+ "//absl/numeric:int128",
++ "//absl/numeric:representation",
+ "//absl/types:optional",
+ "//absl/types:span",
+ ],
+--- a/absl/strings/CMakeLists.txt
++++ b/absl/strings/CMakeLists.txt
+@@ -396,6 +396,7 @@ absl_cc_library(NAME str_format_internal
+ absl::strings
+ absl::config
+ absl::core_headers
++ absl::numeric_representation
+ absl::type_traits
+ absl::int128
+ absl::span
+--- a/absl/strings/internal/str_format/float_conversion.cc
++++ b/absl/strings/internal/str_format/float_conversion.cc
+@@ -15,6 +15,7 @@
+ #include "absl/functional/function_ref.h"
+ #include "absl/meta/type_traits.h"
+ #include "absl/numeric/int128.h"
++#include "absl/numeric/internal/representation.h"
+ #include "absl/strings/numbers.h"
+ #include "absl/types/optional.h"
+ #include "absl/types/span.h"
+@@ -25,6 +26,8 @@
+
+ namespace {
+
++using ::absl::numeric_internal::IsDoubleDouble;
++
+ // The code below wants to avoid heap allocations.
+ // To do so it needs to allocate memory on the stack.
+ // `StackArray` will allocate memory on the stack in the form of a uint32_t
+@@ -98,13 +101,6 @@
+ return next_carry % divisor;
+ }
+
+-constexpr bool IsDoubleDouble() {
+- // This is the `double-double` representation of `long double`.
+- // We do not handle it natively. Fallback to snprintf.
+- return std::numeric_limits<long double>::digits ==
+- 2 * std::numeric_limits<double>::digits;
+-}
+-
+ using MaxFloatType =
+ typename std::conditional<IsDoubleDouble(), double, long double>::type;
+
+@@ -1391,6 +1387,8 @@
+ bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv,
+ FormatSinkImpl *sink) {
+ if (IsDoubleDouble()) {
++ // This is the `double-double` representation of `long double`. We do not
++ // handle it natively. Fallback to snprintf.
+ return FallbackToSnprintf(v, conv, sink);
+ }
+
diff --git a/debian/patches/endian-hash.diff b/debian/patches/endian-hash.diff
new file mode 100644
index 00000000..01c1b6b0
--- /dev/null
+++ b/debian/patches/endian-hash.diff
@@ -0,0 +1,111 @@
+From: Benjamin Barenblat <bbaren@google.com>
+Subject: Remove endian-sensitivity from hash slow path
+Forwarded: yes
+Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/9c6a50fdd80bb39fabd95faeda84f04062685ff3
+
+Prior to this commit, the Abseil hash fast path was endian-agnostic, but
+the slow path assumed a little-endian platform. Change the slow path to
+be endian-correct, ensuring that values produced by the fast and slow
+paths are equal even on big-endian systems.
+
+The author works at Google. Upstream applied this patch as Piper revision
+355424258 and exported it to GitHub; the Applied-Upstream URL above points to
+the exported commit.
+
+--- a/absl/hash/BUILD.bazel
++++ b/absl/hash/BUILD.bazel
+@@ -37,6 +37,7 @@ cc_library(name = "hash",
+ linkopts = ABSL_DEFAULT_LINKOPTS,
+ deps = [
+ ":city",
++ "//absl/base:config",
+ "//absl/base:core_headers",
+ "//absl/base:endian",
+ "//absl/container:fixed_array",
+--- a/absl/hash/CMakeLists.txt
++++ b/absl/hash/CMakeLists.txt
+@@ -25,6 +25,7 @@ absl_cc_library(NAME hash
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
+ DEPS
++ absl::config
+ absl::core_headers
+ absl::endian
+ absl::fixed_array
+--- a/absl/hash/internal/hash.h
++++ b/absl/hash/internal/hash.h
+@@ -38,7 +38,8 @@
+ #include <utility>
+ #include <vector>
+
+-#include "absl/base/internal/endian.h"
++#include "absl/base/config.h"
++#include "absl/base/internal/unaligned_access.h"
+ #include "absl/base/port.h"
+ #include "absl/container/fixed_array.h"
+ #include "absl/meta/type_traits.h"
+@@ -804,26 +805,54 @@ class ABSL_DLL CityHashState
+ size_t len);
+
+ // Reads 9 to 16 bytes from p.
+- // The first 8 bytes are in .first, the rest (zero padded) bytes are in
+- // .second.
++ // The least significant 8 bytes are in .first, the rest (zero padded) bytes
++ // are in .second.
+ static std::pair<uint64_t, uint64_t> Read9To16(const unsigned char* p,
+ size_t len) {
+- uint64_t high = little_endian::Load64(p + len - 8);
+- return {little_endian::Load64(p), high >> (128 - len * 8)};
++ uint64_t low_mem = absl::base_internal::UnalignedLoad64(p);
++ uint64_t high_mem = absl::base_internal::UnalignedLoad64(p + len - 8);
++#ifdef ABSL_IS_LITTLE_ENDIAN
++ uint64_t most_significant = high_mem;
++ uint64_t least_significant = low_mem;
++#else
++ uint64_t most_significant = low_mem;
++ uint64_t least_significant = high_mem;
++#endif
++ return {least_significant, most_significant >> (128 - len * 8)};
+ }
+
+ // Reads 4 to 8 bytes from p. Zero pads to fill uint64_t.
+ static uint64_t Read4To8(const unsigned char* p, size_t len) {
+- return (static_cast<uint64_t>(little_endian::Load32(p + len - 4))
+- << (len - 4) * 8) |
+- little_endian::Load32(p);
++ uint32_t low_mem = absl::base_internal::UnalignedLoad32(p);
++ uint32_t high_mem = absl::base_internal::UnalignedLoad32(p + len - 4);
++#ifdef ABSL_IS_LITTLE_ENDIAN
++ uint32_t most_significant = high_mem;
++ uint32_t least_significant = low_mem;
++#else
++ uint32_t most_significant = low_mem;
++ uint32_t least_significant = high_mem;
++#endif
++ return (static_cast<uint64_t>(most_significant) << (len - 4) * 8) |
++ least_significant;
+ }
+
+ // Reads 1 to 3 bytes from p. Zero pads to fill uint32_t.
+ static uint32_t Read1To3(const unsigned char* p, size_t len) {
+- return static_cast<uint32_t>((p[0]) | //
+- (p[len / 2] << (len / 2 * 8)) | //
+- (p[len - 1] << ((len - 1) * 8)));
++ unsigned char mem0 = p[0];
++ unsigned char mem1 = p[len / 2];
++ unsigned char mem2 = p[len - 1];
++#ifdef ABSL_IS_LITTLE_ENDIAN
++ unsigned char significant2 = mem2;
++ unsigned char significant1 = mem1;
++ unsigned char significant0 = mem0;
++#else
++ unsigned char significant2 = mem0;
++ unsigned char significant1 = mem1;
++ unsigned char significant0 = mem2;
++#endif
++ return static_cast<uint32_t>(significant0 | //
++ (significant1 << (len / 2 * 8)) | //
++ (significant2 << ((len - 1) * 8)));
+ }
+
+ ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t state, uint64_t v) {
diff --git a/debian/patches/endian-random.diff b/debian/patches/endian-random.diff
new file mode 100644
index 00000000..9fe2b166
--- /dev/null
+++ b/debian/patches/endian-random.diff
@@ -0,0 +1,249 @@
+From: Benjamin Barenblat <bbaren@google.com>
+Subject: Remove endian-sensitivity from Abseil's RNG
+Forwarded: yes
+Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/c36d825d9a5443f81d2656685ae021d6326da90c
+
+Ensure that the Abseil random number generator produces identical output
+on both big- and little-endian platforms by byte-swapping appropriately
+on big-endian systems.
+
+The author works at Google. Upstream applied this patch as Piper
+revision 355635051 and exported it to GitHub; the Applied-Upstream URL
+above points to the exported commit.
+
+--- a/absl/base/BUILD.bazel
++++ b/absl/base/BUILD.bazel
+@@ -479,6 +479,7 @@
+ copts = ABSL_DEFAULT_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
+ deps = [
++ ":base",
+ ":config",
+ ":core_headers",
+ ],
+--- a/absl/base/CMakeLists.txt
++++ b/absl/base/CMakeLists.txt
+@@ -418,6 +418,7 @@
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
+ DEPS
++ absl::base
+ absl::config
+ absl::core_headers
+ PUBLIC
+--- a/absl/base/internal/endian.h
++++ b/absl/base/internal/endian.h
+@@ -26,6 +26,7 @@
+ #endif
+
+ #include <cstdint>
++#include "absl/base/casts.h"
+ #include "absl/base/config.h"
+ #include "absl/base/internal/unaligned_access.h"
+ #include "absl/base/port.h"
+@@ -173,6 +174,36 @@
+
+ #endif /* ENDIAN */
+
++inline uint8_t FromHost(uint8_t x) { return x; }
++inline uint16_t FromHost(uint16_t x) { return FromHost16(x); }
++inline uint32_t FromHost(uint32_t x) { return FromHost32(x); }
++inline uint64_t FromHost(uint64_t x) { return FromHost64(x); }
++inline uint8_t ToHost(uint8_t x) { return x; }
++inline uint16_t ToHost(uint16_t x) { return ToHost16(x); }
++inline uint32_t ToHost(uint32_t x) { return ToHost32(x); }
++inline uint64_t ToHost(uint64_t x) { return ToHost64(x); }
++
++inline int8_t FromHost(int8_t x) { return x; }
++inline int16_t FromHost(int16_t x) {
++ return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x)));
++}
++inline int32_t FromHost(int32_t x) {
++ return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x)));
++}
++inline int64_t FromHost(int64_t x) {
++ return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x)));
++}
++inline int8_t ToHost(int8_t x) { return x; }
++inline int16_t ToHost(int16_t x) {
++ return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x)));
++}
++inline int32_t ToHost(int32_t x) {
++ return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x)));
++}
++inline int64_t ToHost(int64_t x) {
++ return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x)));
++}
++
+ // Functions to do unaligned loads and stores in little-endian order.
+ inline uint16_t Load16(const void *p) {
+ return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));
+@@ -233,6 +264,36 @@
+
+ #endif /* ENDIAN */
+
++inline uint8_t FromHost(uint8_t x) { return x; }
++inline uint16_t FromHost(uint16_t x) { return FromHost16(x); }
++inline uint32_t FromHost(uint32_t x) { return FromHost32(x); }
++inline uint64_t FromHost(uint64_t x) { return FromHost64(x); }
++inline uint8_t ToHost(uint8_t x) { return x; }
++inline uint16_t ToHost(uint16_t x) { return ToHost16(x); }
++inline uint32_t ToHost(uint32_t x) { return ToHost32(x); }
++inline uint64_t ToHost(uint64_t x) { return ToHost64(x); }
++
++inline int8_t FromHost(int8_t x) { return x; }
++inline int16_t FromHost(int16_t x) {
++ return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x)));
++}
++inline int32_t FromHost(int32_t x) {
++ return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x)));
++}
++inline int64_t FromHost(int64_t x) {
++ return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x)));
++}
++inline int8_t ToHost(int8_t x) { return x; }
++inline int16_t ToHost(int16_t x) {
++ return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x)));
++}
++inline int32_t ToHost(int32_t x) {
++ return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x)));
++}
++inline int64_t ToHost(int64_t x) {
++ return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x)));
++}
++
+ // Functions to do unaligned loads and stores in big-endian order.
+ inline uint16_t Load16(const void *p) {
+ return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));
+--- a/absl/random/CMakeLists.txt
++++ b/absl/random/CMakeLists.txt
+@@ -611,6 +611,7 @@
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
+ absl::config
++ absl::endian
+ TESTONLY
+ )
+
+@@ -758,6 +759,7 @@
+ LINKOPTS
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
++ absl::endian
+ absl::random_internal_iostream_state_saver
+ absl::random_internal_randen
+ absl::raw_logging_internal
+@@ -1119,6 +1121,7 @@
+ LINKOPTS
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
++ absl::endian
+ absl::random_internal_randen_slow
+ gtest_main
+ )
+--- a/absl/random/internal/BUILD.bazel
++++ b/absl/random/internal/BUILD.bazel
+@@ -124,7 +124,10 @@
+ ],
+ copts = ABSL_DEFAULT_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
+- deps = ["//absl/base:config"],
++ deps = [
++ "//absl/base:config",
++ "//absl/base:endian",
++ ],
+ )
+
+ cc_library(
+@@ -241,6 +244,7 @@
+ deps = [
+ ":iostream_state_saver",
+ ":randen",
++ "//absl/base:endian",
+ "//absl/meta:type_traits",
+ ],
+ )
+@@ -606,6 +610,7 @@
+ ":platform",
+ ":randen_slow",
+ "@com_google_googletest//:gtest_main",
++ "//absl/base:endian",
+ ],
+ )
+
+--- a/absl/random/internal/explicit_seed_seq.h
++++ b/absl/random/internal/explicit_seed_seq.h
+@@ -23,6 +23,7 @@
+ #include <vector>
+
+ #include "absl/base/config.h"
++#include "absl/base/internal/endian.h"
+
+ namespace absl {
+ ABSL_NAMESPACE_BEGIN
+@@ -73,7 +74,7 @@
+ template <typename OutIterator>
+ void generate(OutIterator begin, OutIterator end) {
+ for (size_t index = 0; begin != end; begin++) {
+- *begin = state_.empty() ? 0 : state_[index++];
++ *begin = state_.empty() ? 0 : little_endian::FromHost32(state_[index++]);
+ if (index >= state_.size()) {
+ index = 0;
+ }
+--- a/absl/random/internal/randen_engine.h
++++ b/absl/random/internal/randen_engine.h
+@@ -23,6 +23,7 @@
+ #include <limits>
+ #include <type_traits>
+
++#include "absl/base/internal/endian.h"
+ #include "absl/meta/type_traits.h"
+ #include "absl/random/internal/iostream_state_saver.h"
+ #include "absl/random/internal/randen.h"
+@@ -76,7 +77,7 @@
+ impl_.Generate(state_);
+ }
+
+- return state_[next_++];
++ return little_endian::ToHost(state_[next_++]);
+ }
+
+ template <class SeedSequence>
+@@ -181,7 +182,8 @@
+ // In the case that `elem` is `uint8_t`, it must be cast to something
+ // larger so that it prints as an integer rather than a character. For
+ // simplicity, apply the cast all circumstances.
+- os << static_cast<numeric_type>(elem) << os.fill();
++ os << static_cast<numeric_type>(little_endian::FromHost(elem))
++ << os.fill();
+ }
+ os << engine.next_;
+ return os;
+@@ -200,7 +202,7 @@
+ // necessary to read a wider type and then cast it to uint8_t.
+ numeric_type value;
+ is >> value;
+- elem = static_cast<result_type>(value);
++ elem = little_endian::ToHost(static_cast<result_type>(value));
+ }
+ is >> next;
+ if (is.fail()) {
+--- a/absl/random/internal/randen_slow_test.cc
++++ b/absl/random/internal/randen_slow_test.cc
+@@ -17,6 +17,7 @@
+ #include <cstring>
+
+ #include "gtest/gtest.h"
++#include "absl/base/internal/endian.h"
+ #include "absl/random/internal/randen_traits.h"
+
+ namespace {
+@@ -56,7 +57,7 @@
+
+ uint64_t* id = d.state;
+ for (const auto& elem : kGolden) {
+- EXPECT_EQ(elem, *id++);
++ EXPECT_EQ(absl::little_endian::FromHost64(elem), *id++);
+ }
+ }
+
diff --git a/debian/patches/fix-hppa.diff b/debian/patches/fix-hppa.diff
new file mode 100644
index 00000000..915efff4
--- /dev/null
+++ b/debian/patches/fix-hppa.diff
@@ -0,0 +1,26 @@
+From: John David Anglin <dave.anglin@bell.net>
+Subject: Fix build on hppa
+Bug-Debian: https://bugs.debian.org/971768
+Reviewed-by: Benjamin Barenblat <bbaren@debian.org>
+
+--- a/absl/base/internal/direct_mmap.h
++++ b/absl/base/internal/direct_mmap.h
+@@ -74,6 +74,7 @@
+ inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd,
+ off64_t offset) noexcept {
+ #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \
++ (defined(__hppa__) && !defined(__LP64__)) || \
+ (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
+ (defined(__PPC__) && !defined(__PPC64__)) || \
+ (defined(__riscv) && __riscv_xlen == 32) || \
+--- a/absl/debugging/internal/examine_stack.cc
++++ b/absl/debugging/internal/examine_stack.cc
+@@ -48,6 +48,8 @@
+ return reinterpret_cast<void*>(context->uc_mcontext.pc);
+ #elif defined(__arm__)
+ return reinterpret_cast<void*>(context->uc_mcontext.arm_pc);
++#elif defined(__hppa__)
++ return reinterpret_cast<void*>(context->uc_mcontext.sc_iaoq[0]);
+ #elif defined(__i386__)
+ if (14 < ABSL_ARRAYSIZE(context->uc_mcontext.gregs))
+ return reinterpret_cast<void*>(context->uc_mcontext.gregs[14]);
diff --git a/debian/patches/fma-contraction.diff b/debian/patches/fma-contraction.diff
new file mode 100644
index 00000000..95181a36
--- /dev/null
+++ b/debian/patches/fma-contraction.diff
@@ -0,0 +1,63 @@
+From: Benjamin Barenblat <bbaren@google.com>
+Subject: Make tests tolerant of FMA contraction
+Forwarded: yes
+Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/b0735979d778a768caee207f01f327535cbd2140
+
+Weaken Duration.ToDoubleSecondsCheckEdgeCases and
+Duration.ToDoubleSecondsCheckRandom to make them less sensitive to fused
+multiply/add contraction.
+
+The author works at Google. Upstream applied this patch as Piper
+revision 360297653 and exported it to GitHub; the the Applied-Upstream URL
+above points to the exported commit.
+
+--- a/absl/time/duration_test.cc
++++ b/absl/time/duration_test.cc
+@@ -1369,10 +1369,13 @@
+ EXPECT_THAT(ToTimeval(absl::Nanoseconds(2000)), TimevalMatcher(tv));
+ }
+
+-void VerifySameAsMul(double time_as_seconds, int* const misses) {
++void VerifyApproxSameAsMul(double time_as_seconds, int* const misses) {
+ auto direct_seconds = absl::Seconds(time_as_seconds);
+ auto mul_by_one_second = time_as_seconds * absl::Seconds(1);
+- if (direct_seconds != mul_by_one_second) {
++ // These are expected to differ by up to one tick due to fused multiply/add
++ // contraction.
++ if (absl::AbsDuration(direct_seconds - mul_by_one_second) >
++ absl::time_internal::MakeDuration(0, 1u)) {
+ if (*misses > 10) return;
+ ASSERT_LE(++(*misses), 10) << "Too many errors, not reporting more.";
+ EXPECT_EQ(direct_seconds, mul_by_one_second)
+@@ -1384,7 +1387,8 @@
+ // For a variety of interesting durations, we find the exact point
+ // where one double converts to that duration, and the very next double
+ // converts to the next duration. For both of those points, verify that
+-// Seconds(point) returns the same duration as point * Seconds(1.0)
++// Seconds(point) returns a duration near point * Seconds(1.0). (They may
++// not be exactly equal due to fused multiply/add contraction.)
+ TEST(Duration, ToDoubleSecondsCheckEdgeCases) {
+ constexpr uint32_t kTicksPerSecond = absl::time_internal::kTicksPerSecond;
+ constexpr auto duration_tick = absl::time_internal::MakeDuration(0, 1u);
+@@ -1423,8 +1427,8 @@
+ }
+ // Now low_edge is the highest double that converts to Duration d,
+ // and high_edge is the lowest double that converts to Duration after_d.
+- VerifySameAsMul(low_edge, &misses);
+- VerifySameAsMul(high_edge, &misses);
++ VerifyApproxSameAsMul(low_edge, &misses);
++ VerifyApproxSameAsMul(high_edge, &misses);
+ }
+ }
+ }
+@@ -1444,8 +1448,8 @@
+ int misses = 0;
+ for (int i = 0; i < 1000000; ++i) {
+ double d = std::exp(uniform(gen));
+- VerifySameAsMul(d, &misses);
+- VerifySameAsMul(-d, &misses);
++ VerifyApproxSameAsMul(d, &misses);
++ VerifyApproxSameAsMul(-d, &misses);
+ }
+ }
+
diff --git a/debian/patches/latomic.diff b/debian/patches/latomic.diff
new file mode 100644
index 00000000..d78c7469
--- /dev/null
+++ b/debian/patches/latomic.diff
@@ -0,0 +1,20 @@
+From: Benjamin Barenblat <bbaren@google.com>
+Subject: Use libatomic if necessary
+Bug-Debian: https://bugs.debian.org/973492
+
+On some architectures, notably armel, Abseil needs symbols defined in
+libatomic. Abseil does not currently have a well-developed system to
+declare external library dependencies, so just have the linker determine
+if anything needs libatomic and add the DT_NEEDED entry where necessary.
+
+--- a/absl/copts/AbseilConfigureCopts.cmake
++++ b/absl/copts/AbseilConfigureCopts.cmake
+@@ -64,4 +64,8 @@
+ set(ABSL_TEST_COPTS "")
+ endif()
+
++list(APPEND ABSL_DEFAULT_LINKOPTS
++ "-Wl,--as-needed" "-latomic" "-Wl,--no-as-needed"
++)
++
+ set(ABSL_CXX_STANDARD "${CMAKE_CXX_STANDARD}")
diff --git a/debian/patches/nan-narrowing.diff b/debian/patches/nan-narrowing.diff
new file mode 100644
index 00000000..c7ec9325
--- /dev/null
+++ b/debian/patches/nan-narrowing.diff
@@ -0,0 +1,25 @@
+From: Benjamin Barenblat <bbaren@google.com>
+Subject: Avoid libgcc -NaN narrowing bug
+Forwarded: yes
+Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/1bae23e32ba1f1af7c7d1488a69a351ec96dc98d
+
+When testing -NaN parsing, avoid narrowing -NaN from double to float. This
+avoids a bug in libgcc (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98251).
+
+The author works at Google. Upstream applied this patch as Piper revision
+347654751 and exported it to GitHub; the Applied-Upstream URL above points to
+the exported commit.
+
+--- a/absl/strings/charconv_test.cc
++++ b/absl/strings/charconv_test.cc
+@@ -653,7 +653,9 @@ TEST(FromChars, NaNFloats) {
+ negative_from_chars_float);
+ EXPECT_TRUE(std::signbit(negative_from_chars_float));
+ EXPECT_FALSE(Identical(negative_from_chars_float, from_chars_float));
+- from_chars_float = std::copysign(from_chars_float, -1.0);
++ // Use the (float, float) overload of std::copysign to prevent narrowing;
++ // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98251.
++ from_chars_float = std::copysign(from_chars_float, -1.0f);
+ EXPECT_TRUE(Identical(negative_from_chars_float, from_chars_float));
+ }
+ }
diff --git a/debian/patches/ppc-float-conversion.diff b/debian/patches/ppc-float-conversion.diff
new file mode 100644
index 00000000..f0ff9595
--- /dev/null
+++ b/debian/patches/ppc-float-conversion.diff
@@ -0,0 +1,268 @@
+From: Samuel Benzaquen <sbenza@google.com>
+Subject: Fix float conversion for PPC.
+Origin: backport, https://github.com/abseil/abseil-cpp/commit/c36d825d9a5443f81d2656685ae021d6326da90c
+
+In PPC `long double` is a double-double representation which behaves weirdly
+wrt numeric_limits. Don't take `long double` into account when we are not
+handling `long double` natively anyway.
+
+Fix the convert test to always run the conversion even if we are not going to
+compare against libc's printf result. This allows exercising the code itself to
+make sure we don't trigger assertions or UB found by sanitizers.
+
+The author works at Google. Upstream applied this patch as Piper revision
+355857729 and exported it to GitHub; the Applied-Upstream URL above points to
+the exported commit.
+
+--- a/absl/strings/internal/str_format/convert_test.cc
++++ b/absl/strings/internal/str_format/convert_test.cc
+@@ -540,7 +540,8 @@
+ }
+
+ template <typename Floating>
+-void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats) {
++void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats,
++ const std::set<Floating> &skip_verify) {
+ const NativePrintfTraits &native_traits = VerifyNativeImplementation();
+ // Reserve the space to ensure we don't allocate memory in the output itself.
+ std::string str_format_result;
+@@ -588,7 +589,16 @@
+ AppendPack(&str_format_result, format, absl::MakeSpan(args));
+ }
+
+- if (string_printf_result != str_format_result) {
++#ifdef _MSC_VER
++ // MSVC has a different rounding policy than us so we can't test our
++ // implementation against the native one there.
++ continue;
++#elif defined(__APPLE__)
++ // Apple formats NaN differently (+nan) vs. (nan)
++ if (std::isnan(d)) continue;
++#endif
++ if (string_printf_result != str_format_result &&
++ skip_verify.find(d) == skip_verify.end()) {
+ // We use ASSERT_EQ here because failures are usually correlated and a
+ // bug would print way too many failed expectations causing the test
+ // to time out.
+@@ -602,12 +612,6 @@
+ }
+
+ TEST_F(FormatConvertTest, Float) {
+-#ifdef _MSC_VER
+- // MSVC has a different rounding policy than us so we can't test our
+- // implementation against the native one there.
+- return;
+-#endif // _MSC_VER
+-
+ std::vector<float> floats = {0.0f,
+ -0.0f,
+ .9999999f,
+@@ -621,7 +625,8 @@
+ std::numeric_limits<float>::epsilon(),
+ std::numeric_limits<float>::epsilon() + 1.0f,
+ std::numeric_limits<float>::infinity(),
+- -std::numeric_limits<float>::infinity()};
++ -std::numeric_limits<float>::infinity(),
++ std::nanf("")};
+
+ // Some regression tests.
+ floats.push_back(0.999999989f);
+@@ -650,21 +655,14 @@
+ std::sort(floats.begin(), floats.end());
+ floats.erase(std::unique(floats.begin(), floats.end()), floats.end());
+
+-#ifndef __APPLE__
+- // Apple formats NaN differently (+nan) vs. (nan)
+- floats.push_back(std::nan(""));
+-#endif
+-
+- TestWithMultipleFormatsHelper(floats);
++ TestWithMultipleFormatsHelper(floats, {});
+ }
+
+ TEST_F(FormatConvertTest, Double) {
+-#ifdef _MSC_VER
+- // MSVC has a different rounding policy than us so we can't test our
+- // implementation against the native one there.
+- return;
+-#endif // _MSC_VER
+-
++ // For values that we know won't match the standard library implementation we
++ // skip verification, but still run the algorithm to catch asserts/sanitizer
++ // bugs.
++ std::set<double> skip_verify;
+ std::vector<double> doubles = {0.0,
+ -0.0,
+ .99999999999999,
+@@ -678,7 +676,8 @@
+ std::numeric_limits<double>::epsilon(),
+ std::numeric_limits<double>::epsilon() + 1,
+ std::numeric_limits<double>::infinity(),
+- -std::numeric_limits<double>::infinity()};
++ -std::numeric_limits<double>::infinity(),
++ std::nan("")};
+
+ // Some regression tests.
+ doubles.push_back(0.99999999999999989);
+@@ -708,33 +707,29 @@
+ "5084551339423045832369032229481658085593321233482747978262041447231"
+ "68738177180919299881250404026184124858368.000000";
+
+- if (!gcc_bug_22142) {
+- for (int exp = -300; exp <= 300; ++exp) {
+- const double all_ones_mantissa = 0x1fffffffffffff;
+- doubles.push_back(std::ldexp(all_ones_mantissa, exp));
++ for (int exp = -300; exp <= 300; ++exp) {
++ const double all_ones_mantissa = 0x1fffffffffffff;
++ doubles.push_back(std::ldexp(all_ones_mantissa, exp));
++ if (gcc_bug_22142) {
++ skip_verify.insert(doubles.back());
+ }
+ }
+
+ if (gcc_bug_22142) {
+- for (auto &d : doubles) {
+- using L = std::numeric_limits<double>;
+- double d2 = std::abs(d);
+- if (d2 == L::max() || d2 == L::min() || d2 == L::denorm_min()) {
+- d = 0;
+- }
+- }
++ using L = std::numeric_limits<double>;
++ skip_verify.insert(L::max());
++ skip_verify.insert(L::min()); // NOLINT
++ skip_verify.insert(L::denorm_min());
++ skip_verify.insert(-L::max());
++ skip_verify.insert(-L::min()); // NOLINT
++ skip_verify.insert(-L::denorm_min());
+ }
+
+ // Remove duplicates to speed up the logic below.
+ std::sort(doubles.begin(), doubles.end());
+ doubles.erase(std::unique(doubles.begin(), doubles.end()), doubles.end());
+
+-#ifndef __APPLE__
+- // Apple formats NaN differently (+nan) vs. (nan)
+- doubles.push_back(std::nan(""));
+-#endif
+-
+- TestWithMultipleFormatsHelper(doubles);
++ TestWithMultipleFormatsHelper(doubles, skip_verify);
+ }
+
+ TEST_F(FormatConvertTest, DoubleRound) {
+@@ -1055,11 +1050,6 @@
+ }
+
+ TEST_F(FormatConvertTest, LongDouble) {
+-#ifdef _MSC_VER
+- // MSVC has a different rounding policy than us so we can't test our
+- // implementation against the native one there.
+- return;
+-#endif // _MSC_VER
+ const NativePrintfTraits &native_traits = VerifyNativeImplementation();
+ const char *const kFormats[] = {"%", "%.3", "%8.5", "%9", "%.5000",
+ "%.60", "%+", "% ", "%-10"};
+@@ -1120,10 +1110,18 @@
+ for (auto d : doubles) {
+ FormatArgImpl arg(d);
+ UntypedFormatSpecImpl format(fmt_str);
++ std::string result = FormatPack(format, {&arg, 1});
++
++#ifdef _MSC_VER
++ // MSVC has a different rounding policy than us so we can't test our
++ // implementation against the native one there.
++ continue;
++#endif // _MSC_VER
++
+ // We use ASSERT_EQ here because failures are usually correlated and a
+ // bug would print way too many failed expectations causing the test to
+ // time out.
+- ASSERT_EQ(StrPrint(fmt_str.c_str(), d), FormatPack(format, {&arg, 1}))
++ ASSERT_EQ(StrPrint(fmt_str.c_str(), d), result)
+ << fmt_str << " " << StrPrint("%.18Lg", d) << " "
+ << StrPrint("%La", d) << " " << StrPrint("%.1080Lf", d);
+ }
+--- a/absl/strings/internal/str_format/float_conversion.cc
++++ b/absl/strings/internal/str_format/float_conversion.cc
+@@ -98,12 +98,22 @@
+ return next_carry % divisor;
+ }
+
++constexpr bool IsDoubleDouble() {
++ // This is the `double-double` representation of `long double`.
++ // We do not handle it natively. Fallback to snprintf.
++ return std::numeric_limits<long double>::digits ==
++ 2 * std::numeric_limits<double>::digits;
++}
++
++using MaxFloatType =
++ typename std::conditional<IsDoubleDouble(), double, long double>::type;
++
+ // Generates the decimal representation for an integer of the form `v * 2^exp`,
+ // where `v` and `exp` are both positive integers.
+ // It generates the digits from the left (ie the most significant digit first)
+ // to allow for direct printing into the sink.
+ //
+-// Requires `0 <= exp` and `exp <= numeric_limits<long double>::max_exponent`.
++// Requires `0 <= exp` and `exp <= numeric_limits<MaxFloatType>::max_exponent`.
+ class BinaryToDecimal {
+ static constexpr int ChunksNeeded(int exp) {
+ // We will left shift a uint128 by `exp` bits, so we need `128+exp` total
+@@ -118,10 +128,10 @@
+ static void RunConversion(uint128 v, int exp,
+ absl::FunctionRef<void(BinaryToDecimal)> f) {
+ assert(exp > 0);
+- assert(exp <= std::numeric_limits<long double>::max_exponent);
++ assert(exp <= std::numeric_limits<MaxFloatType>::max_exponent);
+ static_assert(
+ StackArray::kMaxCapacity >=
+- ChunksNeeded(std::numeric_limits<long double>::max_exponent),
++ ChunksNeeded(std::numeric_limits<MaxFloatType>::max_exponent),
+ "");
+
+ StackArray::RunWithCapacity(
+@@ -218,14 +228,14 @@
+
+ // Converts a value of the form `x * 2^-exp` into a sequence of decimal digits.
+ // Requires `-exp < 0` and
+-// `-exp >= limits<long double>::min_exponent - limits<long double>::digits`.
++// `-exp >= limits<MaxFloatType>::min_exponent - limits<MaxFloatType>::digits`.
+ class FractionalDigitGenerator {
+ public:
+ // Run the conversion for `v * 2^exp` and call `f(generator)`.
+ // This function will allocate enough stack space to perform the conversion.
+ static void RunConversion(
+ uint128 v, int exp, absl::FunctionRef<void(FractionalDigitGenerator)> f) {
+- using Limits = std::numeric_limits<long double>;
++ using Limits = std::numeric_limits<MaxFloatType>;
+ assert(-exp < 0);
+ assert(-exp >= Limits::min_exponent - 128);
+ static_assert(StackArray::kMaxCapacity >=
+@@ -858,10 +868,10 @@
+ // This buffer holds the "0x1.ab1de3" portion of "0x1.ab1de3pe+2". Compute the
+ // size with long double which is the largest of the floats.
+ constexpr size_t kBufSizeForHexFloatRepr =
+- 2 // 0x
+- + std::numeric_limits<long double>::digits / 4 // number of hex digits
+- + 1 // round up
+- + 1; // "." (dot)
++ 2 // 0x
++ + std::numeric_limits<MaxFloatType>::digits / 4 // number of hex digits
++ + 1 // round up
++ + 1; // "." (dot)
+ char digits_buffer[kBufSizeForHexFloatRepr];
+ char *digits_iter = digits_buffer;
+ const char *const digits =
+@@ -1380,10 +1390,7 @@
+
+ bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv,
+ FormatSinkImpl *sink) {
+- if (std::numeric_limits<long double>::digits ==
+- 2 * std::numeric_limits<double>::digits) {
+- // This is the `double-double` representation of `long double`.
+- // We do not handle it natively. Fallback to snprintf.
++ if (IsDoubleDouble()) {
+ return FallbackToSnprintf(v, conv, sink);
+ }
+
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 00000000..efe60449
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,11 @@
+configure.diff
+fix-hppa.diff
+std-hash.diff
+latomic.diff
+cpu-frequency.diff
+nan-narrowing.diff
+endian-hash.diff
+endian-random.diff
+ppc-float-conversion.diff
+fma-contraction.diff
+disable-double-double-tests.diff
diff --git a/debian/patches/std-hash.diff b/debian/patches/std-hash.diff
new file mode 100644
index 00000000..52096742
--- /dev/null
+++ b/debian/patches/std-hash.diff
@@ -0,0 +1,46 @@
+From: Benjamin Barenblat <bbaren@google.com>
+Subject: Work around broken std::hash on s390x
+Forwarded: no
+Bug-Debian: https://bugs.debian.org/977638
+
+On s390x, std::hash hashes large classes of data to the same value, which
+violates assumptions made by the Abseil tests. #ifdef out the test code that
+depends on those assumptions.
+
+--- a/absl/hash/hash_test.cc
++++ b/absl/hash/hash_test.cc
+@@ -358,6 +358,8 @@
+ TEST(HashValueTest, StdBitset) {
+ EXPECT_TRUE((is_hashable<std::bitset<257>>::value));
+
++ // The following assertions fail on s390x (https://bugs.debian.org/977638).
++#ifndef __s390x__
+ EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(
+ {std::bitset<2>("00"), std::bitset<2>("01"), std::bitset<2>("10"),
+ std::bitset<2>("11")}));
+@@ -379,6 +381,7 @@
+ std::bitset<kNumBits>(bit_strings[3].c_str()),
+ std::bitset<kNumBits>(bit_strings[4].c_str()),
+ std::bitset<kNumBits>(bit_strings[5].c_str())}));
++#endif
+ } // namespace
+
+ template <typename T>
+@@ -400,10 +403,15 @@
+ }
+
+ REGISTER_TYPED_TEST_CASE_P(HashValueSequenceTest, BasicUsage);
++// std::vector<bool> tests fail on s390x, so exclude them. See
++// https://bugs.debian.org/977638.
+ using IntSequenceTypes =
+ testing::Types<std::deque<int>, std::forward_list<int>, std::list<int>,
+- std::vector<int>, std::vector<bool>, std::set<int>,
+- std::multiset<int>>;
++ std::vector<int>,
++#ifndef __s390x__
++ std::vector<bool>,
++#endif
++ std::set<int>, std::multiset<int>>;
+ INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueSequenceTest, IntSequenceTypes);
+
+ // Private type that only supports AbslHashValue to make sure our chosen hash