aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/7z/Makefile24
-rw-r--r--tools/7z/patches/7-zip-flags.patch8
-rw-r--r--tools/7z/patches/7-zip-musl.patch31
-rw-r--r--tools/Makefile31
-rw-r--r--tools/autoconf/Makefile6
-rw-r--r--tools/autoconf/patches/000-relocatable.patch53
-rw-r--r--tools/automake/Makefile7
-rw-r--r--tools/automake/patches/000-relocatable.patch22
-rw-r--r--tools/automake/patches/100-aclocal-skip-not-existing-directories.patch2
-rw-r--r--tools/automake/patches/101-do-not-require-files.patch13
-rw-r--r--tools/automake/patches/200-other-V-values-for-verbosity.patch4
-rw-r--r--tools/automake/patches/300-output-TRUE-cond-first.patch34
-rw-r--r--tools/automake/patches/310-maintainer-clean-built_sources.patch49
-rw-r--r--tools/automake/patches/999-clean-am.patch28
-rw-r--r--tools/b43-tools/Makefile6
-rw-r--r--tools/bash/Makefile4
-rw-r--r--tools/bc/Makefile11
-rw-r--r--tools/bc/patches/000-getopt-prototype.patch18
-rw-r--r--tools/bc/patches/001-no_doc.patch21
-rw-r--r--tools/bc/patches/002-fix-libmath.patch32
-rw-r--r--tools/bison/Makefile4
-rw-r--r--tools/ccache/Makefile7
-rw-r--r--tools/ccache/patches/100-honour-copts.patch6
-rw-r--r--tools/cmake/Makefile4
-rw-r--r--tools/cmake/patches/110-liblzma.patch6
-rw-r--r--tools/cmake/patches/120-curl-fix-libressl-linking.patch7
-rw-r--r--tools/cmake/patches/130-bootstrap_parallel_make_flag.patch2
-rw-r--r--tools/cmake/patches/140-zlib.patch2
-rw-r--r--tools/cmake/patches/150-zstd-libarchive.patch2
-rw-r--r--tools/cmake/patches/160-disable_xcode_generator.patch4
-rw-r--r--tools/coreutils/Makefile34
-rw-r--r--tools/coreutils/patches/000-bootstrap.patch16
-rw-r--r--tools/cpio/patches/cpio-c23.patch23
-rw-r--r--tools/dwarves/Makefile4
-rw-r--r--tools/e2fsprogs/Makefile30
-rw-r--r--tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch11
-rw-r--r--tools/e2fsprogs/patches/002-dont-build-e4defrag.patch11
-rw-r--r--tools/e2fsprogs/patches/003-no-crond.patch11
-rw-r--r--tools/elftosb/patches/001-libm.patch6
-rw-r--r--tools/elftosb/patches/002-fix-header-path.patch5
-rw-r--r--tools/elftosb/patches/010-no-register.patch113
-rw-r--r--tools/elfutils/Makefile83
-rw-r--r--tools/elfutils/patches/001-fix-backport-iquote-include.patch12
-rw-r--r--tools/elfutils/patches/011-backport-mips-support-strip.patch230
-rw-r--r--tools/elfutils/patches/012-backport-mips-support-readelf.patch1079
-rw-r--r--tools/elfutils/patches/013-backport-mips-support-elflint.patch157
-rw-r--r--tools/elfutils/patches/100-portability.patch780
-rw-r--r--tools/elfutils/patches/101-shared-conditional.patch184
-rw-r--r--tools/elfutils/patches/110-objects-manifest.patch162
-rw-r--r--tools/erofs-utils/Makefile40
-rw-r--r--tools/expat/Makefile5
-rw-r--r--tools/fakeroot/Makefile4
-rw-r--r--tools/fakeroot/patches/200-disable-doc.patch2
-rw-r--r--tools/fakeroot/patches/300-time64-hack.patch11
-rw-r--r--tools/fakeroot/patches/400-alpine-libc.musl-fix.patch11
-rw-r--r--tools/fakeroot/patches/600-macOS.patch8
-rw-r--r--tools/findutils/Makefile4
-rw-r--r--tools/findutils/patches/010-endpwent.patch20
-rw-r--r--tools/firmware-utils/Makefile6
-rw-r--r--tools/flex/patches/300-m4-path.patch23
-rw-r--r--tools/gmp/patches/001-acinclude-m4-fix-std23.patch19
-rw-r--r--tools/gmp/patches/002-acinclude-m4-add-parameter-names.patch22
-rw-r--r--tools/gnulib/Makefile14
-rw-r--r--tools/gnulib/patches/000-bootstrap.patch2
-rw-r--r--tools/gnulib/patches/010-autoconf-version.patch47
-rw-r--r--tools/gnulib/patches/020-python-version.patch47
-rw-r--r--tools/gnulib/patches/120-unmangle-darwin-fts-h.patch19
-rw-r--r--tools/gnulib/patches/150-portable-tdestroy.patch16
-rw-r--r--tools/gnulib/patches/160-flag-reallocarray.patch129
-rw-r--r--tools/gnulib/patches/190-stdc-m4-no-cache.patch59
-rw-r--r--tools/gnulib/patches/195-c99-use-std-gnu23.patch10
-rw-r--r--tools/gnulib/patches/200-force-disable-after-configure.patch57
-rw-r--r--tools/gnulib/patches/320-modules-fallocate-posix.patch326
-rw-r--r--tools/gnulib/patches/640-mem-hash-map.patch494
-rw-r--r--tools/gnulib/patches/645-next-prime.patch218
-rw-r--r--tools/gnulib/patches/646-hashcode-string.patch294
-rw-r--r--tools/gnulib/patches/647-hashkey-string.patch215
-rw-r--r--tools/gnulib/patches/650-package-version.patch176
-rw-r--r--tools/gnulib/patches/651-package-version-simplify.patch66
-rw-r--r--tools/gnulib/patches/652-package-version-simplify-further.patch89
-rw-r--r--tools/gnulib/patches/653-package-version-warning.patch32
-rw-r--r--tools/gnulib/patches/660-version-stamp.patch75
-rw-r--r--tools/gnulib/patches/689-vc-mtime.patch366
-rw-r--r--tools/gnulib/patches/755-clean-temp-hashkey.patch64
-rw-r--r--tools/gnulib/patches/795-string-desc-rename-functions.patch1137
-rw-r--r--tools/gnulib/patches/796-vc-mtime-less-read.patch44
-rw-r--r--tools/gnulib/patches/797-vc-mtime-add-api.patch968
-rw-r--r--tools/gnulib/patches/798-vc-mtime-add-api.patch91
-rw-r--r--tools/gnulib/patches/799-vc-mtime-old-git.patch125
-rw-r--r--tools/gnulib/patches/900-str_startswith-module.patch117
-rw-r--r--tools/gnulib/patches/901-str_endswith-module.patch119
-rw-r--r--tools/include/byteswap.h2
-rw-r--r--tools/isl/Makefile4
-rw-r--r--tools/kernel2minor/Makefile29
-rw-r--r--tools/libdeflate/Makefile6
-rw-r--r--tools/libdeflate/patches/0001-lib-x86-increase-AVX-VNNI-gcc-prerequisite-to-12.1.patch32
-rw-r--r--tools/liblzo/patches/001-add-cmake-ENABLE-configurables.patch14
-rw-r--r--tools/libtool/Makefile13
-rw-r--r--tools/libtool/patches/000-relocatable.patch8
-rw-r--r--tools/libtool/patches/001-always-install-aux.patch11
-rw-r--r--tools/libtool/patches/100-libdir-fixes.patch8
-rw-r--r--tools/libtool/patches/110-dont-use-target-dir-for-relinking.patch4
-rw-r--r--tools/libtool/patches/120-strip-unsafe-dirs-for-relinking.patch2
-rw-r--r--tools/libtool/patches/130-trailingslash.patch37
-rw-r--r--tools/libtool/patches/140-don-t-quote-SHELL-in-Makefile.am.patch12
-rw-r--r--tools/libtool/patches/200-openwrt-branding.patch2
-rw-r--r--tools/llvm-bpf/Makefile34
-rw-r--r--tools/lz4/Makefile11
-rw-r--r--tools/lz4/patches/001-add-make-ENABLE_DOCS-configurable.patch60
-rw-r--r--tools/lz4/patches/002-makefile-install-links-from-same-dir.patch71
-rw-r--r--tools/lzma/patches/001-large_files.patch8
-rw-r--r--tools/lzma/patches/002-lzmp.patch36
-rw-r--r--tools/lzma/patches/003-compile_fixes.patch14
-rw-r--r--tools/lzop/patches/001-add-cmake-ENABLE_DOCS-configurable.patch8
-rw-r--r--tools/lzop/patches/002-bump-minimum-cmake-version.patch11
-rw-r--r--tools/m4/Makefile4
-rw-r--r--tools/make-ext4fs/Makefile6
-rw-r--r--tools/meson/Makefile4
-rw-r--r--tools/missing-macros/Makefile4
-rw-r--r--tools/mkimage/Makefile4
-rw-r--r--tools/mkimage/patches/030-allow-to-use-different-magic.patch4
-rw-r--r--tools/mkimage/patches/095-tools-disable-TOOLS_FIT_FULL_CHECK.patch2
-rw-r--r--tools/mold/Makefile6
-rw-r--r--tools/mpfr/Makefile4
-rw-r--r--tools/mpfr/patches/001-only_src.patch2
-rw-r--r--tools/mpfr/patches/100-freebsd-compat.patch2
-rw-r--r--tools/mtd-utils/Makefile12
-rw-r--r--tools/mtd-utils/patches/110-portability.patch26
-rw-r--r--tools/mtd-utils/patches/130-lzma_jffs2.patch105
-rw-r--r--tools/mtools/Makefile4
-rw-r--r--tools/ninja/Makefile25
-rw-r--r--tools/ninja/patches/001-backport-gtest.patch153
-rw-r--r--tools/ninja/patches/010-bootstrap-configure-only.patch24
-rw-r--r--tools/ninja/patches/100-make_jobserver_support.patch233
-rw-r--r--tools/padjffs2/Makefile3
-rw-r--r--tools/patch-image/src/patch-cmdline.c4
-rw-r--r--tools/patch/Makefile6
-rw-r--r--tools/patch/patches/010-CVE-2018-6951.patch24
-rw-r--r--tools/patch/patches/020-CVE-2018-1000156.patch142
-rw-r--r--tools/patch/patches/030-CVE-2018-6952.patch25
-rw-r--r--tools/patch/patches/040-Fix-error-handling-with-git-style-patches.patch53
-rw-r--r--tools/patch/patches/050-CVE-2019-13636.patch108
-rw-r--r--tools/patch/patches/060-CVE-2019-13638.patch38
-rw-r--r--tools/patch/patches/070-don-t-fail-hard-on-EACCES-when-copying-xattrs.patch33
-rw-r--r--tools/pkgconf/Makefile4
-rw-r--r--tools/quilt/Makefile4
-rw-r--r--tools/quilt/patches/001-fix_compile.patch2
-rw-r--r--tools/sparse/Makefile1
-rw-r--r--tools/sparse/patches/010-llvm15.patch128
-rw-r--r--tools/squashfs3-lzma/patches/160-gcc15.patch20
-rw-r--r--tools/squashfs4/Makefile14
-rw-r--r--tools/squashfs4/patches/001-xz_wrapper-support-multiple-lzma-configuration-optio.patch187
-rw-r--r--tools/squashfs4/patches/002-xz_wrapper-make-new-OpenWrt-extended-options-non-def.patch898
-rw-r--r--tools/tar/Makefile4
-rw-r--r--tools/tar/patches/0001-Fix-savannah-bug-64441.patch35
-rw-r--r--tools/tar/patches/100-symlink-force-root-name.patch2
-rw-r--r--tools/tar/patches/110-symlink-force-permissions.patch2
-rw-r--r--tools/util-linux/Makefile130
-rw-r--r--tools/util-linux/patches/010-meson-curses.patch24
-rw-r--r--tools/util-linux/patches/100-fix_include_order.patch12
-rw-r--r--tools/util-linux/patches/102-macos-uuid-next.patch13
-rw-r--r--tools/util-linux/patches/110-meson-fix-a-bug-in-posixipc_libs-configuration.patch23
-rw-r--r--tools/xxhash/Makefile25
-rw-r--r--tools/xz/Makefile7
-rw-r--r--tools/yafut/Makefile20
-rw-r--r--tools/zlib/Makefile9
-rw-r--r--tools/zstd/Makefile4
-rw-r--r--tools/zstd/patches/001-Provide-variant-pkg-config-file-for-multi-threaded-s.patch126
168 files changed, 8785 insertions, 3396 deletions
diff --git a/tools/7z/Makefile b/tools/7z/Makefile
index 2d75d9059e..4fb82eb753 100644
--- a/tools/7z/Makefile
+++ b/tools/7z/Makefile
@@ -1,33 +1,27 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=7z
-PKG_VERSION:=23.01
-PKG_SOURCE_VERSION:=2301
+PKG_VERSION:=25.01
-PKG_SOURCE:=$(PKG_NAME)$(PKG_SOURCE_VERSION)-src.tar.xz
+PKG_SOURCE:=$(PKG_NAME)$(subst .,,$(PKG_VERSION))-src.tar.xz
PKG_SOURCE_URL:=https://7-zip.org/a/
-PKG_HASH:=356071007360e5a1824d9904993e8b2480b51b570e8c9faf7c0f58ebe4bf9f74
-PKG_CPE_ID:=cpe:/a:7-zip:7zip
+PKG_HASH:=ed087f83ee789c1ea5f39c464c55a5c9d4008deb0efe900814f2df262b82c36e
+
+PKG_CPE_ID:=cpe:/a:7-zip:7-zip
# This builds the 7zr variant which supports only 7z, so no non-LGPL code should be included
PKG_LICENSE:=LGPL-2.1-or-later
PKG_LICENSE_FILES:=DOC/License.txt DOC/copying.txt
-HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)
+HOST_MAKE_PATH:=CPP/7zip/Bundles/Alone7z
include $(INCLUDE_DIR)/host-build.mk
-TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS)
-
-ALONE_DIR=$(HOST_BUILD_DIR)/CPP/7zip/Bundles/Alone7z
-
-define Host/Compile
- $(MAKE) -C $(ALONE_DIR) -f makefile.gcc
-endef
+TAR_OPTIONS := -C $(HOST_BUILD_DIR) $(TAR_OPTIONS)
+HOST_MAKE_FLAGS += -f makefile.gcc
define Host/Install
- $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
- $(INSTALL_BIN) $(ALONE_DIR)/_o/7zr $(STAGING_DIR_HOST)/bin/7zr
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/$(HOST_MAKE_PATH)/_o/7zr $(STAGING_DIR_HOST)/bin/
endef
define Host/Clean
diff --git a/tools/7z/patches/7-zip-flags.patch b/tools/7z/patches/7-zip-flags.patch
index b9b2152f22..5c684b0689 100644
--- a/tools/7z/patches/7-zip-flags.patch
+++ b/tools/7z/patches/7-zip-flags.patch
@@ -9,12 +9,12 @@
endif
# for object file
-@@ -32,7 +32,7 @@ endif
- # -save-temps
- CFLAGS_BASE_LIST = -c
+@@ -50,7 +50,7 @@ endif
+ endif
+
# CFLAGS_BASE_LIST = -S
-CFLAGS_BASE = -O2 $(CFLAGS_BASE_LIST) $(CFLAGS_WARN_WALL) $(CFLAGS_WARN) \
+CFLAGS_BASE = $(CFLAGS_BASE_LIST) $(CFLAGS_WARN_WALL) $(CFLAGS_WARN) -D_GNU_SOURCE \
- -DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
+ $(CFLAGS_DEBUG) -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
-fPIC
diff --git a/tools/7z/patches/7-zip-musl.patch b/tools/7z/patches/7-zip-musl.patch
index e066cc8ec9..1a7a5c30c0 100644
--- a/tools/7z/patches/7-zip-musl.patch
+++ b/tools/7z/patches/7-zip-musl.patch
@@ -1,26 +1,15 @@
---- a/C/CpuArch.c
-+++ b/C/CpuArch.c
-@@ -766,8 +766,6 @@ BoolInt CPU_IsSupported_AES (void) { ret
-
- #ifdef USE_HWCAP
-
--#include <asm/hwcap.h>
--
- #define MY_HWCAP_CHECK_FUNC_2(name1, name2) \
- BoolInt CPU_IsSupported_ ## name1() { return (getauxval(AT_HWCAP) & (HWCAP_ ## name2)) ? 1 : 0; }
-
--- a/C/Threads.c
+++ b/C/Threads.c
-@@ -265,7 +265,7 @@ WRes Thread_Create_With_CpuSet(CThread *
+@@ -472,7 +472,7 @@ WRes Thread_Create_With_CpuSet(CThread *
*/
// ret2 =
- pthread_attr_setaffinity_np(&attr, sizeof(*cpuSet), cpuSet);
+ //pthread_attr_setaffinity_np(&attr, sizeof(*cpuSet), cpuSet);
// if (ret2) ret = ret2;
- #endif
+ #endif
}
-@@ -275,14 +275,12 @@ WRes Thread_Create_With_CpuSet(CThread *
+@@ -482,14 +482,12 @@ WRes Thread_Create_With_CpuSet(CThread *
if (!ret)
{
p->_created = 1;
@@ -37,7 +26,7 @@
// ret2 =
--- a/C/Threads.h
+++ b/C/Threads.h
-@@ -20,6 +20,7 @@
+@@ -29,6 +29,7 @@ Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_
#endif
#include <pthread.h>
@@ -45,15 +34,3 @@
#endif
---- a/CPP/Windows/SystemInfo.cpp
-+++ b/CPP/Windows/SystemInfo.cpp
-@@ -36,9 +36,6 @@
- #endif
- */
-
--#ifdef MY_CPU_ARM_OR_ARM64
--#include <asm/hwcap.h>
--#endif
- #endif
-
- #ifdef __linux__
diff --git a/tools/Makefile b/tools/Makefile
index f60a458f98..9188622eb9 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -40,6 +40,7 @@ tools-y += cpio
tools-y += dosfstools
tools-y += e2fsprogs
tools-y += elfutils
+tools-y += erofs-utils
tools-y += expat
tools-y += fakeroot
tools-y += findutils
@@ -82,7 +83,7 @@ tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(CONFIG_TARGET_ath79),y) += lzma-old s
tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(CONFIG_TARGET_mxs),y) += elftosb sdimage
tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(CONFIG_TARGET_realtek),y) += 7z
tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(CONFIG_TARGET_tegra),y) += cbootimage cbootimage-configs
-tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(CONFIG_USES_MINOR),y) += kernel2minor
+tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(CONFIG_USES_MINOR),y) += yafut
tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(CONFIG_USE_SPARSE),y) += sparse
tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(CONFIG_USE_LLVM_BUILD),y) += llvm-bpf
tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(CONFIG_USE_MOLD),y) += mold
@@ -93,11 +94,14 @@ $(curdir)/automake/compile := $(curdir)/autoconf/compile $(curdir)/pkgconf/compi
$(curdir)/b43-tools/compile := $(curdir)/bison/compile
$(curdir)/bc/compile := $(curdir)/bison/compile $(curdir)/libtool/compile
$(curdir)/bison/compile := $(curdir)/flex/compile
+$(curdir)/bzip2/compile := $(curdir)/cmake/compile
$(curdir)/cbootimage/compile += $(curdir)/automake/compile
$(curdir)/cmake/compile += $(curdir)/libressl/compile $(curdir)/ninja/compile $(curdir)/expat/compile $(curdir)/xz/compile $(curdir)/zlib/compile $(curdir)/zstd/compile
+$(curdir)/coreutils/compile := $(curdir)/automake/compile $(curdir)/bison/compile $(curdir)/gnulib/compile
$(curdir)/dosfstools/compile := $(curdir)/automake/compile
-$(curdir)/e2fsprogs/compile := $(curdir)/libtool/compile
-$(curdir)/elfutils/compile := $(curdir)/m4/compile $(curdir)/zlib/compile $(curdir)/gnulib/compile $(curdir)/libtool/compile
+$(curdir)/e2fsprogs/compile := $(curdir)/libtool/compile $(curdir)/util-linux/compile
+$(curdir)/elfutils/compile := $(curdir)/bison/compile $(curdir)/gnulib/compile $(curdir)/m4/compile $(curdir)/zlib/compile
+$(curdir)/erofs-utils/compile := $(curdir)/libtool/compile $(curdir)/xz/compile $(curdir)/lz4/compile $(curdir)/util-linux/compile
$(curdir)/fakeroot/compile := $(curdir)/libtool/compile
$(curdir)/findutils/compile := $(curdir)/bison/compile
$(curdir)/firmware-utils/compile += $(curdir)/cmake/compile
@@ -121,7 +125,7 @@ $(curdir)/mklibs/compile := $(curdir)/libtool/compile
$(curdir)/mold/compile := $(curdir)/cmake/compile $(curdir)/zlib/compile $(curdir)/zstd/compile
$(curdir)/mpc/compile := $(curdir)/mpfr/compile $(curdir)/gmp/compile
$(curdir)/mpfr/compile := $(curdir)/gmp/compile
-$(curdir)/mtd-utils/compile := $(curdir)/libtool/compile $(curdir)/e2fsprogs/compile $(curdir)/zlib/compile
+$(curdir)/mtd-utils/compile := $(curdir)/libtool/compile $(curdir)/zlib/compile $(curdir)/util-linux/compile
$(curdir)/padjffs2/compile := $(curdir)/findutils/compile
$(curdir)/patchelf/compile := $(curdir)/libtool/compile
$(curdir)/pkgconf/compile := $(curdir)/meson/compile
@@ -129,13 +133,21 @@ $(curdir)/quilt/compile := $(curdir)/autoconf/compile $(curdir)/findutils/compil
$(curdir)/sdcc/compile := $(curdir)/bison/compile
$(curdir)/squashfs3-lzma/compile := $(curdir)/lzma-old/compile
$(curdir)/squashfs4/compile := $(curdir)/xz/compile $(curdir)/zlib/compile
-$(curdir)/util-linux/compile := $(curdir)/bison/compile
+$(curdir)/util-linux/compile := $(curdir)/bison/compile $(curdir)/automake/compile
+$(curdir)/yafut/compile := $(curdir)/cmake/compile
ifneq ($(HOST_OS),Linux)
- $(curdir)/coreutils/compile += $(curdir)/automake/compile $(curdir)/bison/compile $(curdir)/gnulib/compile
- $(curdir)/squashfs4/compile += $(curdir)/coreutils/compile
tools-y += coreutils
+else
+ tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(CONFIG_SDK),y) += coreutils
endif
+ifneq ($(filter coreutils,$(tools-y)),)
+ $(curdir)/elfutils/compile += $(curdir)/coreutils/compile
+ $(curdir)/findutils/compile += $(curdir)/coreutils/compile
+ $(curdir)/squashfs4/compile += $(curdir)/coreutils/compile
+ $(curdir)/util-linux/compile += $(curdir)/coreutils/compile
+endif
+
ifeq ($(HOST_OS),Darwin)
tools-y += bash
else
@@ -145,8 +157,9 @@ endif
ifneq ($(CONFIG_CCACHE)$(CONFIG_SDK),)
$(foreach tool, $(filter-out zstd zlib xz pkgconf patch ninja meson libressl expat cmake,$(tools-y)), $(eval $(curdir)/$(tool)/compile += $(curdir)/ccache/compile))
-tools-y += ccache
-$(curdir)/ccache/compile := $(curdir)/cmake/compile
+tools-y += ccache xxhash
+$(curdir)/xxhash/compile := $(curdir)/cmake/compile
+$(curdir)/ccache/compile := $(curdir)/xxhash/compile
endif
# in case there is no patch tool on the host we need to make patch tool a
diff --git a/tools/autoconf/Makefile b/tools/autoconf/Makefile
index d933c712b4..1058cf9ac4 100644
--- a/tools/autoconf/Makefile
+++ b/tools/autoconf/Makefile
@@ -7,11 +7,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=autoconf
-PKG_VERSION:=2.71
+PKG_VERSION:=2.72
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/autoconf
-PKG_HASH:=431075ad0bf529ef13cb41e9042c542381103e80015686222b8a9d4abef42a1c
+PKG_HASH:=ba885c1319578d6c94d46e9b0dceb4014caafe2490e437a0dbca3f270a223f5a
include $(INCLUDE_DIR)/host-build.mk
diff --git a/tools/autoconf/patches/000-relocatable.patch b/tools/autoconf/patches/000-relocatable.patch
index 3961d2264b..21b7f14f7f 100644
--- a/tools/autoconf/patches/000-relocatable.patch
+++ b/tools/autoconf/patches/000-relocatable.patch
@@ -1,3 +1,34 @@
+--- a/bin/autoconf.in
++++ b/bin/autoconf.in
+@@ -29,7 +29,10 @@ use warnings FATAL => 'all';
+
+ BEGIN
+ {
+- my $pkgdatadir = $ENV{'autom4te_perllibdir'} || '@pkgdatadir@';
++ my $pkgdatadir = $ENV{'autom4te_perllibdir'} ||
++ ($ENV{'STAGING_DIR_HOST'} ?
++ $ENV{'STAGING_DIR_HOST'} . '/share/autoconf' :
++ '@pkgdatadir@');
+ unshift @INC, $pkgdatadir;
+
+ # Override SHELL. On DJGPP SHELL may not be set to a shell
+@@ -44,8 +47,14 @@ use Autom4te::Channels qw(msg);
+ use Autom4te::General;
+
+ # Lib files.
+-my $autom4te = $ENV{'AUTOM4TE'} || '@bindir@/@autom4te-name@';
+-my $trailer_m4 = $ENV{'trailer_m4'} || '@pkgdatadir@/autoconf/trailer.m4';
++my $autom4te = $ENV{'AUTOM4TE'} ||
++ ($ENV{'STAGING_DIR_HOST'} ?
++ $ENV{'STAGING_DIR_HOST'} . '/bin/@autom4te-name@' :
++ '@bindir@/@autom4te-name@');
++my $trailer_m4 = $ENV{'trailer_m4'} ||
++ ($ENV{'STAGING_DIR_HOST'} ?
++ $ENV{'STAGING_DIR_HOST'} . '/share/autoconf/autoconf/trailer.m4' :
++ '@pkgdatadir@/autoconf/trailer.m4');
+
+ # $HELP
+ # -----
--- a/bin/autoheader.in
+++ b/bin/autoheader.in
@@ -30,9 +30,12 @@ use 5.006;
@@ -58,7 +89,7 @@
# Some non-GNU m4's don't reject the --help option, so give them /dev/null.
fatal "need GNU m4 1.4 or later: $m4"
if system "$m4 --help </dev/null 2>&1 | grep reload-state >/dev/null";
-@@ -272,6 +276,12 @@ sub load_configuration ($)
+@@ -322,6 +326,12 @@ sub load_configuration ($)
my @words = shellwords ($_);
my $type = shift @words;
@@ -88,7 +119,7 @@
unshift @INC, $pkgdatadir;
$buildauxdir = $ENV{'autom4te_buildauxdir'} || $pkgdatadir . '/build-aux';
-@@ -117,9 +120,9 @@ Written by David J. MacKenzie and Akim D
+@@ -116,9 +119,9 @@ Written by David J. MacKenzie and Akim D
";
# Lib files.
@@ -175,21 +206,3 @@
unshift @INC, $pkgdatadir;
# Override SHELL. On DJGPP SHELL may not be set to a shell
---- a/bin/autoconf.as
-+++ b/bin/autoconf.as
-@@ -89,8 +89,13 @@ exit_missing_arg='
- # restore font-lock: '
-
- # Variables.
--: ${AUTOM4TE='@bindir@/@autom4te-name@'}
--: ${trailer_m4='@pkgdatadir@/autoconf/trailer.m4'}
-+if test -n "$STAGING_DIR_HOST"; then
-+ : ${AUTOM4TE="$STAGING_DIR_HOST/bin/@autom4te-name@"}
-+ : ${trailer_m4="$STAGING_DIR_HOST/share/autoconf/autoconf/trailer.m4"}
-+else
-+ : ${AUTOM4TE='@bindir@/@autom4te-name@'}
-+ : ${trailer_m4='@pkgdatadir@/autoconf/trailer.m4'}
-+fi
- autom4te_options=
- outfile=
- verbose=false
diff --git a/tools/automake/Makefile b/tools/automake/Makefile
index 7f129c1d83..01cd9941d2 100644
--- a/tools/automake/Makefile
+++ b/tools/automake/Makefile
@@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=automake
PKG_CPE_ID:=cpe:/a:gnu:automake
-PKG_VERSION:=1.16.5
+PKG_VERSION:=1.18.1
PKG_API_VERSION:=$(word 2,$(subst ., ,$(PKG_VERSION)))
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/automake
-PKG_HASH:=07bd24ad08a64bc17250ce09ec56e921d6343903943e99ccf63bbf0705e34605
+PKG_HASH:=63e585246d0fc8772dffdee0724f2f988146d1a3f1c756a3dc5cfbefa3c01915
include $(INCLUDE_DIR)/host-build.mk
@@ -21,8 +21,7 @@ HOST_CONFIGURE_ARGS += \
--disable-silent-rules
HOST_CONFIGURE_VARS += \
- PERL="/usr/bin/env perl" \
- am_cv_prog_PERL_ithreads=no
+ PERL="/usr/bin/env perl"
define Host/Configure
(cd $(HOST_BUILD_DIR); $(AM_TOOL_PATHS) STAGING_DIR_HOST="" ./bootstrap)
diff --git a/tools/automake/patches/000-relocatable.patch b/tools/automake/patches/000-relocatable.patch
index 0b61eaeb45..ec442ed3e3 100644
--- a/tools/automake/patches/000-relocatable.patch
+++ b/tools/automake/patches/000-relocatable.patch
@@ -1,6 +1,6 @@
--- a/lib/Automake/Config.in
+++ b/lib/Automake/Config.in
-@@ -34,7 +34,7 @@ our $PACKAGE = '@PACKAGE@';
+@@ -32,7 +32,7 @@ our $PACKAGE = '@PACKAGE@';
our $PACKAGE_BUGREPORT = '@PACKAGE_BUGREPORT@';
our $VERSION = '@VERSION@';
our $RELEASE_YEAR = '@RELEASE_YEAR@';
@@ -11,9 +11,9 @@
# We need at least this version for CLONE support.
--- a/bin/aclocal.in
+++ b/bin/aclocal.in
-@@ -23,9 +23,11 @@ use 5.006;
- use strict;
- use warnings FATAL => 'all';
+@@ -21,9 +21,11 @@
+
+ use 5.006; use strict; use warnings;
+$^W = 1;
+
@@ -24,22 +24,22 @@
unless $ENV{AUTOMAKE_UNINSTALLED};
}
-@@ -65,8 +67,8 @@ $perl_threads = 0;
- # ACLOCAL_PATH environment variable, and reset with the '--system-acdir'
- # option.
+@@ -63,8 +65,8 @@ $perl_threads = 0;
+ # --aclocal-path option/ACLOCAL_PATH environment variable, and reset
+ # with the '--system-acdir' option.
my @user_includes = ();
-my @automake_includes = ('@datadir@/aclocal-' . $APIVERSION);
-my @system_includes = ('@datadir@/aclocal');
+my @automake_includes = ($ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . "/share/aclocal-$APIVERSION" : "@datadir@/aclocal-$APIVERSION");
+my @system_includes = ($ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/aclocal' : '@datadir@/aclocal');
+ my $aclocal_path = '';
# Whether we should copy M4 file in $user_includes[0].
- my $install = 0;
--- a/bin/automake.in
+++ b/bin/automake.in
-@@ -26,9 +26,11 @@ use 5.006;
- use strict;
- use warnings FATAL => 'all';
+@@ -24,9 +24,11 @@ package Automake;
+
+ use 5.006; use strict; use warnings;
+$^W = 1;
+
diff --git a/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch b/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch
index a0d04e21e5..5ba02c0d85 100644
--- a/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch
+++ b/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch
@@ -1,6 +1,6 @@
--- a/bin/aclocal.in
+++ b/bin/aclocal.in
-@@ -371,6 +371,12 @@ sub scan_m4_dirs ($$@)
+@@ -370,6 +370,12 @@ sub scan_m4_dirs ($$@)
foreach my $m4dir (@dirlist)
{
diff --git a/tools/automake/patches/101-do-not-require-files.patch b/tools/automake/patches/101-do-not-require-files.patch
index 3a8c9fcb47..7fbc330975 100644
--- a/tools/automake/patches/101-do-not-require-files.patch
+++ b/tools/automake/patches/101-do-not-require-files.patch
@@ -1,15 +1,6 @@
--- a/bin/automake.in
+++ b/bin/automake.in
-@@ -4513,7 +4513,7 @@ sub handle_gettext ()
- && grep ($_ eq 'intl', @subdirs));
- }
-
-- require_file ($ac_gettext_location, GNU, 'ABOUT-NLS');
-+ require_file ($ac_gettext_location, GNITS, 'ABOUT-NLS');
- }
-
- # Emit makefile footer.
-@@ -5641,7 +5641,7 @@ sub check_gnu_standards ()
+@@ -5700,7 +5700,7 @@ sub check_gnu_standards ()
# otherwise require non-.md.
my $required
= (! -f $file && -f "$file.md") ? "$file.md" : $file;
@@ -18,7 +9,7 @@
}
# Accept one of these three licenses; default to COPYING.
-@@ -5655,7 +5655,7 @@ sub check_gnu_standards ()
+@@ -5714,7 +5714,7 @@ sub check_gnu_standards ()
last;
}
}
diff --git a/tools/automake/patches/200-other-V-values-for-verbosity.patch b/tools/automake/patches/200-other-V-values-for-verbosity.patch
index 1ea9d38b0e..8a5a2d31bd 100644
--- a/tools/automake/patches/200-other-V-values-for-verbosity.patch
+++ b/tools/automake/patches/200-other-V-values-for-verbosity.patch
@@ -9,8 +9,8 @@ Subject: [PATCH] Allow other V values for verbosity
--- a/m4/silent.m4
+++ b/m4/silent.m4
-@@ -43,7 +43,7 @@ else
- fi])
+@@ -53,7 +53,7 @@ case $enable_silent_rules in @%:@ (((
+ esac
if test $am_cv_make_support_nested_variables = yes; then
dnl Using '$V' instead of '$(V)' breaks IRIX make.
- AM_V='$(V)'
diff --git a/tools/automake/patches/300-output-TRUE-cond-first.patch b/tools/automake/patches/300-output-TRUE-cond-first.patch
new file mode 100644
index 0000000000..1ac655adff
--- /dev/null
+++ b/tools/automake/patches/300-output-TRUE-cond-first.patch
@@ -0,0 +1,34 @@
+--- a/lib/Automake/Variable.pm
++++ b/lib/Automake/Variable.pm
+@@ -1258,8 +1258,15 @@ sub output_variables ()
+ foreach my $var (@vars)
+ {
+ my $v = rvar $var;
++ # Output unconditional definitions before conditional ones.
++ if ($v->def (TRUE)) {
++ $res .= $v->output (TRUE)
++ if $v->rdef (TRUE)->owner == VAR_AUTOMAKE;
++ }
+ foreach my $cond ($v->conditions->conds)
+ {
++ # TRUE is handled already.
++ next if $cond->string eq "TRUE";
+ $res .= $v->output ($cond)
+ if $v->rdef ($cond)->owner == VAR_AUTOMAKE;
+ }
+@@ -1269,8 +1276,15 @@ sub output_variables ()
+ foreach my $var (@vars)
+ {
+ my $v = rvar $var;
++ # Output unconditional definitions before conditional ones.
++ if ($v->def (TRUE)) {
++ $res .= $v->output (TRUE)
++ if $v->rdef (TRUE)->owner != VAR_AUTOMAKE;
++ }
+ foreach my $cond ($v->conditions->conds)
+ {
++ # TRUE is handled already.
++ next if $cond->string eq "TRUE";
+ $res .= $v->output ($cond)
+ if $v->rdef ($cond)->owner != VAR_AUTOMAKE;
+ }
diff --git a/tools/automake/patches/310-maintainer-clean-built_sources.patch b/tools/automake/patches/310-maintainer-clean-built_sources.patch
new file mode 100644
index 0000000000..5166c630da
--- /dev/null
+++ b/tools/automake/patches/310-maintainer-clean-built_sources.patch
@@ -0,0 +1,49 @@
+--- a/bin/automake.in
++++ b/bin/automake.in
+@@ -4760,12 +4760,42 @@ sub handle_clean
+ if var ('CLEANFILES');
+ $clean_files{'$(DISTCLEANFILES)'} = DIST_CLEAN
+ if var ('DISTCLEANFILES');
+- $clean_files{'$(MAINTAINERCLEANFILES)'} = MAINTAINER_CLEAN
+- if var ('MAINTAINERCLEANFILES');
+
+ # Built sources are automatically removed by maintainer-clean.
+- $clean_files{'$(BUILT_SOURCES)'} = MAINTAINER_CLEAN
+- if var ('BUILT_SOURCES');
++ # For each defined condition of the maintainer-clean variable, append built sources
++ # and create an unconditional definition with built sources if not already defined.
++ # Then, for each definition of built sources without maintainer-clean defined, define it.
++ # Otherwise, if the variable is not user-defined, define it with built sources.
++ my $mcleanvar = var ('MAINTAINERCLEANFILES');
++ if ($mcleanvar) {
++ foreach my $rcond ($mcleanvar->conditions->conds)
++ {
++ if (! grep { $_ eq '$(BUILT_SOURCES)' } $mcleanvar->value_as_list ($rcond)) {
++ Automake::Variable::define ($mcleanvar->name, VAR_MAKEFILE, '+', $rcond,
++ '$(BUILT_SOURCES)', '', INTERNAL, VAR_ASIS)
++ if var ('BUILT_SOURCES');
++ }
++ }
++ my $bsources = var ('BUILT_SOURCES');
++ if ($bsources) {
++ foreach my $rcond ($bsources->conditions->conds)
++ {
++ Automake::Variable::define ($mcleanvar->name, VAR_MAKEFILE, '', $rcond,
++ '$(BUILT_SOURCES)', '', INTERNAL, VAR_ASIS)
++ if ! ($mcleanvar->def ($rcond) || $mcleanvar->def (TRUE));
++ }
++ if (! $mcleanvar->def (TRUE)) {
++ Automake::Variable::define ($mcleanvar->name, VAR_MAKEFILE, '', TRUE,
++ '$(BUILT_SOURCES)', '', INTERNAL, VAR_ASIS);
++ }
++ }
++ } else {
++ Automake::Variable::define ('MAINTAINERCLEANFILES', VAR_MAKEFILE, '', TRUE,
++ '$(BUILT_SOURCES)', '', INTERNAL, VAR_ASIS)
++ if var ('BUILT_SOURCES');
++ }
++ $clean_files{'$(MAINTAINERCLEANFILES)'} = MAINTAINER_CLEAN
++ if var ('MAINTAINERCLEANFILES');
+
+ # Compute a list of "rm"s to run for each target.
+ my %rms = (MOSTLY_CLEAN, [],
diff --git a/tools/automake/patches/999-clean-am.patch b/tools/automake/patches/999-clean-am.patch
new file mode 100644
index 0000000000..a9642d1c79
--- /dev/null
+++ b/tools/automake/patches/999-clean-am.patch
@@ -0,0 +1,28 @@
+--- a/lib/am/clean.am
++++ b/lib/am/clean.am
+@@ -39,7 +39,7 @@ distclean-generic:
+ ## If you change distclean here, you probably also want to change
+ ## maintainer-clean below.
+ distclean:
+- -rm -f %MAKEFILE%
++ -touch %MAKEFILE%
+
+ maintainer-clean-am: maintainer-clean-generic distclean-am
+ maintainer-clean-generic:
+@@ -51,7 +51,7 @@ maintainer-clean-generic:
+
+ ## See comment for distclean.
+ maintainer-clean:
+- -rm -f %MAKEFILE%
++ -touch %MAKEFILE%
+
+ .PHONY: clean mostlyclean distclean maintainer-clean \
+ clean-generic mostlyclean-generic distclean-generic maintainer-clean-generic
+--- a/lib/am/libtool.am
++++ b/lib/am/libtool.am
+@@ -25,4 +25,4 @@ clean-libtool:
+
+ ?TOPDIR_P?distclean-am: distclean-libtool
+ ?TOPDIR_P?distclean-libtool:
+-?TOPDIR_P? -rm -f libtool config.lt
++?TOPDIR_P? -touch libtool config.lt
diff --git a/tools/b43-tools/Makefile b/tools/b43-tools/Makefile
index 8ec13309be..eb2fb284a8 100644
--- a/tools/b43-tools/Makefile
+++ b/tools/b43-tools/Makefile
@@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=b43-tools
-PKG_DATE:=2022-07-05
+PKG_DATE:=2025-05-04
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/mbuesch/b43-tools.git
-PKG_SOURCE_VERSION:=2fe10ea6690df9a068cb21cde537236bae784a14
-PKG_MIRROR_HASH:=4009d6c1f9ede43102897d6ebf4bd954331f3c4e2a94d4e61c0e5f303f929914
+PKG_SOURCE_VERSION:=cc352349153eeda9c164ecd0d06c161a59ec8753
+PKG_MIRROR_HASH:=c1feba649c2cf3e984a2b897b4a6938252515c0833358d51bd15e049b6b2fb65
include $(INCLUDE_DIR)/host-build.mk
diff --git a/tools/bash/Makefile b/tools/bash/Makefile
index f8262d1db0..8aeb1719f6 100644
--- a/tools/bash/Makefile
+++ b/tools/bash/Makefile
@@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=bash
PKG_CPE_ID:=cpe:/a:gnu:bash
-PKG_VERSION:=5.2.21
+PKG_VERSION:=5.3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/bash
-PKG_HASH:=c8e31bdc59b69aaffc5b36509905ba3e5cbb12747091d27b4b977f078560d5b8
+PKG_HASH:=0d5cd86965f869a26cf64f4b71be7b96f90a3ba8b3d74e27e8e9d9d5550f31ba
HOST_BUILD_PARALLEL := 1
diff --git a/tools/bc/Makefile b/tools/bc/Makefile
index 2c29e094e2..e86a68c05b 100644
--- a/tools/bc/Makefile
+++ b/tools/bc/Makefile
@@ -7,19 +7,20 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bc
-PKG_VERSION:=1.07.1
+PKG_VERSION:=1.08.1
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/bc
-PKG_HASH:=62adfca89b0a1c0164c2cdca59ca210c1d44c3ffc46daf9931cf4942664cb02a
+PKG_HASH:=515430115b3334c636317503460a0950dff79940aa3259ce2c1aa67c2881d023
-PKG_FIXUP := autoreconf
PKG_CPE_ID:=cpe:/a:gnu:bc
+PKG_SUBDIRS:=lib bc dc
+
include $(INCLUDE_DIR)/host-build.mk
define Host/Uninstall
- -$(call Host/Compile/Default,uninstall)
+ -$(call Host/Compile/Default,uninstall SUBDIRS='lib bc dc')
endef
$(eval $(call HostBuild))
diff --git a/tools/bc/patches/000-getopt-prototype.patch b/tools/bc/patches/000-getopt-prototype.patch
new file mode 100644
index 0000000000..ca6246963b
--- /dev/null
+++ b/tools/bc/patches/000-getopt-prototype.patch
@@ -0,0 +1,18 @@
+--- a/h/getopt.h
++++ b/h/getopt.h
+@@ -135,15 +135,7 @@ struct option
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `getopt'. */
+
+-#ifdef __GNU_LIBRARY__
+-/* Many other libraries have conflicting prototypes for getopt, with
+- differences in the consts, in stdlib.h. To avoid compilation
+- errors, only prototype getopt for the GNU C library. */
+ extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
+-#else /* not __GNU_LIBRARY__ */
+-extern int getopt ();
+-#endif /* __GNU_LIBRARY__ */
+-
+ #ifndef __need_getopt
+ extern int getopt_long (int ___argc, char *const *___argv,
+ const char *__shortopts,
diff --git a/tools/bc/patches/001-no_doc.patch b/tools/bc/patches/001-no_doc.patch
deleted file mode 100644
index 119f111f49..0000000000
--- a/tools/bc/patches/001-no_doc.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -1,6 +1,6 @@
- ## Process this file with automake to produce Makefile.in
-
--SUBDIRS = lib bc dc doc
-+SUBDIRS = lib bc dc
-
- MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in \
- stamp-h $(distdir).tar.gz h/number.h depcomp missing \
---- a/Makefile.in
-+++ b/Makefile.in
-@@ -288,7 +288,7 @@ target_alias = @target_alias@
- top_build_prefix = @top_build_prefix@
- top_builddir = @top_builddir@
- top_srcdir = @top_srcdir@
--SUBDIRS = lib bc dc doc
-+SUBDIRS = lib bc dc
- MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in \
- stamp-h $(distdir).tar.gz h/number.h depcomp missing \
- bc/libmath.h
diff --git a/tools/bc/patches/002-fix-libmath.patch b/tools/bc/patches/002-fix-libmath.patch
deleted file mode 100644
index f2212f0953..0000000000
--- a/tools/bc/patches/002-fix-libmath.patch
+++ /dev/null
@@ -1,32 +0,0 @@
---- a/bc/fix-libmath_h
-+++ b/bc/fix-libmath_h
-@@ -1,9 +1,9 @@
--ed libmath.h <<EOS-EOS
--1,1s/^/{"/
--1,\$s/\$/",/
--2,\$s/^/"/
--\$,\$d
--\$,\$s/,\$/,0}/
--w
--q
--EOS-EOS
-+#!/usr/bin/env bash
-+sed -e '1 s/^/{"/' \
-+ -e 's/$/",/' \
-+ -e '2,$ s/^/"/' \
-+ -e '$ d' \
-+ -i libmath.h
-+
-+sed -e '$ s/$/0}/' \
-+ -i libmath.h
---- a/configure
-+++ b/configure
-@@ -5288,7 +5288,7 @@ case $bcle-$bcrl-$LEX in
- ?-?-flex)
- LEX="flex -I -8" ;;
- ?-y-*)
-- as_fn_error $? "readline works only with flex." "$LINENO" 5 ;;
-+ : ;; # as_fn_error $? "readline works only with flex." "$LINENO" 5 ;;
- esac
-
- case $LEX-`uname -s` in
diff --git a/tools/bison/Makefile b/tools/bison/Makefile
index 97d34b5a16..4cb0faf336 100644
--- a/tools/bison/Makefile
+++ b/tools/bison/Makefile
@@ -21,13 +21,13 @@ include $(INCLUDE_DIR)/host-build.mk
HOST_CONFIGURE_ARGS += --enable-threads=posix --disable-nls
define Host/Install
- $(call Host/Install/Default)
+ $(call Host/Compile/Default,install aclocal_DATA=) # Macro provided by gnulib
$(INSTALL_BIN) ./scripts/yacc $(STAGING_DIR_HOST)/bin/yacc
endef
define Host/Uninstall
rm -f $(STAGING_DIR_HOST)/bin/yacc
- -$(call Host/Compile/Default,uninstall)
+ -$(call Host/Compile/Default,uninstall aclocal_DATA=) # Macro provided by gnulib
endef
$(eval $(call HostBuild))
diff --git a/tools/ccache/Makefile b/tools/ccache/Makefile
index cd2c6d27d5..e8ae78a5dd 100644
--- a/tools/ccache/Makefile
+++ b/tools/ccache/Makefile
@@ -7,11 +7,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ccache
-PKG_VERSION:=4.9.1
+PKG_VERSION:=4.11.3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/ccache/ccache/releases/download/v$(PKG_VERSION)
-PKG_HASH:=12834ecaaaf2db069dda1d1d991f91c19e3274cc04a471af5b64195def17e90f
+PKG_HASH:=28a407314f03a7bd7a008038dbaffa83448bc670e2fc119609b1d99fb33bb600
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/cmake.mk
@@ -22,6 +22,7 @@ CMAKE_HOST_OPTIONS += \
-DCMAKE_SKIP_RPATH=FALSE \
-DCMAKE_INSTALL_RPATH="${STAGING_DIR_HOST}/lib" \
-DENABLE_DOCUMENTATION=OFF \
- -DREDIS_STORAGE_BACKEND=OFF
+ -DREDIS_STORAGE_BACKEND=OFF \
+ -DENABLE_TESTING=OFF
$(eval $(call HostBuild))
diff --git a/tools/ccache/patches/100-honour-copts.patch b/tools/ccache/patches/100-honour-copts.patch
index 8f1c426501..8c95685b28 100644
--- a/tools/ccache/patches/100-honour-copts.patch
+++ b/tools/ccache/patches/100-honour-copts.patch
@@ -1,6 +1,6 @@
---- a/src/ccache.cpp
-+++ b/src/ccache.cpp
-@@ -1841,6 +1841,7 @@ get_manifest_key(Context& ctx, Hash& has
+--- a/src/ccache/ccache.cpp
++++ b/src/ccache/ccache.cpp
+@@ -2018,6 +2018,7 @@ get_manifest_key(Context& ctx, Hash& has
"OBJCPLUS_INCLUDE_PATH", // Clang
"CLANG_CONFIG_FILE_SYSTEM_DIR", // Clang
"CLANG_CONFIG_FILE_USER_DIR", // Clang
diff --git a/tools/cmake/Makefile b/tools/cmake/Makefile
index 1027b671bd..6bc79a7a55 100644
--- a/tools/cmake/Makefile
+++ b/tools/cmake/Makefile
@@ -7,7 +7,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=cmake
-PKG_VERSION:=3.29.0
+PKG_VERSION:=3.31.5
PKG_VERSION_MAJOR:=$(word 1,$(subst ., ,$(PKG_VERSION))).$(word 2,$(subst ., ,$(PKG_VERSION)))
PKG_RELEASE:=1
PKG_CPE_ID:=cpe:/a:kitware:cmake
@@ -15,7 +15,7 @@ PKG_CPE_ID:=cpe:/a:kitware:cmake
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/Kitware/CMake/releases/download/v$(PKG_VERSION)/ \
https://cmake.org/files/v$(PKG_VERSION_MAJOR)/
-PKG_HASH:=a0669630aae7baa4a8228048bf30b622f9e9fd8ee8cedb941754e9e38686c778
+PKG_HASH:=66fb53a145648be56b46fa9e8ccade3a4d0dfc92e401e52ce76bdad1fea43d27
HOST_BUILD_PARALLEL:=1
HOST_CONFIGURE_PARALLEL:=1
diff --git a/tools/cmake/patches/110-liblzma.patch b/tools/cmake/patches/110-liblzma.patch
index d7cbd434a1..4b8ec0d33f 100644
--- a/tools/cmake/patches/110-liblzma.patch
+++ b/tools/cmake/patches/110-liblzma.patch
@@ -1,8 +1,8 @@
--- a/Modules/FindLibLZMA.cmake
+++ b/Modules/FindLibLZMA.cmake
-@@ -58,7 +58,13 @@ The following variables are provided for
-
- #]=======================================================================]
+@@ -61,7 +61,13 @@ The following variables are provided for
+ cmake_policy(PUSH)
+ cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
-find_path(LIBLZMA_INCLUDE_DIR lzma.h )
+if(UNIX)
diff --git a/tools/cmake/patches/120-curl-fix-libressl-linking.patch b/tools/cmake/patches/120-curl-fix-libressl-linking.patch
index a46acd63da..7fda7c59a0 100644
--- a/tools/cmake/patches/120-curl-fix-libressl-linking.patch
+++ b/tools/cmake/patches/120-curl-fix-libressl-linking.patch
@@ -20,10 +20,11 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
---
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
-@@ -647,6 +647,14 @@ if(CURL_USE_OPENSSL)
+@@ -775,7 +775,14 @@ if(CURL_USE_OPENSSL)
endif()
- set(SSL_ENABLED ON)
+ set(_ssl_enabled ON)
set(USE_OPENSSL ON)
+-
+ check_library_exists("rt" clock_gettime "" HAVE_LIBRT)
+ if(HAVE_LIBRT)
+ list(APPEND OPENSSL_LIBRARIES rt)
@@ -34,4 +35,4 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
+ endif()
list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
include_directories(${OPENSSL_INCLUDE_DIR})
-
+ list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "openssl")
diff --git a/tools/cmake/patches/130-bootstrap_parallel_make_flag.patch b/tools/cmake/patches/130-bootstrap_parallel_make_flag.patch
index ffe47f9901..2409ba666f 100644
--- a/tools/cmake/patches/130-bootstrap_parallel_make_flag.patch
+++ b/tools/cmake/patches/130-bootstrap_parallel_make_flag.patch
@@ -1,6 +1,6 @@
--- a/bootstrap
+++ b/bootstrap
-@@ -1493,7 +1493,10 @@ int main(){ printf("1%c", (char)0x0a); r
+@@ -1514,7 +1514,10 @@ int main(){ printf("1%c", (char)0x0a); r
' > "test.c"
cmake_original_make_flags="${cmake_make_flags}"
if test "x${cmake_parallel_make}" != "x"; then
diff --git a/tools/cmake/patches/140-zlib.patch b/tools/cmake/patches/140-zlib.patch
index 8b7b7de1b0..17334a66e0 100644
--- a/tools/cmake/patches/140-zlib.patch
+++ b/tools/cmake/patches/140-zlib.patch
@@ -1,6 +1,6 @@
--- a/Modules/FindZLIB.cmake
+++ b/Modules/FindZLIB.cmake
-@@ -117,10 +117,13 @@ else()
+@@ -120,10 +120,13 @@ else()
set(ZLIB_NAMES_DEBUG zd zlibd zdlld zlibd1 zlib1d zlibstaticd zlibwapid zlibvcd zlibstatd)
endif()
diff --git a/tools/cmake/patches/150-zstd-libarchive.patch b/tools/cmake/patches/150-zstd-libarchive.patch
index a6f8e35e6b..429ef80f54 100644
--- a/tools/cmake/patches/150-zstd-libarchive.patch
+++ b/tools/cmake/patches/150-zstd-libarchive.patch
@@ -1,6 +1,6 @@
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
-@@ -656,7 +656,7 @@ IF(ENABLE_ZSTD)
+@@ -680,7 +680,7 @@ IF(ENABLE_ZSTD)
SET(ZSTD_FIND_QUIETLY TRUE)
ENDIF (ZSTD_INCLUDE_DIR)
diff --git a/tools/cmake/patches/160-disable_xcode_generator.patch b/tools/cmake/patches/160-disable_xcode_generator.patch
index 20d1086bd4..f10981cd32 100644
--- a/tools/cmake/patches/160-disable_xcode_generator.patch
+++ b/tools/cmake/patches/160-disable_xcode_generator.patch
@@ -1,6 +1,6 @@
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
-@@ -846,7 +846,7 @@ if(CMake_USE_XCOFF_PARSER)
+@@ -888,7 +888,7 @@ if(CMake_USE_XCOFF_PARSER)
endif()
# Xcode only works on Apple
@@ -11,7 +11,7 @@
PRIVATE
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
-@@ -132,7 +132,7 @@
+@@ -133,7 +133,7 @@
# include "cmGlobalGhsMultiGenerator.h"
#endif
diff --git a/tools/coreutils/Makefile b/tools/coreutils/Makefile
index f55fdcc1b2..a0443b214c 100644
--- a/tools/coreutils/Makefile
+++ b/tools/coreutils/Makefile
@@ -8,38 +8,42 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=coreutils
PKG_CPE_ID:=cpe:/a:gnu:coreutils
-PKG_VERSION:=9.5
+PKG_VERSION:=9.6
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/coreutils
-PKG_HASH:=767ae6a22950ec42f3ba5f7c1de79dd27800ee8e9b8642da5dedb5974a1741e5
+PKG_HASH:=2bec616375002c92c1ed5ead32a092b174fe44c14bc736d32e5961053b821d84
HOST_BUILD_PARALLEL := 1
-PKG_PROGRAMS:=date readlink touch ln chown ginstall
+PKG_PROGRAMS:=chown cp date ginstall ln readlink realpath rmdir seq stat touch
include $(INCLUDE_DIR)/host-build.mk
export GNULIB_SRCDIR:=$(HOST_GNULIB_SRCDIR)
HOST_GNULIB_SKIP := \
- lib/nstrftime.c \
- lib/fprintftime.c \
- lib/locale.in.h
+ lib/iconv_open-aix.gperf \
+ lib/iconv_open-hpux.gperf \
+ lib/iconv_open-irix.gperf \
+ lib/iconv_open-osf.gperf \
+ lib/iconv_open-solaris.gperf \
+ lib/iconv_open-zos.gperf
HOST_CONFIGURE_ARGS += \
- --disable-year2038 \
--enable-install-program=$(subst $(space),$(comma),$(strip $(PKG_PROGRAMS)))
HOST_MAKE_FLAGS += \
- $(AM_TOOL_PATHS_FAKE) \
+ $(AM_TOOL_PATHS) AUTOPOINT="$(TRUE)" GTKDOCIZE="$(TRUE)" \
+ am__CONFIG_DISTCLEAN_FILES= \
+ MAINTAINERCLEANFILES='$$$$(filter-out lib/iconv_open% %.texi,$$$$(BUILT_SOURCES))' \
PROGRAMS="$(patsubst %,src/%,$(PKG_PROGRAMS))" \
LIBRARIES= MANS= SUBDIRS=.
define Host/Bootstrap
( \
cd $(HOST_BUILD_DIR); \
- $(AM_TOOL_PATHS_FAKE) \
+ $(AM_TOOL_PATHS) AUTOPOINT="$(TRUE)" GTKDOCIZE="$(TRUE)" \
./bootstrap \
--bootstrap-sync \
--force \
@@ -58,17 +62,21 @@ define Host/Configure
$(if $(QUILT),$(call Host/Bootstrap))
$(foreach src,$(HOST_GNULIB_SKIP),mv -f $(HOST_BUILD_DIR)/$(src)~ $(HOST_BUILD_DIR)/$(src) || true; )
$(call Host/Configure/Default)
+ $(call Host/Uninstall)
+ $(call Host/Compile/Default,lib/config.h)
endef
define Host/Install
$(INSTALL_DIR) $(1)/bin
- $(INSTALL_BIN) $(patsubst %,$(HOST_BUILD_DIR)/src/%,$(PKG_PROGRAMS)) $(1)/bin/
- ln -sf ginstall $(1)/bin/install
+ $(foreach prog,$(filter-out g%,$(PKG_PROGRAMS)),$(INSTALL_BIN) $(patsubst %,$(HOST_BUILD_DIR)/src/%,$(prog)) $(1)/bin/g$(prog); )
+ $(foreach prog,$(filter g%,$(PKG_PROGRAMS)),$(INSTALL_BIN) $(patsubst %,$(HOST_BUILD_DIR)/src/%,$(prog)) $(1)/bin/$(prog); )
+ $(foreach prog,$(filter-out g%,$(PKG_PROGRAMS)),g$(LN) g$(prog) $(1)/bin/$(prog); )
+ $(foreach prog,$(filter g%,$(PKG_PROGRAMS)),g$(LN) $(prog) $(1)/bin/$(patsubst g%,%,$(prog)); )
endef
define Host/Uninstall
- rm -f $(STAGING_DIR_HOST)/bin/install
- -$(call Host/Compile/Default,uninstall)
+ #$(call Host/Compile/Default,uninstall) # Removes necessary symlinks
+ -$(call Host/Compile/Default,maintainer-clean) # Clean bootstrap files from the release
endef
$(eval $(call HostBuild))
diff --git a/tools/coreutils/patches/000-bootstrap.patch b/tools/coreutils/patches/000-bootstrap.patch
index 68db19084f..1edf879e0e 100644
--- a/tools/coreutils/patches/000-bootstrap.patch
+++ b/tools/coreutils/patches/000-bootstrap.patch
@@ -34,7 +34,7 @@
if [ ! "$inst_ver" ]; then
warn_ "Error: '$app' not found"
ret=1
-@@ -1157,7 +1157,7 @@ autogen()
+@@ -1205,7 +1205,7 @@ autogen()
# two just-pre-run programs.
# Import from gettext.
@@ -43,3 +43,17 @@
grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
with_gettext=no
+--- a/bootstrap.conf
++++ b/bootstrap.conf
+@@ -354,11 +354,8 @@ gnulib_tool_option_extras="--tests-base=
+ buildreq="\
+ autoconf 2.64
+ automake 1.11.2
+-autopoint 0.19.2
+ bison -
+-gettext 0.19.2
+ git 1.4.4
+-gperf -
+ gzip -
+ m4 -
+ makeinfo 6.1
diff --git a/tools/cpio/patches/cpio-c23.patch b/tools/cpio/patches/cpio-c23.patch
new file mode 100644
index 0000000000..825f369d6e
--- /dev/null
+++ b/tools/cpio/patches/cpio-c23.patch
@@ -0,0 +1,23 @@
+--- a/src/extern.h
++++ b/src/extern.h
+@@ -97,7 +97,8 @@ extern char input_is_special;
+ extern char output_is_special;
+ extern char input_is_seekable;
+ extern char output_is_seekable;
+-extern int (*xstat) ();
++//void not good enough
++extern int (*xstat) (const char * restrict, struct stat * restrict);
+ extern void (*copy_function) ();
+ extern char *change_directory_option;
+
+--- a/src/global.c
++++ b/src/global.c
+@@ -185,7 +185,7 @@ bool to_stdout_option = false;
+
+ /* A pointer to either lstat or stat, depending on whether
+ dereferencing of symlinks is done for input files. */
+-int (*xstat) ();
++int (*xstat) (const char * restrict, struct stat * restrict);
+
+ /* Which copy operation to perform. (-i, -o, -p) */
+ void (*copy_function) () = 0;
diff --git a/tools/dwarves/Makefile b/tools/dwarves/Makefile
index 16dc765f58..56259b260e 100644
--- a/tools/dwarves/Makefile
+++ b/tools/dwarves/Makefile
@@ -3,12 +3,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dwarves
-PKG_VERSION:=1.26
+PKG_VERSION:=1.29
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://fedorapeople.org/~acme/dwarves/
-PKG_HASH:=1d8c9a1c2d42e06cc121a70a39c4f621fd28f15c476ed1b7c7b226f41fdd32df
+PKG_HASH:=59c597d4e953c714d6f3ff36aeed2ac30cba85c1d7b94d0c87ca91d611d98a56
PKG_MAINTAINER:=Tony Ambardar <itugrok@yahoo.com>
PKG_LICENSE:=GPL-2.0-only
diff --git a/tools/e2fsprogs/Makefile b/tools/e2fsprogs/Makefile
index 567e6a4c9a..5deee08160 100644
--- a/tools/e2fsprogs/Makefile
+++ b/tools/e2fsprogs/Makefile
@@ -9,11 +9,10 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=e2fsprogs
PKG_CPE_ID:=cpe:/a:e2fsprogs_project:e2fsprogs
-PKG_VERSION:=1.47.0
-PKG_HASH:=0b4fe723d779b0927fb83c9ae709bc7b40f66d7df36433bef143e41c54257084
-PKG_RELEASE:=1
+PKG_VERSION:=1.47.2
+PKG_HASH:=08242e64ca0e8194d9c1caad49762b19209a06318199b63ce74ae4ef2d74e63c
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@KERNEL/linux/kernel/people/tytso/e2fsprogs/v$(PKG_VERSION)/
HOST_BUILD_PARALLEL:=1
@@ -27,11 +26,16 @@ HOST_CFLAGS += $(HOST_FPIC)
HOST_CONFIGURE_ARGS += \
--disable-elf-shlibs \
- --enable-libuuid \
+ --disable-libuuid \
--disable-tls \
--disable-nls \
--enable-threads=pth \
- --disable-fuse2fs
+ --disable-fuse2fs \
+ --with-crond-dir=no
+
+# The following uses pkg-config the wrong way around. Just override it.
+HOST_CONFIGURE_VARS += \
+ ac_cv_lib_uuid_uuid_generate=yes
define Host/Prepare
$(call Host/Prepare/Default)
@@ -39,17 +43,13 @@ define Host/Prepare
endef
define Host/Install
- $(Host/Install/Default)
- $(MAKE) -C $(HOST_BUILD_DIR)/lib/uuid install
- mkdir -p $(STAGING_DIR_HOST)/include/e2fsprogs
- $(CP) $(STAGING_DIR_HOST)/include/uuid $(STAGING_DIR_HOST)/include/e2fsprogs/
- rm -rf $(STAGING_DIR_HOST)/include/uuid
- $(INSTALL_DATA) $(HOST_BUILD_DIR)/lib/uuid/libuuid.a $(STAGING_DIR_HOST)/lib/
+ $(call Host/Install/Default)
+ $(SED) 's|^DIR=.*|DIR=$$$${STAGING_DIR_HOST}/share/et|' $(STAGING_DIR_HOST)/bin/compile_et
+ $(SED) 's|^DIR=.*|DIR=$$$${STAGING_DIR_HOST}/share/ss|' $(STAGING_DIR_HOST)/bin/mk_cmds
endef
-define Host/Clean
- rm -f $(STAGING_DIR_HOST)/bin/e2fsck
- rm -f $(STAGING_DIR_HOST)/bin/tune2fs
+define Host/Uninstall
+ -$(call Host/Compile/Default,uninstall)
endef
$(eval $(call HostBuild))
diff --git a/tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch b/tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch
deleted file mode 100644
index c94c609160..0000000000
--- a/tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/e2fsck/e2fsck.h
-+++ b/e2fsck/e2fsck.h
-@@ -81,7 +81,7 @@
- * Exit codes used by fsck-type programs
- */
- #define FSCK_OK 0 /* No errors */
--#define FSCK_NONDESTRUCT 1 /* File system errors corrected */
-+#define FSCK_NONDESTRUCT 0 /* File system errors corrected */
- #define FSCK_REBOOT 2 /* System should be rebooted */
- #define FSCK_UNCORRECTED 4 /* File system errors left uncorrected */
- #define FSCK_ERROR 8 /* Operational error */
diff --git a/tools/e2fsprogs/patches/002-dont-build-e4defrag.patch b/tools/e2fsprogs/patches/002-dont-build-e4defrag.patch
deleted file mode 100644
index f59cd317a1..0000000000
--- a/tools/e2fsprogs/patches/002-dont-build-e4defrag.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/misc/Makefile.in
-+++ b/misc/Makefile.in
-@@ -12,7 +12,7 @@ MKDIR_P = @MKDIR_P@
-
- @MCONFIG@
-
--@DEFRAG_CMT@@LINUX_CMT@E4DEFRAG_PROG= e4defrag
-+@DEFRAG_CMT@@LINUX_CMT@E4DEFRAG_PROG=
- @DEFRAG_CMT@@LINUX_CMT@E4DEFRAG_MAN= e4defrag.8
-
- @LINUX_CMT@E4CRYPT_PROG = e4crypt
diff --git a/tools/e2fsprogs/patches/003-no-crond.patch b/tools/e2fsprogs/patches/003-no-crond.patch
deleted file mode 100644
index 67ddd4ab0c..0000000000
--- a/tools/e2fsprogs/patches/003-no-crond.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/configure
-+++ b/configure
-@@ -15259,7 +15259,7 @@ then :
-
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${crond_dir}" >&5
- printf "%s\n" "${crond_dir}" >&6; }
-- have_crond="yes"
-+ have_crond="no"; with_crond_dir=""
-
- else $as_nop
-
diff --git a/tools/elftosb/patches/001-libm.patch b/tools/elftosb/patches/001-libm.patch
index 02705d24bb..6b49ac1af2 100644
--- a/tools/elftosb/patches/001-libm.patch
+++ b/tools/elftosb/patches/001-libm.patch
@@ -1,6 +1,6 @@
---- elftosb-10.12.01/makefile.rules 2012-03-15 11:01:44.979020178 -0400
-+++ elftosb-10.12.01/makefile.rules 2012-03-15 11:01:16.332761989 -0400
-@@ -101,7 +101,7 @@
+--- a/makefile.rules
++++ b/makefile.rules
+@@ -101,7 +101,7 @@ OBJ_FILES_KEYGEN = \
keygen.o
diff --git a/tools/elftosb/patches/002-fix-header-path.patch b/tools/elftosb/patches/002-fix-header-path.patch
index 5e3b5091b9..5099b29644 100644
--- a/tools/elftosb/patches/002-fix-header-path.patch
+++ b/tools/elftosb/patches/002-fix-header-path.patch
@@ -5,9 +5,8 @@ others once multiarch becomes more common.
This patch makes the types a relative path, and allows the system
to use whatever include paths it feels are correct.
-diff -Naurp elftosb-10.12.01-orig/common/stdafx.h elftosb-10.12.01/common/stdafx.h
---- elftosb-10.12.01-orig/common/stdafx.h 2012-07-12 13:30:10.990249396 -0400
-+++ elftosb-10.12.01/common/stdafx.h 2012-07-12 13:30:06.858249391 -0400
+--- a/common/stdafx.h
++++ b/common/stdafx.h
@@ -27,7 +27,7 @@
// For Linux systems only, types.h only defines the signed
// integer types. This is not professional code.
diff --git a/tools/elftosb/patches/010-no-register.patch b/tools/elftosb/patches/010-no-register.patch
new file mode 100644
index 0000000000..7a830370e2
--- /dev/null
+++ b/tools/elftosb/patches/010-no-register.patch
@@ -0,0 +1,113 @@
+--- a/elftosb2/elftosb_lexer.cpp
++++ b/elftosb2/elftosb_lexer.cpp
+@@ -722,9 +722,9 @@ static int yy_flex_strlen (yyconst char
+ */
+ YY_DECL
+ {
+- register yy_state_type yy_current_state;
+- register char *yy_cp, *yy_bp;
+- register int yy_act;
++ yy_state_type yy_current_state;
++ char *yy_cp, *yy_bp;
++ int yy_act;
+
+ #line 38 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+
+@@ -773,7 +773,7 @@ YY_DECL
+ yy_match:
+ do
+ {
+- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
++ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+@@ -1555,9 +1555,9 @@ void yyFlexLexer::LexerOutput( const cha
+ */
+ int yyFlexLexer::yy_get_next_buffer()
+ {
+- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+- register char *source = (yytext_ptr);
+- register int number_to_move, i;
++ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
++ char *source = (yytext_ptr);
++ int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+@@ -1689,14 +1689,14 @@ int yyFlexLexer::yy_get_next_buffer()
+
+ yy_state_type yyFlexLexer::yy_get_previous_state()
+ {
+- register yy_state_type yy_current_state;
+- register char *yy_cp;
++ yy_state_type yy_current_state;
++ char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
++ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+@@ -1721,10 +1721,10 @@ int yyFlexLexer::yy_get_next_buffer()
+ */
+ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state )
+ {
+- register int yy_is_jam;
+- register char *yy_cp = (yy_c_buf_p);
++ int yy_is_jam;
++ char *yy_cp = (yy_c_buf_p);
+
+- register YY_CHAR yy_c = 1;
++ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+@@ -1742,9 +1742,9 @@ int yyFlexLexer::yy_get_next_buffer()
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+- void yyFlexLexer::yyunput( int c, register char* yy_bp)
++ void yyFlexLexer::yyunput( int c, char* yy_bp)
+ {
+- register char *yy_cp;
++ char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+@@ -1754,10 +1754,10 @@ int yyFlexLexer::yy_get_next_buffer()
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+- register yy_size_t number_to_move = (yy_n_chars) + 2;
+- register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
++ yy_size_t number_to_move = (yy_n_chars) + 2;
++ char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+- register char *source =
++ char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+@@ -2190,7 +2190,7 @@ void yyFlexLexer::LexerError( yyconst ch
+ #ifndef yytext_ptr
+ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+ {
+- register int i;
++ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+@@ -2199,7 +2199,7 @@ static void yy_flex_strncpy (char* s1, y
+ #ifdef YY_NEED_STRLEN
+ static int yy_flex_strlen (yyconst char * s )
+ {
+- register int n;
++ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
diff --git a/tools/elfutils/Makefile b/tools/elfutils/Makefile
index 466fc31271..294947df10 100644
--- a/tools/elfutils/Makefile
+++ b/tools/elfutils/Makefile
@@ -3,22 +3,22 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=elfutils
-PKG_VERSION:=0.191
-PKG_RELEASE:=2
+PKG_VERSION:=0.192
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://sourceware.org/$(PKG_NAME)/ftp/$(PKG_VERSION)
-PKG_HASH:=df76db71366d1d708365fc7a6c60ca48398f14367eb2b8954efc8897147ad871
+PKG_HASH:=616099beae24aba11f9b63d86ca6cc8d566d968b802391334c91df54eab416b4
PKG_LICENSE:=GPL-3.0-or-later
PKG_LICENSE_FILES:=COPYING COPYING-GPLV2 COPYING-LGPLV3
PKG_CPE_ID:=cpe:/a:elfutils_project:elfutils
PKG_FIXUP:=autoreconf
-PKG_INSTALL:=1
+
+PKG_PROGRAMS:=elflint findtextrel elfcmp unstrip stack elfcompress elfclassify srcfiles
PKG_SUBDIRS := \
- libgnu \
config \
lib \
libelf \
@@ -27,35 +27,77 @@ PKG_SUBDIRS := \
libebl \
libdwelf \
libdwfl \
- libdw
+ libdw \
+ src
PKG_GNULIB_BASE:=libgnu
PKG_GNULIB_ARGS = \
--dir=$(HOST_BUILD_DIR) \
- --local-dir=$(STAGING_DIR_HOST)/share/gnulib \
- --source-base=$(PKG_GNULIB_BASE) \
--libtool \
--avoid=reallocarray \
--import
PKG_GNULIB_MODS = \
argp \
+ fallocate-posix \
+ fnmatch-gnu \
fts \
- obstack \
+ obstack-printf-posix \
progname \
strchrnul \
tsearch
+HOST_BUILD_PARALLEL:=1
+
include $(INCLUDE_DIR)/host-build.mk
+export $(PKG_GNULIB_BASE)=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/.libs/$(PKG_GNULIB_BASE).a
+
+export $(PKG_GNULIB_BASE)_exitfail=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-exitfail.o
+export $(PKG_GNULIB_BASE)_fallocate-posix=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-posix_fallocate.o
+export $(PKG_GNULIB_BASE)_mbszero=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-mbszero.o
+export $(PKG_GNULIB_BASE)_obstack=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-obstack.o
+export $(PKG_GNULIB_BASE)_obstack-printf=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-obstack_printf.o
+export $(PKG_GNULIB_BASE)_printf-args=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-printf-args.o
+export $(PKG_GNULIB_BASE)_printf-frexp=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-printf-frexp.o
+export $(PKG_GNULIB_BASE)_printf-frexpl=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-printf-frexpl.o
+export $(PKG_GNULIB_BASE)_printf-parse=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-printf-parse.o
+export $(PKG_GNULIB_BASE)_tsearch=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-tsearch.o
+export $(PKG_GNULIB_BASE)_vasnprintf=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-vasnprintf.o
+export $(PKG_GNULIB_BASE)_xsize=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-xsize.o
+
+HOST_MAKE_FLAGS += \
+ am__CONFIG_DISTCLEAN_FILES= \
+ DEFAULT_INCLUDES='-iquote . -I$$$$(top_builddir) -I$$$$(top_srcdir)/$(PKG_GNULIB_BASE)' \
+ AM_LDFLAGS='$$$$(STACK_USAGE_NO_ERROR)' \
+ LIBS+='$$$$(if $$$$(findstring $(lastword $(PKG_SUBDIRS)),$$$$(subdir)), $$$$($(PKG_GNULIB_BASE)))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_exitfail))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_fallocate-posix))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_mbszero))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_obstack))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_obstack-printf))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_printf-args))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_printf-frexp))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_printf-frexpl))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_printf-parse))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_tsearch))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_vasnprintf))' \
+ LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_xsize))' \
+ REPLACE_FCNTL=0 REPLACE_FREE=0 REPLACE_FSTAT=0 REPLACE_OPEN=0 \
+ REPLACE_OBSTACK=0 REPLACE_OBSTACK_PRINTF=0 \
+ bin_PROGRAMS='$(PKG_PROGRAMS)' EXEEXT=
+
+HOST_CPPFLAGS += "'-I$$$$(top_srcdir)/lib'"
+
ifeq ($(HOST_OS),Darwin)
HOST_CFLAGS += -I/opt/homebrew/include
endif
-HOST_CFLAGS += -Wno-error -fPIC
+HOST_CFLAGS += -Wno-error -fPIC -std=gnu17
HOST_CONFIGURE_ARGS += \
+ --enable-maintainer-mode \
--without-libintl-prefix \
--without-libiconv-prefix \
--disable-debuginfod \
@@ -71,22 +113,23 @@ ifeq ($(HOST_OS),Darwin)
HOST_CONFIGURE_ARGS += --disable-symbol-versioning
endif
-Hooks/HostConfigure/Pre := Host/Gnulib $(Hooks/HostConfigure/Pre)
-define Host/Gnulib
- $(STAGING_DIR_HOST)/bin/gnulib-tool $(PKG_GNULIB_ARGS) $(PKG_GNULIB_MODS);
- ln -sf ../lib/eu-config.h $(HOST_BUILD_DIR)/libgnu/;
-endef
+HOST_CONFIGURE_VARS += \
+ ac_cv_search_argp_parse=yes \
+ ac_cv_search_fts_close=yes \
+ ac_cv_search__obstack_free=yes \
+ ac_cv_buildid=yes
-define Host/Compile
- $(call Host/Compile/Default,SUBDIRS='$$$$(wildcard $(PKG_SUBDIRS))')
-endef
+Hooks/HostConfigure/Pre := Host/Gnulib/Prepare $(Hooks/HostConfigure/Pre)
+Hooks/HostCompile/Pre := Host/Gnulib/Compile $(Hooks/HostCompile/Pre)
-define Host/Install
- $(call Host/Compile/Default,install SUBDIRS='$$$$(wildcard $(PKG_SUBDIRS))')
+define Host/Configure
+ $(call Host/Configure/Default)
+ $(call Host/Uninstall)
endef
define Host/Uninstall
-$(call Host/Compile/Default,uninstall)
+ -$(call Host/Compile/Default,maintainer-clean) # Clean bootstrap files from the release
endef
$(eval $(call HostBuild))
diff --git a/tools/elfutils/patches/001-fix-backport-iquote-include.patch b/tools/elfutils/patches/001-fix-backport-iquote-include.patch
new file mode 100644
index 0000000000..62ed84dd27
--- /dev/null
+++ b/tools/elfutils/patches/001-fix-backport-iquote-include.patch
@@ -0,0 +1,12 @@
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -21,7 +21,8 @@ DEFS += $(YYDEBUG) -DDEBUGPRED=@DEBUGPRE
+ -DSRCDIR=\"$(shell cd $(srcdir);pwd)\" -DOBJDIR=\"$(shell pwd)\"
+
+ DEFAULT_INCLUDES =
+-AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
++AM_CPPFLAGS = -iquote . -iquote $(srcdir) -I$(top_srcdir)/lib \
++ -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+ -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \
+ -I$(srcdir)/../libdwfl -I$(srcdir)/../libasm -I../debuginfod
+
diff --git a/tools/elfutils/patches/011-backport-mips-support-strip.patch b/tools/elfutils/patches/011-backport-mips-support-strip.patch
new file mode 100644
index 0000000000..7ea9bedc1a
--- /dev/null
+++ b/tools/elfutils/patches/011-backport-mips-support-strip.patch
@@ -0,0 +1,230 @@
+In mips64 little-endian, r_info consists of four byte fields(contains
+three reloc types) and a 32-bit symbol index. In order to adapt
+GELF_R_SYM and GELF_R_TYPE, need convert raw data to get correct symbol
+index and type.
+
+ libelf/elf_getdata.c: Some eu-utils use read-mmap method to map file,
+so we need to malloc and memcpy raw data to avoid segment fault. After
+modification, the correct value are saved in the malloced memory not in
+process address space.
+ libelf/elf_updata.c: Because we converted the relocation info in mips
+order when we call elf_getdata.c, so we need to convert the modified data
+in original order bits before writing the data to the file.
+
+Signed-off-by: Ying Huang <ying.huang@oss.cipunited.com>
+---
+ libelf/elf_getdata.c | 132 ++++++++++++++++++++++++++++++++++++++++++-
+ libelf/elf_update.c | 53 +++++++++++++++++
+ 2 files changed, 183 insertions(+), 2 deletions(-)
+
+--- a/libelf/elf_getdata.c
++++ b/libelf/elf_getdata.c
+@@ -135,6 +135,119 @@ __libelf_data_type (GElf_Ehdr *ehdr, int
+
+ /* Convert the data in the current section. */
+ static void
++convert_data_for_mips64el (Elf_Scn *scn, int eclass,
++ int data, size_t size, Elf_Type type)
++{
++ /* Do we need to convert the data and/or adjust for alignment? */
++ if (data == MY_ELFDATA || type == ELF_T_BYTE)
++ {
++ /* In order to adapt macro GELF_R_SYM and GELF_R_TYPE on mips64, need to convert
++ relocation info(raw data). Some eu-utils use read-mmap method to map file, so
++ we need to malloc and memcpy raw data to avoid segment fault. After modification,
++ the correct value are saved in the malloced memory not in process address space. */
++ scn->data_base = malloc (size);
++ if (scn->data_base == NULL)
++ {
++ __libelf_seterrno (ELF_E_NOMEM);
++ return;
++ }
++
++ /* The copy will be appropriately aligned for direct access. */
++ memcpy (scn->data_base, scn->rawdata_base, size);
++ }
++ else
++ {
++ xfct_t fp;
++
++ scn->data_base = malloc (size);
++ if (scn->data_base == NULL)
++ {
++ __libelf_seterrno (ELF_E_NOMEM);
++ return;
++ }
++
++ /* Make sure the source is correctly aligned for the conversion
++ function to directly access the data elements. */
++ char *rawdata_source;
++ /* In order to adapt macro GELF_R_SYM and GELF_R_TYPE on mips64, need to convert
++ relocation info(raw data). Some eu-utils use read-mmap method to map file, so
++ we need to malloc and memcpy raw data to avoid segment fault. After modification,
++ the correct value are saved in the malloced memory not in process address space. */
++ rawdata_source = malloc (size);
++ if (rawdata_source == NULL)
++ {
++ __libelf_seterrno (ELF_E_NOMEM);
++ return;
++ }
++
++ /* The copy will be appropriately aligned for direct access. */
++ memcpy (rawdata_source, scn->rawdata_base, size);
++
++ /* Get the conversion function. */
++ fp = __elf_xfctstom[eclass - 1][type];
++
++ fp (scn->data_base, rawdata_source, size, 0);
++
++ if (rawdata_source != scn->rawdata_base)
++ free (rawdata_source);
++ }
++
++ scn->data_list.data.d.d_buf = scn->data_base;
++ scn->data_list.data.d.d_size = size;
++ scn->data_list.data.d.d_type = type;
++ scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
++ scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
++ scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
++
++ scn->data_list.data.s = scn;
++
++ /* In mips64 little-endian, r_info consists of four byte fields(contains
++ three reloc types) and a 32-bit symbol index. In order to adapt
++ GELF_R_SYM and GELF_R_TYPE, need to convert r_info to get correct symbol
++ index and type. */
++ /* references:
++ https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf
++ Page40 && Page41 */
++ GElf_Shdr shdr_mem;
++ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
++ if (shdr->sh_type == SHT_REL)
++ {
++ size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_REL, 1, EV_CURRENT);
++ int nentries = shdr->sh_size / sh_entsize;
++ for (int cnt = 0; cnt < nentries; ++cnt)
++ {
++ Elf_Data_Scn *data_scn = (Elf_Data_Scn *) &scn->data_list.data.d;
++ Elf64_Rel *value = &((Elf64_Rel *) data_scn->d.d_buf)[cnt];
++ Elf64_Xword info = value->r_info;
++ value->r_info = (((info & 0xffffffff) << 32)
++ | ((info >> 56) & 0xff)
++ | ((info >> 40) & 0xff00)
++ | ((info >> 24) & 0xff0000)
++ | ((info >> 8) & 0xff000000));
++ ((Elf64_Rel *) data_scn->d.d_buf)[cnt] = *value;
++ }
++ }
++ else if (shdr->sh_type == SHT_RELA)
++ {
++ size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_RELA, 1, EV_CURRENT);
++ int nentries = shdr->sh_size / sh_entsize;
++ for (int cnt = 0; cnt < nentries; cnt++)
++ {
++ Elf_Data_Scn *data_scn = (Elf_Data_Scn *) &scn->data_list.data.d;
++ Elf64_Rela *value = &((Elf64_Rela *) data_scn->d.d_buf)[cnt];
++ Elf64_Xword info = value->r_info;
++ value->r_info = (((info & 0xffffffff) << 32)
++ | ((info >> 56) & 0xff)
++ | ((info >> 40) & 0xff00)
++ | ((info >> 24) & 0xff0000)
++ | ((info >> 8) & 0xff000000));
++ ((Elf64_Rela *) data_scn->d.d_buf)[cnt] = *value;
++ }
++ }
++}
++
++/* Convert the data in the current section. */
++static void
+ convert_data (Elf_Scn *scn, int eclass,
+ int data, size_t size, Elf_Type type)
+ {
+@@ -451,8 +564,23 @@ __libelf_set_data_list_rdlock (Elf_Scn *
+ return;
+ }
+
+- /* Convert according to the version and the type. */
+- convert_data (scn, elf->class,
++ GElf_Shdr shdr_mem;
++ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
++ GElf_Ehdr ehdr_mem;
++ GElf_Ehdr *ehdr = gelf_getehdr (scn->elf, &ehdr_mem);
++ if (shdr != NULL && (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) &&
++ scn->elf->class == ELFCLASS64 && ehdr != NULL &&
++ ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
++ convert_data_for_mips64el (scn, elf->class,
++ (elf->class == ELFCLASS32
++ || (offsetof (struct Elf, state.elf32.ehdr)
++ == offsetof (struct Elf, state.elf64.ehdr))
++ ? elf->state.elf32.ehdr->e_ident[EI_DATA]
++ : elf->state.elf64.ehdr->e_ident[EI_DATA]),
++ scn->rawdata.d.d_size, scn->rawdata.d.d_type);
++ else
++ /* Convert according to the version and the type. */
++ convert_data (scn, elf->class,
+ (elf->class == ELFCLASS32
+ || (offsetof (struct Elf, state.elf32.ehdr)
+ == offsetof (struct Elf, state.elf64.ehdr))
+--- a/libelf/elf_update.c
++++ b/libelf/elf_update.c
+@@ -228,7 +228,60 @@ elf_update (Elf *elf, Elf_Cmd cmd)
+ size = -1;
+ }
+ else
++ {
++ /* Because we converted the relocation info in mips order when we call elf_getdata.c,
++ so we need to convert the modified data in original order bits before writing the
++ data to the file. */
++ Elf_Scn *scn = NULL;
++ while ((scn = elf_nextscn (elf, scn)) != NULL)
++ {
++ GElf_Shdr shdr_mem;
++ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
++ GElf_Ehdr ehdr_mem;
++ GElf_Ehdr *ehdr = gelf_getehdr (scn->elf, &ehdr_mem);
++ if (shdr != NULL && (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) &&
++ scn->elf->class == ELFCLASS64 &&
++ ehdr != NULL && ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
++ {
++ Elf_Data *d = elf_getdata (scn, NULL);
++ if (shdr->sh_type == SHT_REL)
++ {
++ size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_REL, 1, EV_CURRENT);
++ int nentries = shdr->sh_size / sh_entsize;
++ for (int cnt = 0; cnt < nentries; ++cnt)
++ {
++ Elf_Data_Scn *data_scn = (Elf_Data_Scn *) d;
++ Elf64_Rel *value = &((Elf64_Rel *) data_scn->d.d_buf)[cnt];
++ Elf64_Xword info = value->r_info;
++ value->r_info = (info >> 32
++ | ((info << 56) & 0xff00000000000000)
++ | ((info << 40) & 0xff000000000000)
++ | ((info << 24) & 0xff0000000000)
++ | ((info << 8) & 0xff00000000));
++ ((Elf64_Rel *) data_scn->d.d_buf)[cnt] = *value;
++ }
++ }
++ else if (shdr->sh_type == SHT_RELA)
++ {
++ size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_RELA, 1, EV_CURRENT);
++ int nentries = shdr->sh_size / sh_entsize;
++ for (int cnt = 0; cnt < nentries; cnt++)
++ {
++ Elf_Data_Scn *data_scn = (Elf_Data_Scn *) d;
++ Elf64_Rela *value = &((Elf64_Rela *) data_scn->d.d_buf)[cnt];
++ Elf64_Xword info = value->r_info;
++ value->r_info = (info >> 32
++ | ((info << 56) & 0xff00000000000000)
++ | ((info << 40) & 0xff000000000000)
++ | ((info << 24) & 0xff0000000000)
++ | ((info << 8) & 0xff00000000));
++ ((Elf64_Rela *) data_scn->d.d_buf)[cnt] = *value;
++ }
++ }
++ }
++ }
+ size = write_file (elf, size, change_bo, shnum);
++ }
+ }
+
+ out:
diff --git a/tools/elfutils/patches/012-backport-mips-support-readelf.patch b/tools/elfutils/patches/012-backport-mips-support-readelf.patch
new file mode 100644
index 0000000000..3a61acde6e
--- /dev/null
+++ b/tools/elfutils/patches/012-backport-mips-support-readelf.patch
@@ -0,0 +1,1079 @@
+-h: support show Flags name
+-S: support show mips related section type
+-r: support show type of Relocation section
+-w: can work and can show correct "strp" contents
+-l: support show mips related program header entry type
+-d: can show mips related Dynamic type name
+-a: support show complete Object attribute section ".gnu.attributes"
+
+Also add test/run-readelf-reloc.sh file to test new type2/type3 of
+src/readelf -r.
+
+Signed-off-by: Ying Huang <ying.huang@oss.cipunited.com>
+---
+ backends/Makefile.am | 2 +-
+ backends/mips_attrs.c | 140 +++++++++
+ backends/mips_init.c | 7 +
+ backends/mips_symbol.c | 571 +++++++++++++++++++++++++++++++++++++
+ libelf/libelfP.h | 1 +
+ src/readelf.c | 188 +++++++++---
+ tests/Makefile.am | 5 +-
+ tests/run-readelf-reloc.sh | 42 +++
+ 8 files changed, 907 insertions(+), 49 deletions(-)
+ create mode 100644 backends/mips_attrs.c
+ create mode 100755 tests/run-readelf-reloc.sh
+
+--- a/backends/Makefile.am
++++ b/backends/Makefile.am
+@@ -102,7 +102,7 @@ loongarch_SRCS = loongarch_init.c loonga
+
+ arc_SRCS = arc_init.c arc_symbol.c
+
+-mips_SRCS = mips_init.c mips_symbol.c mips_initreg.c \
++mips_SRCS = mips_init.c mips_symbol.c mips_attrs.c mips_initreg.c \
+ mips_cfi.c mips_unwind.c mips_regs.c mips_retval.c \
+ mips_corenote.c
+
+--- /dev/null
++++ b/backends/mips_attrs.c
+@@ -0,0 +1,140 @@
++/* Object attribute tags for MIPS.
++ Copyright (C) 2024 CIP United Inc.
++ This file is part of elfutils.
++
++ This file is free software; you can redistribute it and/or modify
++ it under the terms of either
++
++ * the GNU Lesser General Public License as published by the Free
++ Software Foundation; either version 3 of the License, or (at
++ your option) any later version
++
++ or
++
++ * the GNU General Public License as published by the Free
++ Software Foundation; either version 2 of the License, or (at
++ your option) any later version
++
++ or both in parallel, as here.
++
++ elfutils 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 copies of the GNU General Public License and
++ the GNU Lesser General Public License along with this program. If
++ not, see <http://www.gnu.org/licenses/>. */
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <string.h>
++#include <dwarf.h>
++
++#define BACKEND mips_
++#include "libebl_CPU.h"
++
++#define KNOWN_VALUES(...) do \
++ { \
++ static const char *table[] = { __VA_ARGS__ }; \
++ if (value < sizeof table / sizeof table[0]) \
++ *value_name = table[value]; \
++ } while (0)
++
++//copy gnu attr tags from binutils-2.34/elfcpp/mips.h
++/* Object attribute tags. */
++enum
++{
++ /* 0-3 are generic. */
++
++ /* Floating-point ABI used by this object file. */
++ Tag_GNU_MIPS_ABI_FP = 4,
++
++ /* MSA ABI used by this object file. */
++ Tag_GNU_MIPS_ABI_MSA = 8,
++};
++
++/* Object attribute values. */
++enum
++{
++ /* Values defined for Tag_GNU_MIPS_ABI_MSA. */
++
++ /* Not tagged or not using any ABIs affected by the differences. */
++ Val_GNU_MIPS_ABI_MSA_ANY = 0,
++
++ /* Using 128-bit MSA. */
++ Val_GNU_MIPS_ABI_MSA_128 = 1,
++};
++
++/* Object attribute values. */
++enum
++{
++ /* This is reserved for backward-compatibility with an earlier
++ implementation of the MIPS NaN2008 functionality. */
++ Val_GNU_MIPS_ABI_FP_NAN2008 = 8,
++};
++
++/* copy binutils-2.34/binutils/readelf.c display_mips_gnu_attribute */
++bool
++mips_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
++ const char *vendor, int tag, uint64_t value,
++ const char **tag_name, const char **value_name)
++{
++ if (!strcmp (vendor, "gnu"))
++ switch (tag)
++ {
++ case Tag_GNU_MIPS_ABI_FP:
++ *tag_name = "Tag_GNU_MIPS_ABI_FP";
++ switch (value)
++ {
++ case Val_GNU_MIPS_ABI_FP_ANY:
++ *value_name = "Hard or soft float";
++ return true;
++ case Val_GNU_MIPS_ABI_FP_DOUBLE:
++ *value_name = "Hard float (double precision)";
++ return true;
++ case Val_GNU_MIPS_ABI_FP_SINGLE:
++ *value_name = "Hard float (single precision)";
++ return true;
++ case Val_GNU_MIPS_ABI_FP_SOFT:
++ *value_name = "Soft float";
++ return true;
++ case Val_GNU_MIPS_ABI_FP_OLD_64:
++ *value_name = "Hard float (MIPS32r2 64-bit FPU 12 callee-saved)";
++ return true;
++ case Val_GNU_MIPS_ABI_FP_XX:
++ *value_name = "Hard float (32-bit CPU, Any FPU)";
++ return true;
++ case Val_GNU_MIPS_ABI_FP_64:
++ *value_name = "Hard float (32-bit CPU, 64-bit FPU)";
++ return true;
++ case Val_GNU_MIPS_ABI_FP_64A:
++ *value_name = "Hard float compat (32-bit CPU, 64-bit FPU)";
++ return true;
++ case Val_GNU_MIPS_ABI_FP_NAN2008:
++ *value_name = "NaN 2008 compatibility";
++ return true;
++ default:
++ return true;
++ }
++ return true;
++ case Tag_GNU_MIPS_ABI_MSA:
++ *tag_name = "Tag_GNU_MIPS_ABI_MSA";
++ switch (value)
++ {
++ case Val_GNU_MIPS_ABI_MSA_ANY:
++ *value_name = "Any MSA or not";
++ return true;
++ case Val_GNU_MIPS_ABI_MSA_128:
++ *value_name = "128-bit MSA";
++ return true;
++ default:
++ return true;
++ }
++ return true;
++ }
++
++ return false;
++}
+--- a/backends/mips_init.c
++++ b/backends/mips_init.c
+@@ -48,6 +48,13 @@ mips_init (Elf *elf __attribute__ ((unus
+ /* We handle it. */
+ mips_init_reloc (eh);
+ HOOK (eh, reloc_simple_type);
++ HOOK (eh, section_type_name);
++ HOOK (eh, machine_flag_check);
++ HOOK (eh, machine_flag_name);
++ HOOK (eh, segment_type_name);
++ HOOK (eh, dynamic_tag_check);
++ HOOK (eh, dynamic_tag_name);
++ HOOK (eh, check_object_attribute);
+ HOOK (eh, set_initial_registers_tid);
+ HOOK (eh, abi_cfi);
+ HOOK (eh, unwind);
+--- a/backends/mips_symbol.c
++++ b/backends/mips_symbol.c
+@@ -61,3 +61,574 @@ mips_reloc_simple_type (Ebl *ebl, int ty
+ return ELF_T_NUM;
+ }
+ }
++
++/* copy binutils-2.34/binutils/readelf.c get_mips_section_type_name */
++const char *
++mips_section_type_name (int type,
++ char *buf __attribute__ ((unused)),
++ size_t len __attribute__ ((unused)))
++{
++ switch (type)
++ {
++ case SHT_MIPS_LIBLIST:
++ return "MIPS_LIBLIST";
++ case SHT_MIPS_MSYM:
++ return "MIPS_MSYM";
++ case SHT_MIPS_CONFLICT:
++ return "MIPS_CONFLICT";
++ case SHT_MIPS_GPTAB:
++ return "MIPS_GPTAB";
++ case SHT_MIPS_UCODE:
++ return "MIPS_UCODE";
++ case SHT_MIPS_DEBUG:
++ return "MIPS_DEBUG";
++ case SHT_MIPS_REGINFO:
++ return "MIPS_REGINFO";
++ case SHT_MIPS_PACKAGE:
++ return "MIPS_PACKAGE";
++ case SHT_MIPS_PACKSYM:
++ return "MIPS_PACKSYM";
++ case SHT_MIPS_RELD:
++ return "MIPS_RELD";
++ case SHT_MIPS_IFACE:
++ return "MIPS_IFACE";
++ case SHT_MIPS_CONTENT:
++ return "MIPS_CONTENT";
++ case SHT_MIPS_OPTIONS:
++ return "MIPS_OPTIONS";
++ case SHT_MIPS_SHDR:
++ return "MIPS_SHDR";
++ case SHT_MIPS_FDESC:
++ return "MIPS_FDESC";
++ case SHT_MIPS_EXTSYM:
++ return "MIPS_EXTSYM";
++ case SHT_MIPS_DENSE:
++ return "MIPS_DENSE";
++ case SHT_MIPS_PDESC:
++ return "MIPS_PDESC";
++ case SHT_MIPS_LOCSYM:
++ return "MIPS_LOCSYM";
++ case SHT_MIPS_AUXSYM:
++ return "MIPS_AUXSYM";
++ case SHT_MIPS_OPTSYM:
++ return "MIPS_OPTSYM";
++ case SHT_MIPS_LOCSTR:
++ return "MIPS_LOCSTR";
++ case SHT_MIPS_LINE:
++ return "MIPS_LINE";
++ case SHT_MIPS_RFDESC:
++ return "MIPS_RFDESC";
++ case SHT_MIPS_DELTASYM:
++ return "MIPS_DELTASYM";
++ case SHT_MIPS_DELTAINST:
++ return "MIPS_DELTAINST";
++ case SHT_MIPS_DELTACLASS:
++ return "MIPS_DELTACLASS";
++ case SHT_MIPS_DWARF:
++ return "MIPS_DWARF";
++ case SHT_MIPS_DELTADECL:
++ return "MIPS_DELTADECL";
++ case SHT_MIPS_SYMBOL_LIB:
++ return "MIPS_SYMBOL_LIB";
++ case SHT_MIPS_EVENTS:
++ return "MIPS_EVENTS";
++ case SHT_MIPS_TRANSLATE:
++ return "MIPS_TRANSLATE";
++ case SHT_MIPS_PIXIE:
++ return "MIPS_PIXIE";
++ case SHT_MIPS_XLATE:
++ return "MIPS_XLATE";
++ case SHT_MIPS_XLATE_DEBUG:
++ return "MIPS_XLATE_DEBUG";
++ case SHT_MIPS_WHIRL:
++ return "MIPS_WHIRL";
++ case SHT_MIPS_EH_REGION:
++ return "MIPS_EH_REGION";
++ case SHT_MIPS_XLATE_OLD:
++ return "MIPS_XLATE_OLD";
++ case SHT_MIPS_PDR_EXCEPTION:
++ return "MIPS_PDR_EXCEPTION";
++ case SHT_MIPS_ABIFLAGS:
++ return "MIPS_ABIFLAGS";
++ case SHT_MIPS_XHASH:
++ return "MIPS_XHASH";
++ default:
++ break;
++ }
++ return NULL;
++}
++
++/* Check whether machine flags are valid. */
++bool
++mips_machine_flag_check (GElf_Word flags)
++{
++ if ((flags &~ (EF_MIPS_NOREORDER |
++ EF_MIPS_PIC |
++ EF_MIPS_CPIC |
++ EF_MIPS_UCODE |
++ EF_MIPS_ABI2 |
++ EF_MIPS_OPTIONS_FIRST |
++ EF_MIPS_32BITMODE |
++ EF_MIPS_NAN2008 |
++ EF_MIPS_FP64 |
++ EF_MIPS_ARCH_ASE_MDMX |
++ EF_MIPS_ARCH_ASE_M16 |
++ EF_MIPS_ARCH_ASE_MICROMIPS)) == 0)
++ return false;
++
++ switch(flags & EF_MIPS_MACH)
++ {
++ case EF_MIPS_MACH_3900:
++ case EF_MIPS_MACH_4010:
++ case EF_MIPS_MACH_4100:
++ case EF_MIPS_MACH_4111:
++ case EF_MIPS_MACH_4120:
++ case EF_MIPS_MACH_4650:
++ case EF_MIPS_MACH_5400:
++ case EF_MIPS_MACH_5500:
++ case EF_MIPS_MACH_5900:
++ case EF_MIPS_MACH_SB1:
++ case EF_MIPS_MACH_9000:
++ case EF_MIPS_MACH_LS2E:
++ case EF_MIPS_MACH_LS2F:
++ case EF_MIPS_MACH_GS464:
++ case EF_MIPS_MACH_GS464E:
++ case EF_MIPS_MACH_GS264E:
++ case EF_MIPS_MACH_OCTEON:
++ case EF_MIPS_MACH_OCTEON2:
++ case EF_MIPS_MACH_OCTEON3:
++ case EF_MIPS_MACH_XLR:
++ case EF_MIPS_MACH_IAMR2:
++ case 0:
++ break;
++ default:
++ return false;
++ }
++
++ switch ((flags & EF_MIPS_ABI))
++ {
++ case EF_MIPS_ABI_O32:
++ case EF_MIPS_ABI_O64:
++ case EF_MIPS_ABI_EABI32:
++ case EF_MIPS_ABI_EABI64:
++ case 0:
++ break;
++ default:
++ return false;
++ }
++
++ switch ((flags & EF_MIPS_ARCH))
++ {
++ case EF_MIPS_ARCH_1:
++ case EF_MIPS_ARCH_2:
++ case EF_MIPS_ARCH_3:
++ case EF_MIPS_ARCH_4:
++ case EF_MIPS_ARCH_5:
++ case EF_MIPS_ARCH_32:
++ case EF_MIPS_ARCH_32R2:
++ case EF_MIPS_ARCH_32R6:
++ case EF_MIPS_ARCH_64:
++ case EF_MIPS_ARCH_64R2:
++ case EF_MIPS_ARCH_64R6:
++ return true;
++ default:
++ return false;
++ }
++ return false;
++}
++
++/* copy binutils-2.34/binutils/readelf.c get_machine_flags */
++const char *
++mips_machine_flag_name (Elf64_Word orig __attribute__ ((unused)), Elf64_Word *flagref)
++{
++ if (*flagref & EF_MIPS_NOREORDER)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_NOREORDER);
++ return "noreorder";
++ }
++
++ if (*flagref & EF_MIPS_PIC)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_PIC);
++ return "pic";
++ }
++
++ if (*flagref & EF_MIPS_CPIC)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_CPIC);
++ return "cpic";
++ }
++
++ if (*flagref & EF_MIPS_UCODE)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_UCODE);
++ return "ugen_reserved";
++ }
++
++ if (*flagref & EF_MIPS_ABI2)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_ABI2);
++ return "abi2";
++ }
++
++ if (*flagref & EF_MIPS_OPTIONS_FIRST)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_OPTIONS_FIRST);
++ return "odk first";
++ }
++
++ if (*flagref & EF_MIPS_32BITMODE)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_32BITMODE);
++ return "32bitmode";
++ }
++
++ if (*flagref & EF_MIPS_NAN2008)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_NAN2008);
++ return "nan2008";
++ }
++
++ if (*flagref & EF_MIPS_FP64)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_FP64);
++ return "fp64";
++ }
++
++ switch (*flagref & EF_MIPS_MACH)
++ {
++ case EF_MIPS_MACH_3900:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_3900);
++ return "3900";
++ case EF_MIPS_MACH_4010:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4010);
++ return "4010";
++ case EF_MIPS_MACH_4100:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4100);
++ return "4100";
++ case EF_MIPS_MACH_4111:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4111);
++ return "4111";
++ case EF_MIPS_MACH_4120:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4120);
++ return "4120";
++ case EF_MIPS_MACH_4650:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4650);
++ return "4650";
++ case EF_MIPS_MACH_5400:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_5400);
++ return "5400";
++ case EF_MIPS_MACH_5500:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_5500);
++ return "5500";
++ case EF_MIPS_MACH_5900:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_5900);
++ return "5900";
++ case EF_MIPS_MACH_SB1:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_SB1);
++ return "sb1";
++ case EF_MIPS_MACH_9000:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_9000);
++ return "9000";
++ case EF_MIPS_MACH_LS2E:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_LS2E);
++ return "loongson-2e";
++ case EF_MIPS_MACH_LS2F:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_LS2F);
++ return "loongson-2f";
++ case EF_MIPS_MACH_GS464:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_GS464);
++ return "gs464";
++ case EF_MIPS_MACH_GS464E:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_GS464E);
++ return "gs464e";
++ case EF_MIPS_MACH_GS264E:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_GS264E);
++ return "gs264e";
++ case EF_MIPS_MACH_OCTEON:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_OCTEON);
++ return "octeon";
++ case EF_MIPS_MACH_OCTEON2:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_OCTEON2);
++ return "octeon2";
++ case EF_MIPS_MACH_OCTEON3:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_OCTEON3);
++ return "octeon3";
++ case EF_MIPS_MACH_XLR:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_XLR);
++ return "xlr";
++ case EF_MIPS_MACH_IAMR2:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH_IAMR2);
++ return "interaptiv-mr2";
++ case 0:
++ /* We simply ignore the field in this case to avoid confusion:
++ MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
++ extension. */
++ break;
++ default:
++ *flagref &= ~((Elf64_Word) EF_MIPS_MACH);
++ return "unknown CPU";
++ }
++ switch (*flagref & EF_MIPS_ABI)
++ {
++ case EF_MIPS_ABI_O32:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ABI_O32);
++ return "o32";
++ case EF_MIPS_ABI_O64:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ABI_O64);
++ return "o64";
++ case EF_MIPS_ABI_EABI32:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ABI_EABI32);
++ return "eabi32";
++ case EF_MIPS_ABI_EABI64:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ABI_EABI64);
++ return "eabi64";
++ case 0:
++ /* We simply ignore the field in this case to avoid confusion:
++ MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
++ This means it is likely to be an o32 file, but not for
++ sure. */
++ break;
++ default:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ABI);
++ return "unknown ABI";
++ }
++
++ if (*flagref & EF_MIPS_ARCH_ASE_MDMX)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_ASE_MDMX);
++ return "mdmx";
++ }
++
++ if (*flagref & EF_MIPS_ARCH_ASE_M16)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_ASE_M16);
++ return "mips16";
++ }
++
++ if (*flagref & EF_MIPS_ARCH_ASE_MICROMIPS)
++ {
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_ASE_MICROMIPS);
++ return "micromips";
++ }
++
++ switch (*flagref & EF_MIPS_ARCH)
++ {
++ case EF_MIPS_ARCH_1:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_1);
++ return "mips1";
++ case EF_MIPS_ARCH_2:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_2);
++ return "mips2";
++ case EF_MIPS_ARCH_3:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_3);
++ return "mips3";
++ case EF_MIPS_ARCH_4:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_4);
++ return "mips4";
++ case EF_MIPS_ARCH_5:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_5);
++ return "mips5";
++ case EF_MIPS_ARCH_32:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_32);
++ return "mips32";
++ case EF_MIPS_ARCH_32R2:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_32R2);
++ return "mips32r2";
++ case EF_MIPS_ARCH_32R6:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_32R6);
++ return "mips32r6";
++ case EF_MIPS_ARCH_64:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_64);
++ return "mips64";
++ case EF_MIPS_ARCH_64R2:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_64R2);
++ return "mips64r2";
++ case EF_MIPS_ARCH_64R6:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_64R6);
++ return "mips64r6";
++ default:
++ *flagref &= ~((Elf64_Word) EF_MIPS_ARCH);
++ return "unknown ISA";
++ }
++ return NULL;
++}
++
++/* copy binutils-2.34/binutils/readelf.c get_mips_segment_type */
++const char *
++mips_segment_type_name (int segment, char *buf __attribute__ ((unused)),
++ size_t len __attribute__ ((unused)))
++{
++ switch (segment)
++ {
++ case PT_MIPS_REGINFO:
++ return "REGINFO";
++ case PT_MIPS_RTPROC:
++ return "RTPROC";
++ case PT_MIPS_OPTIONS:
++ return "OPTIONS";
++ case PT_MIPS_ABIFLAGS:
++ return "ABIFLAGS";
++ default:
++ return NULL;
++ }
++}
++
++bool
++mips_dynamic_tag_check (int64_t tag)
++{
++ return ((tag &~ (DT_MIPS_RLD_VERSION
++ | DT_MIPS_TIME_STAMP
++ | DT_MIPS_ICHECKSUM
++ | DT_MIPS_IVERSION
++ | DT_MIPS_FLAGS
++ | DT_MIPS_BASE_ADDRESS
++ | DT_MIPS_MSYM
++ | DT_MIPS_CONFLICT
++ | DT_MIPS_LIBLIST
++ | DT_MIPS_LOCAL_GOTNO
++ | DT_MIPS_CONFLICTNO
++ | DT_MIPS_LIBLISTNO
++ | DT_MIPS_SYMTABNO
++ | DT_MIPS_UNREFEXTNO
++ | DT_MIPS_GOTSYM
++ | DT_MIPS_HIPAGENO
++ | DT_MIPS_RLD_MAP
++ | DT_MIPS_DELTA_CLASS
++ | DT_MIPS_DELTA_CLASS_NO
++ | DT_MIPS_DELTA_INSTANCE
++ | DT_MIPS_DELTA_INSTANCE_NO
++ | DT_MIPS_DELTA_RELOC
++ | DT_MIPS_DELTA_RELOC_NO
++ | DT_MIPS_DELTA_SYM
++ | DT_MIPS_DELTA_SYM_NO
++ | DT_MIPS_DELTA_CLASSSYM
++ | DT_MIPS_DELTA_CLASSSYM_NO
++ | DT_MIPS_CXX_FLAGS
++ | DT_MIPS_PIXIE_INIT
++ | DT_MIPS_SYMBOL_LIB
++ | DT_MIPS_LOCALPAGE_GOTIDX
++ | DT_MIPS_LOCAL_GOTIDX
++ | DT_MIPS_HIDDEN_GOTIDX
++ | DT_MIPS_PROTECTED_GOTIDX
++ | DT_MIPS_OPTIONS
++ | DT_MIPS_INTERFACE
++ | DT_MIPS_DYNSTR_ALIGN
++ | DT_MIPS_INTERFACE_SIZE
++ | DT_MIPS_RLD_TEXT_RESOLVE_ADDR
++ | DT_MIPS_PERF_SUFFIX
++ | DT_MIPS_COMPACT_SIZE
++ | DT_MIPS_GP_VALUE
++ | DT_MIPS_AUX_DYNAMIC
++ | DT_MIPS_PLTGOT
++ | DT_MIPS_RWPLT
++ | DT_MIPS_RLD_MAP_REL
++ | DT_MIPS_XHASH)) == 0);
++}
++
++/* copy binutils-2.34/binutils/readelf.c get_mips_dynamic_type*/
++const char *
++mips_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
++ size_t len __attribute__ ((unused)))
++{
++ switch (tag)
++ {
++ case DT_MIPS_RLD_VERSION:
++ return "MIPS_RLD_VERSION";
++ case DT_MIPS_TIME_STAMP:
++ return "MIPS_TIME_STAMP";
++ case DT_MIPS_ICHECKSUM:
++ return "MIPS_ICHECKSUM";
++ case DT_MIPS_IVERSION:
++ return "MIPS_IVERSION";
++ case DT_MIPS_FLAGS:
++ return "MIPS_FLAGS";
++ case DT_MIPS_BASE_ADDRESS:
++ return "MIPS_BASE_ADDRESS";
++ case DT_MIPS_MSYM:
++ return "MIPS_MSYM";
++ case DT_MIPS_CONFLICT:
++ return "MIPS_CONFLICT";
++ case DT_MIPS_LIBLIST:
++ return "MIPS_LIBLIST";
++ case DT_MIPS_LOCAL_GOTNO:
++ return "MIPS_LOCAL_GOTNO";
++ case DT_MIPS_CONFLICTNO:
++ return "MIPS_CONFLICTNO";
++ case DT_MIPS_LIBLISTNO:
++ return "MIPS_LIBLISTNO";
++ case DT_MIPS_SYMTABNO:
++ return "MIPS_SYMTABNO";
++ case DT_MIPS_UNREFEXTNO:
++ return "MIPS_UNREFEXTNO";
++ case DT_MIPS_GOTSYM:
++ return "MIPS_GOTSYM";
++ case DT_MIPS_HIPAGENO:
++ return "MIPS_HIPAGENO";
++ case DT_MIPS_RLD_MAP:
++ return "MIPS_RLD_MAP";
++ case DT_MIPS_RLD_MAP_REL:
++ return "MIPS_RLD_MAP_REL";
++ case DT_MIPS_DELTA_CLASS:
++ return "MIPS_DELTA_CLASS";
++ case DT_MIPS_DELTA_CLASS_NO:
++ return "MIPS_DELTA_CLASS_NO";
++ case DT_MIPS_DELTA_INSTANCE:
++ return "MIPS_DELTA_INSTANCE";
++ case DT_MIPS_DELTA_INSTANCE_NO:
++ return "MIPS_DELTA_INSTANCE_NO";
++ case DT_MIPS_DELTA_RELOC:
++ return "MIPS_DELTA_RELOC";
++ case DT_MIPS_DELTA_RELOC_NO:
++ return "MIPS_DELTA_RELOC_NO";
++ case DT_MIPS_DELTA_SYM:
++ return "MIPS_DELTA_SYM";
++ case DT_MIPS_DELTA_SYM_NO:
++ return "MIPS_DELTA_SYM_NO";
++ case DT_MIPS_DELTA_CLASSSYM:
++ return "MIPS_DELTA_CLASSSYM";
++ case DT_MIPS_DELTA_CLASSSYM_NO:
++ return "MIPS_DELTA_CLASSSYM_NO";
++ case DT_MIPS_CXX_FLAGS:
++ return "MIPS_CXX_FLAGS";
++ case DT_MIPS_PIXIE_INIT:
++ return "MIPS_PIXIE_INIT";
++ case DT_MIPS_SYMBOL_LIB:
++ return "MIPS_SYMBOL_LIB";
++ case DT_MIPS_LOCALPAGE_GOTIDX:
++ return "MIPS_LOCALPAGE_GOTIDX";
++ case DT_MIPS_LOCAL_GOTIDX:
++ return "MIPS_LOCAL_GOTIDX";
++ case DT_MIPS_HIDDEN_GOTIDX:
++ return "MIPS_HIDDEN_GOTIDX";
++ case DT_MIPS_PROTECTED_GOTIDX:
++ return "MIPS_PROTECTED_GOTIDX";
++ case DT_MIPS_OPTIONS:
++ return "MIPS_OPTIONS";
++ case DT_MIPS_INTERFACE:
++ return "MIPS_INTERFACE";
++ case DT_MIPS_DYNSTR_ALIGN:
++ return "MIPS_DYNSTR_ALIGN";
++ case DT_MIPS_INTERFACE_SIZE:
++ return "MIPS_INTERFACE_SIZE";
++ case DT_MIPS_RLD_TEXT_RESOLVE_ADDR:
++ return "MIPS_RLD_TEXT_RESOLVE_ADDR";
++ case DT_MIPS_PERF_SUFFIX:
++ return "MIPS_PERF_SUFFIX";
++ case DT_MIPS_COMPACT_SIZE:
++ return "MIPS_COMPACT_SIZE";
++ case DT_MIPS_GP_VALUE:
++ return "MIPS_GP_VALUE";
++ case DT_MIPS_AUX_DYNAMIC:
++ return "MIPS_AUX_DYNAMIC";
++ case DT_MIPS_PLTGOT:
++ return "MIPS_PLTGOT";
++ case DT_MIPS_RWPLT:
++ return "MIPS_RWPLT";
++ case DT_MIPS_XHASH:
++ return "MIPS_XHASH";
++ default:
++ return NULL;
++ }
++ return NULL;
++}
+--- a/libelf/libelfP.h
++++ b/libelf/libelfP.h
+@@ -624,4 +624,5 @@ extern void __libelf_reset_rawdata (Elf_
+ #define ELF64_MIPS_R_TYPE1(i) ((i) & 0xff)
+ #define ELF64_MIPS_R_TYPE2(i) (((i) >> 8) & 0xff)
+ #define ELF64_MIPS_R_TYPE3(i) (((i) >> 16) & 0xff)
++#define is_debug_section_type(type) (type == SHT_PROGBITS || type == SHT_MIPS_DWARF)
+ #endif /* libelfP.h */
+--- a/src/readelf.c
++++ b/src/readelf.c
+@@ -2219,17 +2219,41 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *
+ (long int) GELF_R_SYM (rel->r_info));
+ }
+ else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
+- printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
+- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+- likely (ebl_reloc_type_check (ebl,
+- GELF_R_TYPE (rel->r_info)))
+- /* Avoid the leading R_ which isn't carrying any
+- information. */
+- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+- buf, sizeof (buf)) + 2
+- : _("<INVALID RELOC>"),
+- class == ELFCLASS32 ? 10 : 18, sym->st_value,
+- elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
++ {
++ unsigned long inf = rel->r_info;
++ printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
++ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
++ likely (ebl_reloc_type_check (ebl,
++ GELF_R_TYPE (rel->r_info)))
++ /* Avoid the leading R_ which isn't carrying any
++ information. */
++ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
++ buf, sizeof (buf)) + 2
++ : _("<INVALID RELOC>"),
++ class == ELFCLASS32 ? 10 : 18, sym->st_value,
++ elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
++
++ /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753 */
++ if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
++ {
++ unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
++ unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
++ const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
++ const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
++ printf(" Type2: ");
++ if (rtype2 == NULL)
++ printf (_("unrecognized: %lx"), (unsigned long) type2 & 0xffffffff);
++ else
++ printf ("%s", rtype2);
++
++ printf ("\n Type3: ");
++ if (rtype3 == NULL)
++ printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff);
++ else
++ printf ("%s", rtype3);
++ printf("\n");
++ }
++ }
+ else
+ {
+ /* This is a relocation against a STT_SECTION symbol. */
+@@ -2253,16 +2277,40 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *
+ (long int) (sym->st_shndx == SHN_XINDEX
+ ? xndx : sym->st_shndx));
+ else
+- printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
+- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+- ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+- /* Avoid the leading R_ which isn't carrying any
+- information. */
+- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+- buf, sizeof (buf)) + 2
+- : _("<INVALID RELOC>"),
+- class == ELFCLASS32 ? 10 : 18, sym->st_value,
+- elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
++ {
++ unsigned long inf = rel->r_info;
++ printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
++ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
++ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
++ /* Avoid the leading R_ which isn't carrying any
++ information. */
++ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
++ buf, sizeof (buf)) + 2
++ : _("<INVALID RELOC>"),
++ class == ELFCLASS32 ? 10 : 18, sym->st_value,
++ elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
++
++ /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753 */
++ if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
++ {
++ unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
++ unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
++ const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
++ const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
++ printf(" Type2: ");
++ if (rtype2 == NULL)
++ printf (_("unrecognized: %lx"), (unsigned long) type2 & 0xffffffff);
++ else
++ printf ("%s", rtype2);
++
++ printf ("\n Type3: ");
++ if (rtype3 == NULL)
++ printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff);
++ else
++ printf ("%s", rtype3);
++ printf("\n");
++ }
++ }
+ }
+ }
+ }
+@@ -2410,19 +2458,43 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr
+ (long int) GELF_R_SYM (rel->r_info));
+ }
+ else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
+- printf ("\
++ {
++ unsigned long inf = rel->r_info;
++ printf ("\
+ %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
+- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+- likely (ebl_reloc_type_check (ebl,
+- GELF_R_TYPE (rel->r_info)))
+- /* Avoid the leading R_ which isn't carrying any
+- information. */
+- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+- buf, sizeof (buf)) + 2
+- : _("<INVALID RELOC>"),
+- class == ELFCLASS32 ? 10 : 18, sym->st_value,
+- rel->r_addend,
+- elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
++ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
++ likely (ebl_reloc_type_check (ebl,
++ GELF_R_TYPE (rel->r_info)))
++ /* Avoid the leading R_ which isn't carrying any
++ information. */
++ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
++ buf, sizeof (buf)) + 2
++ : _("<INVALID RELOC>"),
++ class == ELFCLASS32 ? 10 : 18, sym->st_value,
++ rel->r_addend,
++ elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
++
++ /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753 */
++ if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
++ {
++ unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
++ unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
++ const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
++ const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
++ printf(" Type2: ");
++ if (rtype2 == NULL)
++ printf (_("unrecognized: %lx"), (unsigned long) type2 & 0xffffffff);
++ else
++ printf ("%s", rtype2);
++
++ printf ("\n Type3: ");
++ if (rtype3 == NULL)
++ printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff);
++ else
++ printf ("%s", rtype3);
++ printf("\n");
++ }
++ }
+ else
+ {
+ /* This is a relocation against a STT_SECTION symbol. */
+@@ -2446,18 +2518,42 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr
+ (long int) (sym->st_shndx == SHN_XINDEX
+ ? xndx : sym->st_shndx));
+ else
+- printf ("\
++ {
++ unsigned long inf = rel->r_info;
++ printf ("\
+ %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
+- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+- ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+- /* Avoid the leading R_ which isn't carrying any
+- information. */
+- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+- buf, sizeof (buf)) + 2
+- : _("<INVALID RELOC>"),
+- class == ELFCLASS32 ? 10 : 18, sym->st_value,
+- rel->r_addend,
+- elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
++ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
++ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
++ /* Avoid the leading R_ which isn't carrying any
++ information. */
++ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
++ buf, sizeof (buf)) + 2
++ : _("<INVALID RELOC>"),
++ class == ELFCLASS32 ? 10 : 18, sym->st_value,
++ rel->r_addend,
++ elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
++
++ /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753 */
++ if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
++ {
++ unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
++ unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
++ const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
++ const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
++ printf(" Type2: ");
++ if (rtype2 == NULL)
++ printf (_("unrecognized: %-7lx"), (unsigned long) type2 & 0xffffffff);
++ else
++ printf ("%s", rtype2);
++
++ printf ("\n Type3: ");
++ if (rtype3 == NULL)
++ printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff);
++ else
++ printf ("%s", rtype3);
++ printf("\n");
++ }
++ }
+ }
+ }
+ }
+@@ -12037,7 +12133,7 @@ print_debug (Dwfl_Module *dwflmod, Ebl *
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+- if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
++ if (shdr != NULL && is_debug_section_type(shdr->sh_type))
+ {
+ const char *name = elf_strptr (ebl->elf, shstrndx,
+ shdr->sh_name);
+@@ -12067,7 +12163,7 @@ print_debug (Dwfl_Module *dwflmod, Ebl *
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+- if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
++ if (shdr != NULL && is_debug_section_type(shdr->sh_type))
+ {
+ static const struct
+ {
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -216,7 +216,7 @@ TESTS = run-arextract.sh run-arsymtest.s
+ run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \
+ run-readelf-dw-form-indirect.sh run-strip-largealign.sh \
+ run-readelf-Dd.sh run-dwfl-core-noncontig.sh run-cu-dwp-section-info.sh \
+- run-declfiles.sh \
++ run-declfiles.sh run-readelf-reloc.sh \
+ run-sysroot.sh
+
+ if !BIARCH
+@@ -684,7 +684,7 @@ EXTRA_DIST = run-arextract.sh run-arsymt
+ testfile-dwp-4-cu-index-overflow.bz2 \
+ testfile-dwp-4-cu-index-overflow.dwp.bz2 \
+ testfile-dwp-cu-index-overflow.source \
+- testfile-define-file.bz2 \
++ run-readelf-reloc.sh testfile-define-file.bz2 \
+ testfile-sysroot.tar.bz2 run-sysroot.sh run-debuginfod-seekable.sh
+
+
+--- /dev/null
++++ b/tests/run-readelf-reloc.sh
+@@ -0,0 +1,42 @@
++#! /bin/bash
++# Copyright (C) 2024 CIP United Inc.
++# This file is part of elfutils.
++#
++# This file 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.
++#
++# elfutils 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 this program. If not, see <http://www.gnu.org/licenses/>.
++
++. $srcdir/test-subr.sh
++
++tempfiles test-readelf-h.txt test-readelf-reloc.txt
++testrun ${abs_top_builddir}/src/readelf -h ${abs_top_builddir}/src/strip.o > test-readelf-h.txt
++machine=`cat test-readelf-h.txt | grep Machine`
++class=`cat test-readelf-h.txt | grep Class`
++endian=`cat test-readelf-h.txt | grep Data`
++if [[ "$machine" == *MIPS* && "$class" == *ELF64 && "$endian" == *little* ]]; then
++testrun ${abs_top_builddir}/src/readelf -r ${abs_top_builddir}/src/strip.o | head -n 12 | tail -n 10 > test-readelf-reloc.txt
++
++testrun_compare cat test-readelf-reloc.txt << EOF
++ Offset Type Value Addend Name
++ 0x0000000000000008 MIPS_GPREL16 000000000000000000 +0 .text
++ Type2: MIPS_SUB
++ Type3: MIPS_HI16
++ 0x0000000000000010 MIPS_GPREL16 000000000000000000 +0 .text
++ Type2: MIPS_SUB
++ Type3: MIPS_LO16
++ 0x0000000000000014 MIPS_CALL16 000000000000000000 +0 gelf_getehdr
++ Type2: MIPS_NONE
++ Type3: MIPS_NONE
++EOF
++fi
++
++exit 0
diff --git a/tools/elfutils/patches/013-backport-mips-support-elflint.patch b/tools/elfutils/patches/013-backport-mips-support-elflint.patch
new file mode 100644
index 0000000000..2ef9304bd1
--- /dev/null
+++ b/tools/elfutils/patches/013-backport-mips-support-elflint.patch
@@ -0,0 +1,157 @@
+The errors were:
+$ src/elflint --gnu src/nm
+section [ 2] '.MIPS.options' contains unknown flag(s) 0x8000000
+section [ 7] '.dynsym': symbol 165 (_DYNAMIC_LINKING): non-local section symbol
+section [24] '.got' contains invalid processor-specific flag(s) 0x10000000
+section [25] '.sdata' contains invalid processor-specific flag(s) 0x10000000
+section [29] '.debug_aranges' has wrong type: expected PROGBITS, is MIPS_DWARF
+section [30] '.debug_info' has wrong type: expected PROGBITS, is MIPS_DWARF
+section [31] '.debug_abbrev' has wrong type: expected PROGBITS, is MIPS_DWARF
+section [32] '.debug_line' has wrong type: expected PROGBITS, is MIPS_DWARF
+section [33] '.debug_frame' has wrong type: expected PROGBITS, is MIPS_DWARF
+section [34] '.debug_str' has wrong type: expected PROGBITS, is MIPS_DWARF
+section [35] '.debug_loc' has wrong type: expected PROGBITS, is MIPS_DWARF
+section [36] '.debug_ranges' has wrong type: expected PROGBITS, is MIPS_DWARF
+section [38] '.symtab': symbol 785 (_gp): st_value out of bounds
+section [38] '.symtab': symbol 910 (_fbss): st_value out of bounds
+section [38] '.symtab': symbol 1051 (_DYNAMIC_LINKING): non-local section symbol
+
+After fixing:
+$ src/elflint --gnu src/nm
+No errors
+
+Signed-off-by: Ying Huang <ying.huang@oss.cipunited.com>
+---
+ backends/mips_init.c | 3 +++
+ backends/mips_symbol.c | 37 +++++++++++++++++++++++++++++++++++++
+ src/elflint.c | 26 +++++++++++++++++++++-----
+ 3 files changed, 61 insertions(+), 5 deletions(-)
+
+--- a/backends/mips_init.c
++++ b/backends/mips_init.c
+@@ -51,10 +51,13 @@ mips_init (Elf *elf __attribute__ ((unus
+ HOOK (eh, section_type_name);
+ HOOK (eh, machine_flag_check);
+ HOOK (eh, machine_flag_name);
++ HOOK (eh, machine_section_flag_check);
+ HOOK (eh, segment_type_name);
+ HOOK (eh, dynamic_tag_check);
+ HOOK (eh, dynamic_tag_name);
+ HOOK (eh, check_object_attribute);
++ HOOK (eh, check_special_symbol);
++ HOOK (eh, check_reloc_target_type);
+ HOOK (eh, set_initial_registers_tid);
+ HOOK (eh, abi_cfi);
+ HOOK (eh, unwind);
+--- a/backends/mips_symbol.c
++++ b/backends/mips_symbol.c
+@@ -158,6 +158,43 @@ mips_section_type_name (int type,
+ return NULL;
+ }
+
++bool
++mips_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), Elf64_Word sh_type)
++{
++ return (sh_type == SHT_MIPS_DWARF);
++}
++
++/* Check whether given symbol's st_value and st_size are OK despite failing
++ normal checks. */
++bool
++mips_check_special_symbol (Elf *elf,
++ const GElf_Sym *sym __attribute__ ((unused)),
++ const char *name __attribute__ ((unused)),
++ const GElf_Shdr *destshdr)
++{
++ size_t shstrndx;
++ if (elf_getshdrstrndx (elf, &shstrndx) != 0)
++ return false;
++ const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name);
++ if (sname == NULL)
++ return false;
++ return (strcmp (sname, ".got") == 0 || strcmp (sname, ".bss") == 0);
++}
++
++/* Check whether SHF_MASKPROC flags are valid. */
++bool
++mips_machine_section_flag_check (GElf_Xword sh_flags)
++{
++ return ((sh_flags &~ (SHF_MIPS_GPREL |
++ SHF_MIPS_MERGE |
++ SHF_MIPS_ADDR |
++ SHF_MIPS_STRINGS |
++ SHF_MIPS_NOSTRIP |
++ SHF_MIPS_LOCAL |
++ SHF_MIPS_NAMES |
++ SHF_MIPS_NODUPE)) == 0);
++}
++
+ /* Check whether machine flags are valid. */
+ bool
+ mips_machine_flag_check (GElf_Word flags)
+--- a/src/elflint.c
++++ b/src/elflint.c
+@@ -936,7 +936,9 @@ section [%2d] '%s': symbol %zu (%s): non
+ }
+
+ if (GELF_ST_TYPE (sym->st_info) == STT_SECTION
+- && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
++ && GELF_ST_BIND (sym->st_info) != STB_LOCAL
++ && ehdr->e_machine != EM_MIPS
++ && strcmp (name, "_DYNAMIC_LINKING") != 0)
+ ERROR (_("\
+ section [%2d] '%s': symbol %zu (%s): non-local section symbol\n"),
+ idx, section_name (ebl, idx), cnt, name);
+@@ -3829,6 +3831,10 @@ cannot get section header for section [%
+ && ebl_bss_plt_p (ebl))
+ good_type = SHT_NOBITS;
+
++ if (ehdr->e_machine == EM_MIPS
++ && (strstr(special_sections[s].name, ".debug") != NULL))
++ good_type = SHT_MIPS_DWARF;
++
+ /* In a debuginfo file, any normal section can be SHT_NOBITS.
+ This is only invalid for DWARF sections and .shstrtab. */
+ if (shdr->sh_type != good_type
+@@ -3989,12 +3995,21 @@ section [%2zu] '%s': size not multiple o
+ ERROR (_("section [%2zu] '%s'"
+ " contains invalid processor-specific flag(s)"
+ " %#" PRIx64 "\n"),
+- cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC);
++ cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC);
+ sh_flags &= ~(GElf_Xword) SHF_MASKPROC;
+ }
+ if (sh_flags & SHF_MASKOS)
+- if (gnuld)
+- sh_flags &= ~(GElf_Xword) SHF_GNU_RETAIN;
++ {
++ if (gnuld)
++ sh_flags &= ~(GElf_Xword) SHF_GNU_RETAIN;
++ if (!ebl_machine_section_flag_check (ebl,
++ sh_flags & SHF_MASKOS))
++ ERROR (_("section [%2zu] '%s'"
++ " contains invalid os-specific flag(s)"
++ " %#" PRIx64 "\n"),
++ cnt, section_name (ebl, cnt), sh_flags & SHF_MASKOS);
++ sh_flags &= ~(GElf_Xword) SHF_MASKOS;
++ }
+ if (sh_flags != 0)
+ ERROR (_("section [%2zu] '%s' contains unknown flag(s)"
+ " %#" PRIx64 "\n"),
+@@ -4060,6 +4075,7 @@ section [%2zu] '%s': merge flag set but
+ switch (shdr->sh_type)
+ {
+ case SHT_PROGBITS:
++ case SHT_MIPS_DWARF:
+ break;
+
+ case SHT_NOBITS:
+@@ -4717,7 +4733,7 @@ program header offset in ELF header and
+ if (shdr != NULL
+ && ((is_debuginfo && shdr->sh_type == SHT_NOBITS)
+ || (! is_debuginfo
+- && (shdr->sh_type == SHT_PROGBITS
++ && (is_debug_section_type(shdr->sh_type)
+ || shdr->sh_type == SHT_X86_64_UNWIND)))
+ && elf_strptr (ebl->elf, shstrndx, shdr->sh_name) != NULL
+ && ! strcmp (".eh_frame_hdr",
diff --git a/tools/elfutils/patches/100-portability.patch b/tools/elfutils/patches/100-portability.patch
index 6f7564731b..a82cd69ba2 100644
--- a/tools/elfutils/patches/100-portability.patch
+++ b/tools/elfutils/patches/100-portability.patch
@@ -1,135 +1,42 @@
--- a/configure.ac
+++ b/configure.ac
-@@ -20,6 +20,7 @@ dnl You should have received a copy of
- dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
- AC_INIT([elfutils],[0.191],[https://sourceware.org/bugzilla],[elfutils],[http://elfutils.org/])
-
-+AC_CONFIG_MACRO_DIRS([m4])
- dnl Workaround for older autoconf < 2.64
- m4_ifndef([AC_PACKAGE_URL],
- [AC_DEFINE([PACKAGE_URL], ["http://elfutils.org/"],
-@@ -43,16 +44,17 @@ elif test "x$program_prefix" = "x"; then
- fi
+@@ -44,6 +44,7 @@ fi
AC_CONFIG_AUX_DIR([config])
--AC_CONFIG_FILES([config/Makefile])
-+AC_CONFIG_FILES([config/Makefile libgnu/Makefile])
+ AC_CONFIG_FILES([config/Makefile])
++AC_CONFIG_FILES([libgnu/Makefile])
AC_COPYRIGHT([Copyright (C) 1996-2024 The elfutils developers.])
--AC_PREREQ(2.63) dnl Minimum Autoconf version required.
-+AC_PREREQ(2.64) dnl Minimum Autoconf version required.
-
- dnl We use GNU make extensions; automake 1.10 defaults to -Wportability.
- AM_INIT_AUTOMAKE([gnits 1.11 -Wno-portability dist-bzip2 no-dist-gzip parallel-tests])
- AM_MAINTAINER_MODE
-
- AM_SILENT_RULES([yes])
-+AC_USE_SYSTEM_EXTENSIONS()
+ AC_PREREQ(2.63) dnl Minimum Autoconf version required.
+@@ -88,11 +89,14 @@ AS_IF([test "$use_locks" = yes],
- AC_CONFIG_SRCDIR([libelf/libelf.h])
- AC_CONFIG_FILES([Makefile])
-@@ -89,12 +91,14 @@ AS_IF([test "$use_locks" = yes],
AH_TEMPLATE([USE_LOCKS], [Defined if libraries should be thread-safe.])
++AC_USE_SYSTEM_EXTENSIONS()
++
m4_version_prereq([2.70], [AC_PROG_CC], [AC_PROG_CC_C99])
-+gl_EARLY
-+gl_INIT
AC_PROG_CXX
--AC_PROG_RANLIB
+ AC_PROG_RANLIB
AC_PROG_YACC
AC_PROG_LEX([noyywrap])
++gl_EARLY
# Only available since automake 1.12
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
-+LT_INIT()
AC_CHECK_TOOL([READELF], [readelf])
- AC_CHECK_TOOL([NM], [nm])
-
-@@ -195,7 +199,6 @@ AC_CACHE_CHECK([whether the compiler gen
- AC_LINK_IFELSE([AC_LANG_PROGRAM()],[ac_cv_buildid=yes; $READELF -n conftest$EXEEXT | grep -q NT_GNU_BUILD_ID || ac_cv_buildid=no],AC_MSG_FAILURE([unexpected compile failure]))])
- if test "$ac_cv_buildid" = "no"; then
- AC_MSG_WARN([compiler doesn't generate build-id by default])
-- LDFLAGS="$LDFLAGS -Wl,--build-id"
- fi
-
- ZRELRO_LDFLAGS="-Wl,-z,relro"
-@@ -635,36 +638,6 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],
+@@ -646,6 +650,8 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],
CFLAGS="$old_CFLAGS"])
AS_IF([test "x$ac_cv_fno_addrsig" = "xyes"], CFLAGS="$CFLAGS -fno-addrsig")
--saved_LIBS="$LIBS"
--AC_SEARCH_LIBS([argp_parse], [argp])
--LIBS="$saved_LIBS"
--case "$ac_cv_search_argp_parse" in
-- no) AC_MSG_FAILURE([failed to find argp_parse]) ;;
-- -l*) argp_LDADD="$ac_cv_search_argp_parse" ;;
-- *) argp_LDADD= ;;
--esac
--AC_SUBST([argp_LDADD])
--
--saved_LIBS="$LIBS"
--AC_SEARCH_LIBS([fts_close], [fts])
--LIBS="$saved_LIBS"
--case "$ac_cv_search_fts_close" in
-- no) AC_MSG_FAILURE([failed to find fts_close]) ;;
-- -l*) fts_LIBS="$ac_cv_search_fts_close" ;;
-- *) fts_LIBS= ;;
--esac
--AC_SUBST([fts_LIBS])
--
--saved_LIBS="$LIBS"
--AC_SEARCH_LIBS([_obstack_free], [obstack])
--LIBS="$saved_LIBS"
--case "$ac_cv_search__obstack_free" in
-- no) AC_MSG_FAILURE([failed to find _obstack_free]) ;;
-- -l*) obstack_LIBS="$ac_cv_search__obstack_free" ;;
-- *) obstack_LIBS= ;;
--esac
--AC_SUBST([obstack_LIBS])
--
- dnl The directories with content.
-
- dnl Documentation.
---- a/libelf/elf_update.c
-+++ b/libelf/elf_update.c
-@@ -37,6 +37,33 @@
-
- #include "libelfP.h"
-
-+#include "elf_fill.c"
++gl_INIT
+
-+#ifdef __APPLE__
-+static int posix_fallocate(int fd, off_t offset, off_t len)
-+{
-+ off_t c_test;
-+ int ret;
-+ if (!__builtin_saddll_overflow(offset, len, &c_test)) {
-+ fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, offset + len, 0};
-+ // Try to get a continuous chunk of disk space
-+ ret = fcntl(fd, F_PREALLOCATE, &store);
-+ if (ret < 0) {
-+ // OK, perhaps we are too fragmented, allocate non-continuous
-+ store.fst_flags = F_ALLOCATEALL;
-+ ret = fcntl(fd, F_PREALLOCATE, &store);
-+ if (ret < 0) {
-+ return ret;
-+ }
-+ }
-+ ret = ftruncate(fd, offset + len);
-+ } else {
-+ // offset+len would overflow.
-+ ret = -1;
-+ }
-+ return ret;
-+}
-+#endif
-
- static int64_t
- write_file (Elf *elf, int64_t size, int change_bo, size_t shnum)
+ saved_LIBS="$LIBS"
+ AC_SEARCH_LIBS([argp_parse], [argp])
+ LIBS="$saved_LIBS"
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
-@@ -59,14 +59,18 @@
- # define once(once_control, init_routine) init_routine()
- #endif /* USE_LOCKS */
+@@ -31,14 +31,19 @@
+
+ #include "locks.h"
-#include <libintl.h>
+#include <gettext.h>
@@ -138,8 +45,9 @@
#define _(Str) dgettext ("elfutils", Str)
/* Compiler-specific definitions. */
++#define __PRAGMA(str) _Pragma (#str)
+#ifdef __APPLE__
-+#define strong_alias(name, aliasname)
++#define strong_alias(name, aliasname) __PRAGMA(weak aliasname = name)
+#else
#define strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
@@ -147,20 +55,16 @@
#ifdef __i386__
# define internal_function __attribute__ ((regparm (3), stdcall))
-@@ -77,12 +81,7 @@
+@@ -49,7 +54,7 @@
#define internal_strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name))) internal_function;
-#ifdef HAVE_VISIBILITY
--#define attribute_hidden \
-- __attribute__ ((visibility ("hidden")))
--#else
- #define attribute_hidden /* empty */
--#endif
-
- #ifdef HAVE_GCC_STRUCT
- #define attribute_packed \
-@@ -166,7 +165,7 @@ asm (".section predict_data, \"aw\"; .pr
++#if defined(HAVE_VISIBILITY) && !defined(__APPLE__)
+ #define attribute_hidden \
+ __attribute__ ((visibility ("hidden")))
+ #else
+@@ -138,7 +143,7 @@ asm (".section predict_data, \"aw\"; .pr
#endif
/* Avoid PLT entries. */
@@ -169,79 +73,6 @@
# define INTUSE(name) _INTUSE(name)
# define _INTUSE(name) __##name##_internal
# define INTDEF(name) _INTDEF(name)
---- a/config/eu.am
-+++ b/config/eu.am
-@@ -31,7 +31,7 @@
- ##
-
- DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"'
--AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I..
-+AM_CPPFLAGS = -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu -I. -I$(srcdir) -I$(top_srcdir)/lib -I..
-
- # Drop the 'u' flag that automake adds by default. It is incompatible
- # with deterministic archives.
---- a/libelf/Makefile.am
-+++ b/libelf/Makefile.am
-@@ -34,9 +34,7 @@ endif
-
- VERSION = 1
-
--lib_LIBRARIES = libelf.a
--noinst_LIBRARIES = libelf_pic.a
--noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so)
-+lib_LTLIBRARIES = libelf.la
- include_HEADERS = libelf.h gelf.h nlist.h
-
- noinst_HEADERS = abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \
-@@ -51,7 +49,8 @@ endif
-
- pkginclude_HEADERS = elf-knowledge.h
-
--libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
-+libelf_la_LIBADD = ../libgnu/libgnu.la ../lib/libeu.la -lz $(zstd_LIBS) -lpthread
-+libelf_la_SOURCES = elf_version.c elf_hash.c elf_error.c \
- elf_begin.c elf_next.c elf_rand.c elf_end.c elf_kind.c \
- gelf_getclass.c elf_getbase.c elf_getident.c \
- elf32_fsize.c elf64_fsize.c gelf_fsize.c \
-@@ -102,37 +101,9 @@ libelf_a_SOURCES = elf_version.c elf_has
- elf32_getchdr.c elf64_getchdr.c gelf_getchdr.c \
- elf_compress.c elf_compress_gnu.c
-
--libelf_pic_a_SOURCES =
--am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os)
--
--libelf_so_DEPS = ../lib/libeu.a
--libelf_so_LDLIBS = $(libelf_so_DEPS) -lz $(zstd_LIBS)
--if USE_LOCKS
--libelf_so_LDLIBS += -lpthread
--endif
--
--libelf_so_LIBS = libelf_pic.a
--libelf.so: $(srcdir)/libelf.map $(libelf_so_LIBS) $(libelf_so_DEPS)
-- $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-- -Wl,--soname,$@.$(VERSION) \
-- -Wl,--version-script,$< \
-- $(NO_UNDEFINED) \
-- -Wl,--whole-archive $(libelf_so_LIBS) -Wl,--no-whole-archive \
-- $(libelf_so_LDLIBS)
-- @$(textrel_check)
-- $(AM_V_at)ln -fs $@ $@.$(VERSION)
--
--install: install-am libelf.so
-+install: install-am
- $(mkinstalldirs) $(DESTDIR)$(libdir)
-- $(INSTALL_PROGRAM) libelf.so $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so
-- ln -fs libelf-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libelf.so.$(VERSION)
-- ln -fs libelf.so.$(VERSION) $(DESTDIR)$(libdir)/libelf.so
-
- uninstall: uninstall-am
-- rm -f $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so
-- rm -f $(DESTDIR)$(libdir)/libelf.so.$(VERSION)
-- rm -f $(DESTDIR)$(libdir)/libelf.so
-
- EXTRA_DIST = libelf.map
--
--CLEANFILES += $(am_libelf_pic_a_OBJECTS) libelf.so libelf.so.$(VERSION)
--- a/backends/i386_auxv.c
+++ b/backends/i386_auxv.c
@@ -48,5 +48,4 @@ EBLHOOK(auxv_info) (GElf_Xword a_type, c
@@ -365,518 +196,34 @@
+#endif
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
-@@ -32,10 +32,10 @@
+@@ -32,6 +32,7 @@
#include <stdbool.h>
#include <pthread.h>
+#include <libeu.h>
#include <libdw.h>
#include <dwarf.h>
+ #include "eu-search.h"
+--- a/config/libdebuginfod.pc.in
++++ b/config/libdebuginfod.pc.in
+@@ -8,5 +8,5 @@ Description: elfutils library to query d
+ Version: @VERSION@
+ URL: http://elfutils.org/
--
- /* Known location expressions already decoded. */
- struct loc_s
- {
---- a/libdw/Makefile.am
-+++ b/libdw/Makefile.am
-@@ -34,14 +34,12 @@ endif
- AM_CPPFLAGS += -I$(srcdir)/../libebl -I$(srcdir)/../libelf -I$(srcdir)/../libdwelf -pthread
- VERSION = 1
-
--lib_LIBRARIES = libdw.a
--noinst_LIBRARIES = libdw_pic.a
--noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so)
-+lib_LTLIBRARIES = libdw.la
-
- include_HEADERS = dwarf.h
- pkginclude_HEADERS = libdw.h known-dwarf.h
-
--libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
-+libdw_la_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
- dwarf_getpubnames.c dwarf_getabbrev.c dwarf_tag.c \
- dwarf_error.c dwarf_nextcu.c dwarf_diename.c dwarf_offdie.c \
- dwarf_attr.c dwarf_formstring.c \
-@@ -103,50 +101,12 @@ $(srcdir)/known-dwarf.h: $(top_srcdir)/c
- mv -f $@.new $@
- endif
-
--libdw_pic_a_SOURCES =
--am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os)
--
--libdw_so_LIBS = ../libebl/libebl_pic.a ../backends/libebl_backends_pic.a \
-- ../libcpu/libcpu_pic.a libdw_pic.a ../libdwelf/libdwelf_pic.a \
-- ../libdwfl/libdwfl_pic.a
--libdw_so_DEPS = ../lib/libeu.a ../libelf/libelf.so
--libdw_so_LDLIBS = $(libdw_so_DEPS) -ldl -lz $(argp_LDADD) $(fts_LIBS) $(obstack_LIBS) $(zip_LIBS) -pthread
--libdw.so: $(srcdir)/libdw.map $(libdw_so_LIBS) $(libdw_so_DEPS)
-- $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-- -Wl,--soname,$@.$(VERSION),--enable-new-dtags \
-- -Wl,--version-script,$< \
-- $(NO_UNDEFINED) \
-- -Wl,--whole-archive $(libdw_so_LIBS) -Wl,--no-whole-archive \
-- $(libdw_so_LDLIBS)
-- @$(textrel_check)
-- $(AM_V_at)ln -fs $@ $@.$(VERSION)
--
--install: install-am libdw.so
-- $(mkinstalldirs) $(DESTDIR)$(libdir)
-- $(INSTALL_PROGRAM) libdw.so $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so
-- ln -fs libdw-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdw.so.$(VERSION)
-- ln -fs libdw.so.$(VERSION) $(DESTDIR)$(libdir)/libdw.so
--
--uninstall: uninstall-am
-- rm -f $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so
-- rm -f $(DESTDIR)$(libdir)/libdw.so.$(VERSION)
-- rm -f $(DESTDIR)$(libdir)/libdw.so
-- rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
--
--libdwfl_objects = $(shell $(AR) t ../libdwfl/libdwfl.a)
--libdw_a_LIBADD = $(addprefix ../libdwfl/,$(libdwfl_objects))
--
--libdwelf_objects = $(shell $(AR) t ../libdwelf/libdwelf.a)
--libdw_a_LIBADD += $(addprefix ../libdwelf/,$(libdwelf_objects))
--
--libebl_objects = $(shell $(AR) t ../libebl/libebl.a)
--libdw_a_LIBADD += $(addprefix ../libebl/,$(libebl_objects))
--
--backends_objects = $(shell $(AR) t ../backends/libebl_backends.a)
--libdw_a_LIBADD += $(addprefix ../backends/,$(backends_objects))
--
--libcpu_objects = $(shell $(AR) t ../libcpu/libcpu.a)
--libdw_a_LIBADD += $(addprefix ../libcpu/,$(libcpu_objects))
-+libdw_la_LIBADD = \
-+ ../libdwfl/libdwfl.la \
-+ ../libdwelf/libdwelf.la \
-+ ../libebl/libebl.la \
-+ ../backends/libebl_backends.la \
-+ ../libcpu/libcpu.la
-
- noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h \
- dwarf_sig8_hash.h cfi.h encoded-value.h
---- a/libasm/Makefile.am
-+++ b/libasm/Makefile.am
-@@ -32,12 +32,10 @@ AM_CPPFLAGS += -I$(top_srcdir)/libelf -I
-
- VERSION = 1
-
--lib_LIBRARIES = libasm.a
--noinst_LIBRARIES = libasm_pic.a
--noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so)
-+lib_LTLIBRARIES = libasm.la
- pkginclude_HEADERS = libasm.h
-
--libasm_a_SOURCES = asm_begin.c asm_abort.c asm_end.c asm_error.c \
-+libasm_la_SOURCES = asm_begin.c asm_abort.c asm_end.c asm_error.c \
- asm_getelf.c asm_newscn.c asm_newscn_ingrp.c \
- asm_newsubscn.c asm_newsym.c asm_newcomsym.c \
- asm_newabssym.c \
-@@ -51,38 +49,6 @@ libasm_a_SOURCES = asm_begin.c asm_abort
- disasm_begin.c disasm_cb.c disasm_end.c disasm_str.c \
- symbolhash.c
-
--libasm_pic_a_SOURCES =
--am_libasm_pic_a_OBJECTS = $(libasm_a_SOURCES:.c=.os)
--
--libasm_so_DEPS = ../lib/libeu.a ../libebl/libebl_pic.a ../libelf/libelf.so ../libdw/libdw.so
--libasm_so_LDLIBS = $(libasm_so_DEPS)
--if USE_LOCKS
--libasm_so_LDLIBS += -lpthread
--endif
--
--libasm_so_LIBS = libasm_pic.a
--libasm.so: $(srcdir)/libasm.map $(libasm_so_LIBS) $(libasm_so_DEPS)
-- $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-- -Wl,--soname,$@.$(VERSION) \
-- -Wl,--version-script,$< \
-- $(NO_UNDEFINED) \
-- -Wl,--whole-archive $(libasm_so_LIBS) -Wl,--no-whole-archive \
-- $(libasm_so_LDLIBS)
-- @$(textrel_check)
-- $(AM_V_at)ln -fs $@ $@.$(VERSION)
--
--install: install-am libasm.so
-- $(mkinstalldirs) $(DESTDIR)$(libdir)
-- $(INSTALL_PROGRAM) libasm.so $(DESTDIR)$(libdir)/libasm-$(PACKAGE_VERSION).so
-- ln -fs libasm-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libasm.so.$(VERSION)
-- ln -fs libasm.so.$(VERSION) $(DESTDIR)$(libdir)/libasm.so
--
--uninstall: uninstall-am
-- rm -f $(DESTDIR)$(libdir)/libasm-$(PACKAGE_VERSION).so
-- rm -f $(DESTDIR)$(libdir)/libasm.so.$(VERSION)
-- rm -f $(DESTDIR)$(libdir)/libasm.so
-- rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
--
- noinst_HEADERS = libasmP.h symbolhash.h
- EXTRA_DIST = libasm.map
-
---- a/libdwfl/Makefile.am
-+++ b/libdwfl/Makefile.am
-@@ -34,13 +34,11 @@ AM_CPPFLAGS += -I$(srcdir) -I$(srcdir)/.
- -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf -I$(builddir)/../debuginfod
- VERSION = 1
-
--noinst_LIBRARIES = libdwfl.a
--noinst_LIBRARIES += libdwfl_pic.a
-+noinst_LTLIBRARIES = libdwfl.la
-
- pkginclude_HEADERS = libdwfl.h
-
--
--libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \
-+libdwfl_la_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \
- dwfl_module.c dwfl_report_elf.c relocate.c \
- dwfl_module_build_id.c dwfl_module_report_build_id.c \
- derelocate.c offline.c segment.c \
-@@ -73,24 +71,14 @@ libdwfl_a_SOURCES = dwfl_begin.c dwfl_en
- gzip.c debuginfod-client.c
-
- if BZLIB
--libdwfl_a_SOURCES += bzip2.c
-+libdwfl_la_SOURCES += bzip2.c
- endif
- if LZMA
--libdwfl_a_SOURCES += lzma.c
-+libdwfl_la_SOURCES += lzma.c
- endif
- if ZSTD
--libdwfl_a_SOURCES += zstd.c
-+libdwfl_la_SOURCES += zstd.c
- endif
-
--libdwfl = $(libdw)
--libdw = ../libdw/libdw.so
--libelf = ../libelf/libelf.so
--libebl = ../libebl/libebl.a
--libeu = ../lib/libeu.a
--
--libdwfl_pic_a_SOURCES =
--am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_SOURCES:.c=.os)
--
- noinst_HEADERS = libdwflP.h
-
--CLEANFILES += $(am_libdwfl_pic_a_OBJECTS)
---- a/backends/Makefile.am
-+++ b/backends/Makefile.am
-@@ -34,7 +34,7 @@ endif
- AM_CPPFLAGS += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \
- -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw
-
--noinst_LIBRARIES = libebl_backends.a libebl_backends_pic.a
-+noinst_LTLIBRARIES = libebl_backends.la
-
- modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \
- m68k bpf riscv csky loongarch arc
-@@ -102,17 +102,13 @@ loongarch_SRCS = loongarch_init.c loonga
-
- arc_SRCS = arc_init.c arc_symbol.c
-
--libebl_backends_a_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \
-+libebl_backends_la_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \
- $(ia64_SRCS) $(alpha_SRCS) $(arm_SRCS) \
- $(aarch64_SRCS) $(sparc_SRCS) $(ppc_SRCS) \
- $(ppc64_SRCS) $(s390_SRCS) \
- $(m68k_SRCS) $(bpf_SRCS) $(riscv_SRCS) $(csky_SRCS) \
- $(loongarch_SRCS) $(arc_SRCS)
-
--libebl_backends_pic_a_SOURCES =
--am_libebl_backends_pic_a_OBJECTS = $(libebl_backends_a_SOURCES:.c=.os)
-
- noinst_HEADERS = libebl_CPU.h common-reloc.c linux-core-note.c x86_corenote.c
- EXTRA_DIST = $(modules:=_reloc.def)
--
--MOSTLYCLEANFILES = $(am_libebl_backends_pic_a_OBJECTS)
---- a/libdwelf/Makefile.am
-+++ b/libdwelf/Makefile.am
-@@ -34,24 +34,12 @@ AM_CPPFLAGS += -I$(srcdir)/../libelf -I$
- -I$(srcdir)/../libdwfl -I$(srcdir)/../libebl
- VERSION = 1
-
--noinst_LIBRARIES = libdwelf.a libdwelf_pic.a
-+noinst_LTLIBRARIES = libdwelf.la
-
- pkginclude_HEADERS = libdwelf.h
- noinst_HEADERS = libdwelfP.h
-
--libdwelf_a_SOURCES = dwelf_elf_gnu_debuglink.c dwelf_dwarf_gnu_debugaltlink.c \
-+libdwelf_la_SOURCES = dwelf_elf_gnu_debuglink.c dwelf_dwarf_gnu_debugaltlink.c \
- dwelf_elf_gnu_build_id.c dwelf_scn_gnu_compressed_size.c \
- dwelf_strtab.c dwelf_elf_begin.c \
- dwelf_elf_e_machine_string.c
--
--libdwelf = $(libdw)
--
--libdw = ../libdw/libdw.so
--libelf = ../libelf/libelf.so
--libebl = ../libebl/libebl.a
--libeu = ../lib/libeu.a
--
--libdwelf_pic_a_SOURCES =
--am_libdwelf_pic_a_OBJECTS = $(libdwelf_a_SOURCES:.c=.os)
--
--CLEANFILES += $(am_libdwelf_pic_a_OBJECTS)
---- a/libebl/Makefile.am
-+++ b/libebl/Makefile.am
-@@ -34,9 +34,9 @@ endif
- AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libdw -I$(srcdir)/../libasm
- VERSION = 1
-
--noinst_LIBRARIES = libebl.a libebl_pic.a
-+noinst_LTLIBRARIES = libebl.la
-
--libebl_a_SOURCES = eblopenbackend.c eblclosebackend.c eblreloctypename.c \
-+libebl_la_SOURCES = eblopenbackend.c eblclosebackend.c eblreloctypename.c \
- eblsegmenttypename.c eblsectiontypename.c \
- eblmachineflagname.c eblsymboltypename.c \
- ebldynamictagname.c eblsectionname.c \
-@@ -56,9 +56,4 @@ libebl_a_SOURCES = eblopenbackend.c eblc
- eblresolvesym.c eblcheckreloctargettype.c \
- ebl_data_marker_symbol.c
-
--libebl_pic_a_SOURCES =
--am_libebl_pic_a_OBJECTS = $(libebl_a_SOURCES:.c=.os)
--
- noinst_HEADERS = libebl.h libeblP.h ebl-hooks.h
--
--MOSTLYCLEANFILES = $(am_libebl_pic_a_OBJECTS)
---- a/debuginfod/Makefile.am
-+++ b/debuginfod/Makefile.am
-@@ -40,23 +40,12 @@ AM_CPPFLAGS += -I$(srcdir) -I$(srcdir)/.
- program_prefix=
- program_transform_name = s,x,x,
-
--if BUILD_STATIC
--libasm = ../libasm/libasm.a
--libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl -lpthread
--libelf = ../libelf/libelf.a -lz
--if DUMMY_LIBDEBUGINFOD
--libdebuginfod = ./libdebuginfod.a
--else
--libdebuginfod = ./libdebuginfod.a -lpthread $(libcurl_LIBS)
--endif
--else
--libasm = ../libasm/libasm.so
--libdw = ../libdw/libdw.so
--libelf = ../libelf/libelf.so
--libdebuginfod = ./libdebuginfod.so
--endif
--libebl = ../libebl/libebl.a
--libeu = ../lib/libeu.a
-+libasm = ../libasm/libasm.la
-+libdw = ../libdw/libdw.la -lz $(zip_LIBS) $(libelf) $(libebl) -ldl -lpthread
-+libelf = ../libelf/libelf.la
-+libdebuginfod = ./libdebuginfod.la
-+libebl = ../libebl/libebl.la
-+libeu = ../lib/libeu.la
-
- AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw:.
-
-@@ -76,14 +65,10 @@ debuginfod_find_SOURCES = debuginfod-fin
- debuginfod_find_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS)
-
- if LIBDEBUGINFOD
--noinst_LIBRARIES = libdebuginfod.a
--noinst_LIBRARIES += libdebuginfod_pic.a
-+libdebuginfod_la_SOURCES = debuginfod-client.c
-+noinst_LTLIBRARIES = libdebuginfod.la
- endif
-
--libdebuginfod_a_SOURCES = debuginfod-client.c
--libdebuginfod_pic_a_SOURCES = debuginfod-client.c
--am_libdebuginfod_pic_a_OBJECTS = $(libdebuginfod_a_SOURCES:.c=.os)
--
- if DUMMY_LIBDEBUGINFOD
- AM_CPPFLAGS += -Wno-unused-parameter
- endif
-@@ -92,42 +77,7 @@ if LIBDEBUGINFOD
- pkginclude_HEADERS = debuginfod.h
- endif
-
--if LIBDEBUGINFOD
--libdebuginfod_so_LIBS = libdebuginfod_pic.a
--if DUMMY_LIBDEBUGINFOD
--libdebuginfod_so_LDLIBS =
--else
--libdebuginfod_so_LDLIBS = -lpthread $(libcurl_LIBS) $(fts_LIBS) $(libelf)
--endif
--$(LIBDEBUGINFOD_SONAME): $(srcdir)/libdebuginfod.map $(libdebuginfod_so_LIBS)
-- $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-- -Wl,--soname,$(LIBDEBUGINFOD_SONAME) \
-- -Wl,--version-script,$< \
-- $(NO_UNDEFINED) \
-- -Wl,--whole-archive $(libdebuginfod_so_LIBS) -Wl,--no-whole-archive \
-- $(libdebuginfod_so_LDLIBS)
-- @$(textrel_check)
--
--libdebuginfod.so: $(LIBDEBUGINFOD_SONAME)
-- ln -fs $< $@
--
--install: install-am libdebuginfod.so
-- $(mkinstalldirs) $(DESTDIR)$(libdir)
-- $(INSTALL_PROGRAM) $(LIBDEBUGINFOD_SONAME) \
-- $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so
-- ln -fs libdebuginfod-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/$(LIBDEBUGINFOD_SONAME)
-- ln -fs libdebuginfod-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdebuginfod.so
--
--uninstall: uninstall-am
-- rm -f $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so
-- rm -f $(DESTDIR)$(libdir)/$(LIBDEBUGINFOD_SONAME)
-- rm -f $(DESTDIR)$(libdir)/libdebuginfod.so
-- rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
--endif
--
- EXTRA_DIST = libdebuginfod.map
--MOSTLYCLEANFILES = $(am_libdebuginfod_pic_a_OBJECTS) $(LIBDEBUGINFOD_SONAME)
--CLEANFILES += $(am_libdebuginfod_pic_a_OBJECTS) libdebuginfod.so
-
- # automake std-options override: arrange to pass LD_LIBRARY_PATH
- installcheck-binPROGRAMS: $(bin_PROGRAMS)
---- a/lib/Makefile.am
-+++ b/lib/Makefile.am
-@@ -31,9 +31,9 @@ include $(top_srcdir)/config/eu.am
- AM_CFLAGS += $(fpic_CFLAGS)
- AM_CPPFLAGS += -I$(srcdir)/../libelf
-
--noinst_LIBRARIES = libeu.a
-+noinst_LTLIBRARIES = libeu.la
-
--libeu_a_SOURCES = xasprintf.c xstrdup.c xstrndup.c xmalloc.c next_prime.c \
-+libeu_la_SOURCES = xasprintf.c xstrdup.c xstrndup.c xmalloc.c next_prime.c \
- crc32.c crc32_file.c \
- color.c error.c printversion.c
-
---- a/src/Makefile.am
-+++ b/src/Makefile.am
-@@ -29,9 +29,9 @@ bin_PROGRAMS = readelf nm size strip elf
- elfcmp objdump ranlib strings ar unstrip stack elfcompress \
- elfclassify srcfiles
-
--noinst_LIBRARIES = libar.a
-+noinst_LTLIBRARIES = libar.la
-
--libar_a_SOURCES = arlib.c arlib2.c arlib-argp.c
-+libar_la_SOURCES = arlib.c arlib2.c arlib-argp.c
-
- EXTRA_DIST = arlib.h debugpred.h
-
-@@ -39,27 +39,16 @@ bin_SCRIPTS = make-debug-archive
- EXTRA_DIST += make-debug-archive.in
- CLEANFILES += make-debug-archive
-
--if BUILD_STATIC
--libasm = ../libasm/libasm.a
--libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) -ldl -lpthread
--libelf = ../libelf/libelf.a -lz $(zstd_LIBS)
-+libasm = ../libasm/libasm.la
-+libdw = ../libdw/libdw.la -lz $(zip_LIBS) $(libelf) -ldl -lpthread
-+libelf = ../libelf/libelf.la -lz $(zstd_LIBS)
- if LIBDEBUGINFOD
--libdebuginfod = ../debuginfod/libdebuginfod.a -lpthread $(libcurl_LIBS)
-+libdebuginfod = ../debuginfod/libdebuginfod.la -lpthread $(libcurl_LIBS)
- else
- libdebuginfod =
- endif
--else
--libasm = ../libasm/libasm.so
--libdw = ../libdw/libdw.so
--libelf = ../libelf/libelf.so
--if LIBDEBUGINFOD
--libdebuginfod = ../debuginfod/libdebuginfod.so
--else
--libdebuginfod =
--endif
--endif
--libebl = ../libebl/libebl.a ../backends/libebl_backends.a ../libcpu/libcpu.a
--libeu = ../lib/libeu.a
-+libebl = ../libebl/libebl.la ../backends/libebl_backends.la ../libcpu/libcpu.la
-+libeu = ../lib/libeu.la
-
- if DEMANGLE
- demanglelib = -lstdc++
-@@ -87,9 +76,9 @@ findtextrel_LDADD = $(libdw) $(libelf) $
- addr2line_LDADD = $(libdw) $(libelf) $(libeu) $(argp_LDADD) $(demanglelib)
- elfcmp_LDADD = $(libebl) $(libdw) $(libelf) $(libeu) $(argp_LDADD)
- objdump_LDADD = $(libasm) $(libebl) $(libdw) $(libelf) $(libeu) $(argp_LDADD)
--ranlib_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS)
-+ranlib_LDADD = libar.la $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS)
- strings_LDADD = $(libelf) $(libeu) $(argp_LDADD)
--ar_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS)
-+ar_LDADD = libar.la $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS)
- unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD)
- stack_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) $(demanglelib)
- elfcompress_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD)
---- a/tests/Makefile.am
-+++ b/tests/Makefile.am
-@@ -689,17 +689,11 @@ installcheck-local:
- TESTS_ENVIRONMENT="$(installed_TESTS_ENVIRONMENT)" \
- LOG_COMPILER="$(installed_LOG_COMPILER)" check-TESTS
-
--if BUILD_STATIC
--libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl -lpthread
--libelf = ../libelf/libelf.a -lz $(zstd_LIBS)
--libasm = ../libasm/libasm.a
--else
--libdw = ../libdw/libdw.so
--libelf = ../libelf/libelf.so
--libasm = ../libasm/libasm.so
--endif
--libebl = ../libebl/libebl.a ../backends/libebl_backends.a ../libcpu/libcpu.a
--libeu = ../lib/libeu.a
-+libdw = ../libdw/libdw.la -lz $(zip_LIBS) $(libelf) $(libebl) -ldl -lpthread
-+libelf = ../libelf/libelf.la
-+libasm = ../libasm/libasm.la
-+libebl = ../libebl/libebl.la ../backends/libebl_backends.la ../libcpu/libcpu.la
-+libeu = ../lib/libeu.la
-
- arextract_LDADD = $(libelf)
- arsymtest_LDADD = $(libelf)
---- a/libcpu/Makefile.am
-+++ b/libcpu/Makefile.am
-@@ -38,19 +38,16 @@ LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAG
- LEX_OUTPUT_ROOT = lex.$(<F:lex.l=)
- AM_YFLAGS = -p$(<F:parse.y=)
-
--noinst_LIBRARIES = libcpu.a libcpu_pic.a
-+noinst_LTLIBRARIES = libcpu.la
-
- noinst_HEADERS = i386_dis.h i386_mne.h x86_64_dis.h
-
--libcpu_a_SOURCES = i386_disasm.c x86_64_disasm.c bpf_disasm.c riscv_disasm.c
--
--libcpu_pic_a_SOURCES =
--am_libcpu_pic_a_OBJECTS = $(libcpu_a_SOURCES:.c=.os)
-+libcpu_la_SOURCES = i386_disasm.c x86_64_disasm.c bpf_disasm.c riscv_disasm.c
-
- i386_gendis_SOURCES = i386_gendis.c i386_lex.l i386_parse.y
-
--i386_disasm.o: i386.mnemonics $(srcdir)/i386_dis.h
--x86_64_disasm.o: x86_64.mnemonics $(srcdir)/x86_64_dis.h
-+$(libcpu_la_OBJECTS): i386.mnemonics $(srcdir)/i386_dis.h
-+$(libcpu_la_OBJECTS): x86_64.mnemonics $(srcdir)/x86_64_dis.h
-
- %_defs: $(srcdir)/defs/i386
- $(AM_V_GEN)m4 -D$* -DDISASSEMBLER $< > $@T
-@@ -87,20 +84,15 @@ endif
-
- i386_lex_no_Werror = yes
-
--libeu = ../lib/libeu.a
-+libeu = ../lib/libeu.la
-
- i386_lex_CFLAGS = -Wno-unused-label -Wno-unused-function -Wno-sign-compare \
- -Wno-implicit-fallthrough
--i386_parse.o: i386_parse.c i386.mnemonics
--i386_lex.o: i386_parse.h
- i386_gendis_LDADD = $(libeu) -lm $(obstack_LIBS)
-
--i386_parse.h: i386_parse.c ;
--
- bpf_disasm_CFLAGS = -Wno-format-nonliteral
+-Libs: -L${libdir} -ldebuginfod
++Libs: -L${libdir} -ldebuginfod -lpthread
+ Cflags: -I${includedir}
+--- a/config/libdw.pc.in
++++ b/config/libdw.pc.in
+@@ -8,7 +8,7 @@ Description: elfutils library for DWARF
+ Version: @VERSION@
+ URL: http://elfutils.org/
- EXTRA_DIST = defs/i386
+-Libs: -L${libdir} -ldw
++Libs: -L${libdir} -ldw -lz -lelf -lz -ldl -lpthread
+ Cflags: -I${includedir}
--MOSTLYCLEANFILES = $(am_libcpu_pic_a_OBJECTS)
- CLEANFILES += $(foreach P,i386 x86_64,$P_defs $P.mnemonics)
- MAINTAINERCLEANFILES = $(foreach P,i386 x86_64, $P_dis.h)
+ # We need the exact matching elfutils libelf version since internal data
--- a/config/libelf.pc.in
+++ b/config/libelf.pc.in
@@ -8,7 +8,7 @@ Description: elfutils libelf library to
@@ -888,13 +235,34 @@
Cflags: -I${includedir}
Requires.private: zlib @LIBZSTD@
---- a/lib/next_prime.c
-+++ b/lib/next_prime.c
-@@ -27,6 +27,7 @@
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-+#include <config.h>
- #include <stddef.h>
-
+--- a/libebl/eblopenbackend.c
++++ b/libebl/eblopenbackend.c
+@@ -202,8 +202,6 @@ static bool default_object_note (const c
+ uint32_t descsz, const char *desc);
+ static bool default_debugscn_p (const char *name);
+ static bool default_copy_reloc_p (int reloc);
+-static bool default_none_reloc_p (int reloc);
+-static bool default_relative_reloc_p (int reloc);
+ static bool default_check_special_symbol (Elf *elf,
+ const GElf_Sym *sym,
+ const char *name,
+@@ -255,8 +253,8 @@ fill_defaults (Ebl *result)
+ result->object_note = default_object_note;
+ result->debugscn_p = default_debugscn_p;
+ result->copy_reloc_p = default_copy_reloc_p;
+- result->none_reloc_p = default_none_reloc_p;
+- result->relative_reloc_p = default_relative_reloc_p;
++ result->none_reloc_p = default_copy_reloc_p;
++ result->relative_reloc_p = default_copy_reloc_p;
+ result->check_special_symbol = default_check_special_symbol;
+ result->data_marker_symbol = default_data_marker_symbol;
+ result->check_st_other_bits = default_check_st_other_bits;
+@@ -638,8 +636,6 @@ default_copy_reloc_p (int reloc __attrib
+ {
+ return false;
+ }
+-strong_alias (default_copy_reloc_p, default_none_reloc_p)
+-strong_alias (default_copy_reloc_p, default_relative_reloc_p)
+ static bool
+ default_check_special_symbol (Elf *elf __attribute__ ((unused)),
diff --git a/tools/elfutils/patches/101-shared-conditional.patch b/tools/elfutils/patches/101-shared-conditional.patch
new file mode 100644
index 0000000000..4eeee6a682
--- /dev/null
+++ b/tools/elfutils/patches/101-shared-conditional.patch
@@ -0,0 +1,184 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -102,6 +102,8 @@ m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+ AC_CHECK_TOOL([READELF], [readelf])
+ AC_CHECK_TOOL([NM], [nm])
+
++LT_INIT([shared disable-static])
++
+ AC_CACHE_CHECK([whether gcc supports __attribute__((visibility()))],
+ ac_cv_visibility, [dnl
+ save_CFLAGS="$CFLAGS"
+@@ -423,7 +425,10 @@ AS_HELP_STRING([--enable-install-elfh],[
+ AM_CONDITIONAL(INSTALL_ELFH, test "$install_elfh" = yes)
+
+ AM_CONDITIONAL(BUILD_STATIC, [dnl
+-test "$use_gprof" = yes -o "$use_gcov" = yes])
++test "$use_gprof" = yes -o "$use_gcov" = yes -o "$enable_static" = yes])
++
++AM_CONDITIONAL(BUILD_SHARED, [dnl
++test "$enable_shared" = yes])
+
+ AC_ARG_ENABLE([tests-rpath],
+ AS_HELP_STRING([--enable-tests-rpath],[build $ORIGIN-using rpath into tests]),
+--- a/libelf/Makefile.am
++++ b/libelf/Makefile.am
+@@ -35,8 +35,11 @@ endif
+ VERSION = 1
+
+ lib_LIBRARIES = libelf.a
++if BUILD_SHARED
+ noinst_LIBRARIES = libelf_pic.a
+ noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so)
++endif
++
+ include_HEADERS = libelf.h gelf.h nlist.h
+
+ noinst_HEADERS = abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \
+@@ -122,11 +125,15 @@ libelf.so: $(srcdir)/libelf.map $(libelf
+ @$(textrel_check)
+ $(AM_V_at)ln -fs $@ $@.$(VERSION)
+
++if BUILD_SHARED
+ install: install-am libelf.so
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ $(INSTALL_PROGRAM) libelf.so $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so
+ ln -fs libelf-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libelf.so.$(VERSION)
+ ln -fs libelf.so.$(VERSION) $(DESTDIR)$(libdir)/libelf.so
++else
++libelf_a_LIBADD = $(foreach dep,$(libelf_so_DEPS:.so=.a) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(addprefix $(dir $(dep)),$(shell cat $(basename $(dep)).manifest)),$(dep)))
++endif
+
+ uninstall: uninstall-am
+ rm -f $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so
+--- a/libdw/Makefile.am
++++ b/libdw/Makefile.am
+@@ -35,8 +35,10 @@ AM_CPPFLAGS += -I$(srcdir)/../libebl -I$
+ VERSION = 1
+
+ lib_LIBRARIES = libdw.a
++if BUILD_SHARED
+ noinst_LIBRARIES = libdw_pic.a
+ noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so)
++endif
+
+ include_HEADERS = dwarf.h
+ pkginclude_HEADERS = libdw.h known-dwarf.h
+@@ -120,11 +122,13 @@ libdw.so: $(srcdir)/libdw.map $(libdw_so
+ @$(textrel_check)
+ $(AM_V_at)ln -fs $@ $@.$(VERSION)
+
++if BUILD_SHARED
+ install: install-am libdw.so
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ $(INSTALL_PROGRAM) libdw.so $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so
+ ln -fs libdw-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdw.so.$(VERSION)
+ ln -fs libdw.so.$(VERSION) $(DESTDIR)$(libdir)/libdw.so
++endif
+
+ uninstall: uninstall-am
+ rm -f $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so
+@@ -147,6 +151,10 @@ libdw_a_LIBADD += $(addprefix ../backend
+ libcpu_objects = $(shell $(AR) t ../libcpu/libcpu.a)
+ libdw_a_LIBADD += $(addprefix ../libcpu/,$(libcpu_objects))
+
++if !BUILD_SHARED
++libdw_a_LIBADD += $(foreach dep,$(libdw_so_DEPS:.so=.a) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(addprefix $(dir $(dep)),$(shell cat $(basename $(dep)).manifest)),$(dep)))
++endif
++
+ noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h \
+ dwarf_sig8_hash.h cfi.h encoded-value.h
+
+--- a/libasm/Makefile.am
++++ b/libasm/Makefile.am
+@@ -33,8 +33,11 @@ AM_CPPFLAGS += -I$(top_srcdir)/libelf -I
+ VERSION = 1
+
+ lib_LIBRARIES = libasm.a
++if BUILD_SHARED
+ noinst_LIBRARIES = libasm_pic.a
+ noinst_DATA = $(noinst_LIBRARIES:_pic.a=.so)
++endif
++
+ pkginclude_HEADERS = libasm.h
+
+ libasm_a_SOURCES = asm_begin.c asm_abort.c asm_end.c asm_error.c \
+@@ -71,11 +74,15 @@ libasm.so: $(srcdir)/libasm.map $(libasm
+ @$(textrel_check)
+ $(AM_V_at)ln -fs $@ $@.$(VERSION)
+
++if BUILD_SHARED
+ install: install-am libasm.so
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ $(INSTALL_PROGRAM) libasm.so $(DESTDIR)$(libdir)/libasm-$(PACKAGE_VERSION).so
+ ln -fs libasm-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libasm.so.$(VERSION)
+ ln -fs libasm.so.$(VERSION) $(DESTDIR)$(libdir)/libasm.so
++else
++libasm_a_LIBADD = $(foreach dep,$(libasm_so_DEPS:.so=.a) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(addprefix $(dir $(dep)),$(shell cat $(basename $(dep)).manifest)),$(dep)))
++endif
+
+ uninstall: uninstall-am
+ rm -f $(DESTDIR)$(libdir)/libasm-$(PACKAGE_VERSION).so
+--- a/debuginfod/Makefile.am
++++ b/debuginfod/Makefile.am
+@@ -77,8 +77,10 @@ debuginfod_find_LDADD = $(libdw) $(libel
+
+ if LIBDEBUGINFOD
+ noinst_LIBRARIES = libdebuginfod.a
++if BUILD_SHARED
+ noinst_LIBRARIES += libdebuginfod_pic.a
+ endif
++endif
+
+ libdebuginfod_a_SOURCES = debuginfod-client.c
+ libdebuginfod_pic_a_SOURCES = debuginfod-client.c
+@@ -111,12 +113,17 @@ $(LIBDEBUGINFOD_SONAME): $(srcdir)/libde
+ libdebuginfod.so: $(LIBDEBUGINFOD_SONAME)
+ ln -fs $< $@
+
++if BUILD_SHARED
+ install: install-am libdebuginfod.so
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ $(INSTALL_PROGRAM) $(LIBDEBUGINFOD_SONAME) \
+ $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so
+ ln -fs libdebuginfod-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/$(LIBDEBUGINFOD_SONAME)
+ ln -fs libdebuginfod-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdebuginfod.so
++else
++libdebuginfod_a_LIBADD = $(foreach dep,$(wildcard $(libdebuginfod_so_LDLIBS:.so=.a)) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(addprefix $(dir $(dep)),$(shell cat $(basename $(dep)).manifest)),$(dep)))
++endif
++
+ uninstall: uninstall-am
+ rm -f $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so
+ rm -f $(DESTDIR)$(libdir)/$(LIBDEBUGINFOD_SONAME)
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -50,7 +50,7 @@ check_PROGRAMS = arextract arsymtest new
+ dwfl-report-offline-memory \
+ varlocs backtrace backtrace-child \
+ backtrace-data backtrace-dwarf debuglink debugaltlink \
+- buildid deleted deleted-lib.so aggregate_size peel_type \
++ buildid aggregate_size peel_type \
+ vdsosyms \
+ getsrc_die strptr newdata newzdata \
+ elfstrtab dwfl-proc-attach \
+@@ -181,7 +181,7 @@ TESTS = run-arextract.sh run-arsymtest.s
+ run-readelf-addr.sh run-readelf-str.sh \
+ run-readelf-multi-noline.sh \
+ run-readelf-types.sh \
+- run-readelf-dwz-multi.sh run-allfcts-multi.sh run-deleted.sh \
++ run-readelf-dwz-multi.sh run-allfcts-multi.sh \
+ run-linkmap-cut.sh run-aggregate-size.sh run-peel-type.sh \
+ vdsosyms run-readelf-A.sh \
+ run-getsrc-die.sh run-strptr.sh newdata newzdata \
+@@ -298,6 +298,11 @@ check_PROGRAMS += funcretval_test_struct
+ funcretval_test_struct_SOURCES = funcretval_test_struct.c
+ TESTS += run-funcretval-struct-native.sh
+
++if BUILD_SHARED
++check_PROGRAMS += deleted deleted-lib.so
++TESTS += run-deleted.sh
++endif
++
+ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
+ run-ar-N.sh \
+ run-show-die-info.sh run-get-files.sh run-get-lines.sh \
diff --git a/tools/elfutils/patches/110-objects-manifest.patch b/tools/elfutils/patches/110-objects-manifest.patch
new file mode 100644
index 0000000000..35ef131190
--- /dev/null
+++ b/tools/elfutils/patches/110-objects-manifest.patch
@@ -0,0 +1,162 @@
+--- a/libdw/Makefile.am
++++ b/libdw/Makefile.am
+@@ -136,19 +136,19 @@ uninstall: uninstall-am
+ rm -f $(DESTDIR)$(libdir)/libdw.so
+ rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
+
+-libdwfl_objects = $(shell $(AR) t ../libdwfl/libdwfl.a)
++libdwfl_objects = $(shell cat ../libdwfl/libdwfl.manifest)
+ libdw_a_LIBADD = $(addprefix ../libdwfl/,$(libdwfl_objects))
+
+-libdwelf_objects = $(shell $(AR) t ../libdwelf/libdwelf.a)
++libdwelf_objects = $(shell cat ../libdwelf/libdwelf.manifest)
+ libdw_a_LIBADD += $(addprefix ../libdwelf/,$(libdwelf_objects))
+
+-libebl_objects = $(shell $(AR) t ../libebl/libebl.a)
++libebl_objects = $(shell cat ../libebl/libebl.manifest)
+ libdw_a_LIBADD += $(addprefix ../libebl/,$(libebl_objects))
+
+-backends_objects = $(shell $(AR) t ../backends/libebl_backends.a)
++backends_objects = $(shell cat ../backends/libebl_backends.manifest)
+ libdw_a_LIBADD += $(addprefix ../backends/,$(backends_objects))
+
+-libcpu_objects = $(shell $(AR) t ../libcpu/libcpu.a)
++libcpu_objects = $(shell cat ../libcpu/libcpu.manifest)
+ libdw_a_LIBADD += $(addprefix ../libcpu/,$(libcpu_objects))
+
+ if !BUILD_SHARED
+@@ -160,5 +160,10 @@ noinst_HEADERS = libdwP.h memory-access.
+
+ EXTRA_DIST = libdw.map
+
+-MOSTLYCLEANFILES = $(am_libdw_pic_a_OBJECTS) libdw.so libdw.so.$(VERSION)
++EXTRA_libdw_a_DEPENDENCIES = libdw.manifest
++
++libdw.manifest: $(libdw_a_OBJECTS)
++ echo $^ > $@
++
++MOSTLYCLEANFILES = $(am_libdw_pic_a_OBJECTS) $(EXTRA_libdw_a_DEPENDENCIES) libdw.so libdw.so.$(VERSION)
+ MAINTAINERCLEANFILES = $(srcdir)/known-dwarf.h
+--- a/libdwfl/Makefile.am
++++ b/libdwfl/Makefile.am
+@@ -94,4 +94,10 @@ am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_S
+
+ noinst_HEADERS = libdwflP.h
+
++EXTRA_libdwfl_a_DEPENDENCIES = libdwfl.manifest
++
++libdwfl.manifest: $(libdwfl_a_OBJECTS)
++ echo $^ > $@
++
++MOSTLYCLEANFILES = $(EXTRA_libdwfl_a_DEPENDENCIES)
+ CLEANFILES += $(am_libdwfl_pic_a_OBJECTS)
+--- a/libdwelf/Makefile.am
++++ b/libdwelf/Makefile.am
+@@ -54,4 +54,10 @@ libeu = ../lib/libeu.a
+ libdwelf_pic_a_SOURCES =
+ am_libdwelf_pic_a_OBJECTS = $(libdwelf_a_SOURCES:.c=.os)
+
++EXTRA_libdwelf_a_DEPENDENCIES = libdwelf.manifest
++
++libdwelf.manifest: $(libdwelf_a_OBJECTS)
++ echo $^ > $@
++
++MOSTLYCLEANFILES = $(EXTRA_libdwelf_a_DEPENDENCIES)
+ CLEANFILES += $(am_libdwelf_pic_a_OBJECTS)
+--- a/libebl/Makefile.am
++++ b/libebl/Makefile.am
+@@ -61,4 +61,9 @@ am_libebl_pic_a_OBJECTS = $(libebl_a_SOU
+
+ noinst_HEADERS = libebl.h libeblP.h ebl-hooks.h
+
+-MOSTLYCLEANFILES = $(am_libebl_pic_a_OBJECTS)
++EXTRA_libebl_a_DEPENDENCIES = libebl.manifest
++
++libebl.manifest: $(libebl_a_OBJECTS)
++ echo $^ > $@
++
++MOSTLYCLEANFILES = $(am_libebl_pic_a_OBJECTS) $(EXTRA_libebl_a_DEPENDENCIES)
+--- a/backends/Makefile.am
++++ b/backends/Makefile.am
+@@ -122,4 +122,9 @@ am_libebl_backends_pic_a_OBJECTS = $(lib
+ noinst_HEADERS = libebl_CPU.h common-reloc.c linux-core-note.c x86_corenote.c
+ EXTRA_DIST = $(modules:=_reloc.def)
+
+-MOSTLYCLEANFILES = $(am_libebl_backends_pic_a_OBJECTS)
++EXTRA_libebl_backends_a_DEPENDENCIES = libebl_backends.manifest
++
++libebl_backends.manifest: $(libebl_backends_a_OBJECTS)
++ echo $^ > $@
++
++MOSTLYCLEANFILES = $(am_libebl_backends_pic_a_OBJECTS) $(EXTRA_libebl_backends_a_DEPENDENCIES)
+--- a/libcpu/Makefile.am
++++ b/libcpu/Makefile.am
+@@ -101,6 +101,11 @@ bpf_disasm_CFLAGS = -Wno-format-nonliter
+
+ EXTRA_DIST = defs/i386
+
+-MOSTLYCLEANFILES = $(am_libcpu_pic_a_OBJECTS)
++EXTRA_libcpu_a_DEPENDENCIES = libcpu.manifest
++
++libcpu.manifest: $(libcpu_a_OBJECTS)
++ echo $^ > $@
++
++MOSTLYCLEANFILES = $(am_libcpu_pic_a_OBJECTS) $(EXTRA_libcpu_a_DEPENDENCIES)
+ CLEANFILES += $(foreach P,i386 x86_64,$P_defs $P.mnemonics)
+ MAINTAINERCLEANFILES = $(foreach P,i386 x86_64, $P_dis.h)
+--- a/libelf/Makefile.am
++++ b/libelf/Makefile.am
+@@ -142,4 +142,10 @@ uninstall: uninstall-am
+
+ EXTRA_DIST = libelf.map
+
++EXTRA_libelf_a_DEPENDENCIES = libelf.manifest
++
++libelf.manifest: $(libelf_a_OBJECTS)
++ echo $^ > $@
++
++MOSTLYCLEANFILES = $(EXTRA_libelf_a_DEPENDENCIES)
+ CLEANFILES += $(am_libelf_pic_a_OBJECTS) libelf.so libelf.so.$(VERSION)
+--- a/lib/Makefile.am
++++ b/lib/Makefile.am
+@@ -42,3 +42,10 @@ noinst_HEADERS = fixedsizehash.h libeu.h
+ atomics.h stdatomic-fbsd.h dynamicsizehash_concurrent.h \
+ eu-search.h locks.h
+ EXTRA_DIST = dynamicsizehash.c dynamicsizehash_concurrent.c
++
++EXTRA_libeu_a_DEPENDENCIES = libeu.manifest
++
++libeu.manifest: $(libeu_a_OBJECTS)
++ echo $^ > $@
++
++MOSTLYCLEANFILES = $(EXTRA_libeu_a_DEPENDENCIES)
+--- a/libasm/Makefile.am
++++ b/libasm/Makefile.am
+@@ -93,4 +93,10 @@ uninstall: uninstall-am
+ noinst_HEADERS = libasmP.h symbolhash.h
+ EXTRA_DIST = libasm.map
+
++EXTRA_libasm_a_DEPENDENCIES = libasm.manifest
++
++libasm.manifest: $(libasm_a_OBJECTS)
++ echo $^ > $@
++
++MOSTLYCLEANFILES = $(EXTRA_libasm_a_DEPENDENCIES)
+ CLEANFILES += $(am_libasm_pic_a_OBJECTS) libasm.so libasm.so.$(VERSION)
+--- a/debuginfod/Makefile.am
++++ b/debuginfod/Makefile.am
+@@ -132,7 +132,13 @@ uninstall: uninstall-am
+ endif
+
+ EXTRA_DIST = libdebuginfod.map
+-MOSTLYCLEANFILES = $(am_libdebuginfod_pic_a_OBJECTS) $(LIBDEBUGINFOD_SONAME)
++
++EXTRA_libdebuginfod_a_DEPENDENCIES = libdebuginfod.manifest
++
++libdebuginfod.manifest: $(libdebuginfod_a_OBJECTS)
++ echo $^ > $@
++
++MOSTLYCLEANFILES = $(am_libdebuginfod_pic_a_OBJECTS) $(LIBDEBUGINFOD_SONAME) $(EXTRA_libdebuginfod_a_DEPENDENCIES)
+ CLEANFILES += $(am_libdebuginfod_pic_a_OBJECTS) libdebuginfod.so
+
+ # automake std-options override: arrange to pass LD_LIBRARY_PATH
diff --git a/tools/erofs-utils/Makefile b/tools/erofs-utils/Makefile
new file mode 100644
index 0000000000..e25f2f8409
--- /dev/null
+++ b/tools/erofs-utils/Makefile
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2009-2025 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=erofs-utils
+PKG_VERSION:=1.8.9
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git
+PKG_MIRROR_HASH:=feab7386de6faf11cb29af5bfa240ea119b14bfd66c14d80de0509c1ab16dcc6
+PKG_SOURCE_DATE:=2025-06-26
+PKG_SOURCE_VERSION:=81169bf3cfd26b8f2b3aa3b20da23971168a90a9
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/host-build.mk
+
+HOST_CONFIGURE_ARGS=\
+ --enable-multithreading \
+ --enable-lzma \
+ --enable-lz4 \
+ --disable-fuse \
+ --with-uuid
+
+define Host/Install
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/mkfs/mkfs.erofs $(STAGING_DIR_HOST)/bin/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/fsck/fsck.erofs $(STAGING_DIR_HOST)/bin/
+endef
+
+define Host/Clean
+ rm -f $(STAGING_DIR_HOST)/bin/mkfs.erofs
+ rm -f $(STAGING_DIR_HOST)/bin/fsck.erofs
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/expat/Makefile b/tools/expat/Makefile
index 8c15f98a22..8e46aa989e 100644
--- a/tools/expat/Makefile
+++ b/tools/expat/Makefile
@@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=expat
PKG_CPE_ID:=cpe:/a:libexpat:libexpat
-PKG_VERSION:=2.6.2
+PKG_VERSION:=2.7.1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_HASH:=d4cf38d26e21a56654ffe4acd9cd5481164619626802328506a2869afab29ab3
+PKG_HASH:=0cce2e6e69b327fc607b8ff264f4b66bdf71ead55a87ffd5f3143f535f15cfa2
PKG_SOURCE_URL:=https://github.com/libexpat/libexpat/releases/download/R_$(subst .,_,$(PKG_VERSION))
HOST_BUILD_PARALLEL:=1
@@ -20,6 +20,7 @@ HOST_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
HOSTCC := $(HOSTCC_NOCACHE)
+HOSTCXX := $(HOSTCXX_NOCACHE)
HOST_CONFIGURE_ARGS += \
--disable-shared \
diff --git a/tools/fakeroot/Makefile b/tools/fakeroot/Makefile
index efd9227d1a..1b8fba25a7 100644
--- a/tools/fakeroot/Makefile
+++ b/tools/fakeroot/Makefile
@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fakeroot
-PKG_VERSION:=1.29
+PKG_VERSION:=1.37.1.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).orig.tar.gz
PKG_SOURCE_URL:=@DEBIAN/pool/main/f/fakeroot
-PKG_HASH:=8fbbafb780c9173e3ace4a04afbc1d900f337f3216883939f5c7db3431be7c20
+PKG_HASH:=959496928c8a676ec8377f665ff6a19a707bfad693325f9cc4a4126642f53224
PKG_LICENSE:=GPL-3.0-or-later
PKG_LICENSE_FILES:=COPYING
PKG_FIXUP:=autoreconf
diff --git a/tools/fakeroot/patches/200-disable-doc.patch b/tools/fakeroot/patches/200-disable-doc.patch
index 29a3e39b2d..cceb6ccc26 100644
--- a/tools/fakeroot/patches/200-disable-doc.patch
+++ b/tools/fakeroot/patches/200-disable-doc.patch
@@ -6,5 +6,5 @@
-SUBDIRS=doc scripts test
+SUBDIRS=scripts test
- noinst_LTLIBRARIES = libcommunicate.la libmacosx.la
+ noinst_LTLIBRARIES = libcommunicate.la libmacosx.la libfakeroot_time64.la
libcommunicate_la_SOURCES = communicate.c
diff --git a/tools/fakeroot/patches/300-time64-hack.patch b/tools/fakeroot/patches/300-time64-hack.patch
new file mode 100644
index 0000000000..46132cdd3d
--- /dev/null
+++ b/tools/fakeroot/patches/300-time64-hack.patch
@@ -0,0 +1,11 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -390,7 +390,7 @@ dnl Digital Unix: stat
+ time64_hack=no
+ AH_TEMPLATE([TIME64_HACK], [time64 shuffle])
+ AC_MSG_CHECKING([if we need to cope with time64])
+-AC_EGREP_CPP([time64],[
++AC_EGREP_CPP([_*[a-z0-9]+_time64[^_]],[
+ #include <bits/wordsize.h>
+ #if __WORDSIZE == 32
+ #define __USE_TIME_BITS64 1
diff --git a/tools/fakeroot/patches/400-alpine-libc.musl-fix.patch b/tools/fakeroot/patches/400-alpine-libc.musl-fix.patch
index f740b120a1..5936034911 100644
--- a/tools/fakeroot/patches/400-alpine-libc.musl-fix.patch
+++ b/tools/fakeroot/patches/400-alpine-libc.musl-fix.patch
@@ -21,14 +21,3 @@ Error relocating openwrt/staging_dir/host/lib/libfakeroot.so: SEND_GET_XATTR: sy
#define SEND_GET_XATTR64(a,b,c) send_get_xattr64(a,b)
#endif
-@@ -142,8 +144,9 @@
-
- /* 10.10 uses id_t in getpriority/setpriority calls, so pretend
- id_t is used everywhere, just happens to be int on some OSes */
--#ifndef _ID_T
-+#if !defined(_ID_T) && !defined(__DEFINED_id_t)
- #define _ID_T
-+#define __DEFINED_id_t
- typedef int id_t;
- #endif
- #endif
diff --git a/tools/fakeroot/patches/600-macOS.patch b/tools/fakeroot/patches/600-macOS.patch
index 730367f07c..df4eb2d6c1 100644
--- a/tools/fakeroot/patches/600-macOS.patch
+++ b/tools/fakeroot/patches/600-macOS.patch
@@ -24,10 +24,10 @@
#include <spawn.h>
--- a/wrapfunc.inp
+++ b/wrapfunc.inp
-@@ -48,9 +48,11 @@ getattrlist$UNIX2003;int;(const char *pa
- #endif
+@@ -51,9 +51,11 @@ getattrlist$UNIX2003;int;(const char *pa
#endif
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
+ #include <spawn.h>
+#if !__DARWIN_ONLY_64_BIT_INO_T
lstat$INODE64;int;(const char *file_name, struct stat *buf);(file_name, buf)
stat$INODE64;int;(const char *file_name, struct stat *buf);(file_name, buf)
@@ -36,7 +36,7 @@
posix_spawn;int;(pid_t * __restrict pid, const char * __restrict path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t * __restrict attrp, char *const argv[ __restrict], char *const envp[ __restrict]);(pid, path, file_actions, attrp, argv, envp)
posix_spawnp;int;(pid_t * __restrict pid, const char * __restrict path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t * __restrict attrp, char *const argv[ __restrict], char *const envp[ __restrict]);(pid, path, file_actions, attrp, argv, envp)
#endif
-@@ -229,7 +231,7 @@ facl;int;(int fd, int cmd, int cnt, void
+@@ -235,7 +237,7 @@ facl;int;(int fd, int cmd, int cnt, void
#ifdef HAVE_FTS_READ
fts_read;FTSENT *;(FTS *ftsp);(ftsp)
#ifdef __APPLE__
@@ -45,7 +45,7 @@
fts_read$INODE64;FTSENT *;(FTS *ftsp);(ftsp)
#endif
#endif /* ifdef __APPLE__ */
-@@ -237,7 +239,7 @@ fts_read$INODE64;FTSENT *;(FTS *ftsp);(f
+@@ -243,7 +245,7 @@ fts_read$INODE64;FTSENT *;(FTS *ftsp);(f
#ifdef HAVE_FTS_CHILDREN
fts_children;FTSENT *;(FTS *ftsp, int options);(ftsp, options)
#ifdef __APPLE__
diff --git a/tools/findutils/Makefile b/tools/findutils/Makefile
index fd0cde2145..6587c759f8 100644
--- a/tools/findutils/Makefile
+++ b/tools/findutils/Makefile
@@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=findutils
PKG_CPE_ID:=cpe:/a:gnu:findutils
-PKG_VERSION:=4.9.0
+PKG_VERSION:=4.10.0
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
-PKG_HASH:=a2bfb8c09d436770edc59f50fa483e785b161a3b7b9d547573cb08065fd462fe
+PKG_HASH:=1387e0b67ff247d2abde998f90dfbf70c1491391a59ddfecb8ae698789f0a4f5
PKG_PROGRAMS:=find locate updatedb xargs
diff --git a/tools/findutils/patches/010-endpwent.patch b/tools/findutils/patches/010-endpwent.patch
deleted file mode 100644
index dc346f3f76..0000000000
--- a/tools/findutils/patches/010-endpwent.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/find/parser.c
-+++ b/find/parser.c
-@@ -67,12 +67,12 @@
- #include "findutils-version.h"
- #include "system.h"
-
--
--#ifndef HAVE_ENDGRENT
--# define endgrent ()
-+#if ! HAVE_ENDGRENT
-+# define endgrent() ((void) 0)
- #endif
--#ifndef HAVE_ENDPWENT
--# define endpwent ()
-+
-+#if ! HAVE_ENDPWENT
-+# define endpwent() ((void) 0)
- #endif
-
- static bool parse_accesscheck (const struct parser_table*, char *argv[], int *arg_ptr);
diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile
index e22f7a7b9a..96146637b3 100644
--- a/tools/firmware-utils/Makefile
+++ b/tools/firmware-utils/Makefile
@@ -11,9 +11,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware-utils.git
-PKG_SOURCE_DATE:=2024-03-23
-PKG_SOURCE_VERSION:=6b242991a995c41769977efb010dc9f4e4ec3da2
-PKG_MIRROR_HASH:=00ff2661fda2eb299ccbfaa07dff8fbcf46b3441a6e9f6f46eaa119e66dbe142
+PKG_SOURCE_DATE:=2025-08-03
+PKG_SOURCE_VERSION:=950f83405a935395492d61c9972b5e5ca826eeee
+PKG_MIRROR_HASH:=19f5b7547dc6f9460e25183c83d55aca9d1f18148466c09b64504a64379a34ae
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/cmake.mk
diff --git a/tools/flex/patches/300-m4-path.patch b/tools/flex/patches/300-m4-path.patch
new file mode 100644
index 0000000000..48e376f276
--- /dev/null
+++ b/tools/flex/patches/300-m4-path.patch
@@ -0,0 +1,23 @@
+--- a/src/main.c
++++ b/src/main.c
+@@ -213,6 +213,8 @@ int main (int argc, char *argv[])
+
+ void check_options (void)
+ {
++ const char * staging_dir = NULL;
++ char * m4_staging = NULL;
+ int i;
+ const char * m4 = NULL;
+
+@@ -341,7 +343,10 @@ void check_options (void)
+
+ /* Setup the filter chain. */
+ output_chain = filter_create_int(NULL, filter_tee_header, headerfilename);
+- if ( !(m4 = getenv("M4"))) {
++ if ( (staging_dir = getenv("STAGING_DIR_HOST"))) {
++ asprintf(&m4_staging, "%s/bin/m4", staging_dir);
++ m4 = m4_staging;
++ } else if ( !(m4 = getenv("M4"))) {
+ char *slash;
+ m4 = M4;
+ if ((slash = strrchr(M4, '/')) != NULL) {
diff --git a/tools/gmp/patches/001-acinclude-m4-fix-std23.patch b/tools/gmp/patches/001-acinclude-m4-fix-std23.patch
new file mode 100644
index 0000000000..05271764b7
--- /dev/null
+++ b/tools/gmp/patches/001-acinclude-m4-fix-std23.patch
@@ -0,0 +1,19 @@
+# HG changeset patch
+# User Marc Glisse <marc.glisse@inria.fr>
+# Date 1738186682 -3600
+# Wed Jan 29 22:38:02 2025 +0100
+# Node ID 8e7bb4ae7a18b1405ea7f9cbcda450b7d920a901
+# Parent e84c5c785bbe8ed8c3620194e50b65adfc2f5d83
+Complete function prototype in acinclude.m4 for C23 compatibility
+
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -609,7 +609,7 @@ GMP_PROG_CC_WORKS_PART([$1], [long long
+
+ #if defined (__GNUC__) && ! defined (__cplusplus)
+ typedef unsigned long long t1;typedef t1*t2;
+-void g(){}
++void g(int,t1 const*,t1,t2,t1 const*,int){}
+ void h(){}
+ static __inline__ t1 e(t2 rp,t2 up,int n,t1 v0)
+ {t1 c,x,r;int i;if(v0){c=1;for(i=1;i<n;i++){x=up[i];r=x+1;rp[i]=r;}}return c;}
diff --git a/tools/gmp/patches/002-acinclude-m4-add-parameter-names.patch b/tools/gmp/patches/002-acinclude-m4-add-parameter-names.patch
new file mode 100644
index 0000000000..9bfa5ecea4
--- /dev/null
+++ b/tools/gmp/patches/002-acinclude-m4-add-parameter-names.patch
@@ -0,0 +1,22 @@
+# HG changeset patch
+# User Marc Glisse <marc.glisse@inria.fr>
+# Date 1743513946 -7200
+# Tue Apr 01 15:25:46 2025 +0200
+# Node ID d66d66d82dbbe4f561920d28c1e1cbe6818452c7
+# Parent 1a2ad0e32507e842486c8ac9d5cdc772fd0c335e
+Add parameter names to function prototype
+
+ 2025-02-01 Marc Glisse <marc.glisse@inria.fr>
+
+ * longlong.h (loongarch64 umul_ppmm): __int128__ -> __int128.
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -609,7 +609,7 @@ GMP_PROG_CC_WORKS_PART([$1], [long long
+
+ #if defined (__GNUC__) && ! defined (__cplusplus)
+ typedef unsigned long long t1;typedef t1*t2;
+-void g(int,t1 const*,t1,t2,t1 const*,int){}
++void g(int a,t1 const*b,t1 c,t2 d,t1 const*e,int f){}
+ void h(){}
+ static __inline__ t1 e(t2 rp,t2 up,int n,t1 v0)
+ {t1 c,x,r;int i;if(v0){c=1;for(i=1;i<n;i++){x=up[i];r=x+1;rp[i]=r;}}return c;}
diff --git a/tools/gnulib/Makefile b/tools/gnulib/Makefile
index 5119355522..1237fad46e 100644
--- a/tools/gnulib/Makefile
+++ b/tools/gnulib/Makefile
@@ -2,11 +2,11 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=gnulib
PKG_CPE_ID:=cpe:/a:gnu:$(PKG_NAME)
-PKG_VERSION:=c99c8d491850dc3a6e0b8604a2729d8bc5c0eff1# # stable-202401
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://git.savannah.gnu.org/cgit/$(PKG_NAME).git/snapshot
-PKG_HASH:=8e6f4a907d9677b55fd452e1340a3e030a6f530b138d420c11975da33f086b1e
+PKG_SOURCE_URL=git://git.git.savannah.gnu.org/$(PKG_NAME).git
+PKG_SOURCE_DATE:=2025-07-01
+PKG_SOURCE_VERSION:=a3151d456d6919c9066b54dc6f680452168165cf# # stable-202501
+PKG_MIRROR_HASH:=b695d96e915ecd6c4551436f417cb2c0879aef4ef6318721c8d5cc86cb44ba9d
include $(INCLUDE_DIR)/host-build.mk
@@ -14,14 +14,14 @@ define Host/Configure
endef
define Host/Install
+ $(call Host/Uninstall)
$(INSTALL_DIR) $(1)/share/aclocal
$(INSTALL_DATA) $(HOST_BUILD_DIR)/m4/*.m4 $(1)/share/aclocal/
- $(INSTALL_DIR) $(1)/share/gnulib
- $(CP) $(HOST_BUILD_DIR)/* $(1)/share/gnulib/
+ $(CP) $(HOST_BUILD_DIR)/ $(1)/share/gnulib/
ln -sf ../share/gnulib/gnulib-tool $(STAGING_DIR_HOST)/bin/gnulib-tool
endef
-define Host/Clean
+define Host/Uninstall
rm -rf $(STAGING_DIR_HOST)/bin/gnulib-tool $(STAGING_DIR_HOST)/share/gnulib
endef
diff --git a/tools/gnulib/patches/000-bootstrap.patch b/tools/gnulib/patches/000-bootstrap.patch
index 120586694e..8d032ac080 100644
--- a/tools/gnulib/patches/000-bootstrap.patch
+++ b/tools/gnulib/patches/000-bootstrap.patch
@@ -43,7 +43,7 @@
if [ ! "$inst_ver" ]; then
warn_ "Error: '$app' not found"
ret=1
-@@ -1157,7 +1157,7 @@ autogen()
+@@ -1205,7 +1205,7 @@ autogen()
# two just-pre-run programs.
# Import from gettext.
diff --git a/tools/gnulib/patches/010-autoconf-version.patch b/tools/gnulib/patches/010-autoconf-version.patch
new file mode 100644
index 0000000000..ff0d795a61
--- /dev/null
+++ b/tools/gnulib/patches/010-autoconf-version.patch
@@ -0,0 +1,47 @@
+--- a/gnulib-tool.sh
++++ b/gnulib-tool.sh
+@@ -344,6 +344,34 @@ Options for --import, --add/remove-impor
+ Report bugs to <bug-gnulib@gnu.org>."
+ }
+
++get_version_sed='
++# Move version to start of line.
++s/.*[v ]\([0-9]\)/\1/
++
++# Skip lines that do not start with version.
++/^[0-9]/!d
++
++# Remove characters after the version.
++s/[^.a-z0-9-].*//
++
++# The first component must be digits only.
++s/^\([0-9]*\)[a-z-].*/\1/
++
++# The following essentially does s/5.005/5.5/
++s/\.0*\([1-9]\)/.\1/g
++p
++q'
++
++# get_version
++# copied from build-aux/bootstrap
++get_version () {
++ app=$1
++
++ $app --version >/dev/null 2>&1 || { $app --version; return 1; }
++
++ $app --version 2>&1 | sed -n "$get_version_sed"
++}
++
+ # func_version
+ # outputs to stdout the --version message.
+ func_version ()
+@@ -1666,6 +1694,9 @@ func_determine_path_separator
+ fi
+ case "$autoconf_minversion" in
+ 1.* | 2.[0-5]* | 2.6[0-3]*)
++ # if the version of autoconf in use is high enough, do not error
++ case "$(get_version autoconf)" in 1.* | 2.[0-5]* | 2.6[0-3]*) false ;; esac && \
++ func_warning "gnulib requires a newer version of autoconf than configure.ac ( $DEFAULT_AUTOCONF_MINVERSION > AC_PREREQ([$autoconf_minversion]) )" || \
+ func_fatal_error "minimum supported autoconf version is 2.64. Try adding AC_PREREQ([$DEFAULT_AUTOCONF_MINVERSION]) to your configure.ac." ;;
+ esac
+
diff --git a/tools/gnulib/patches/020-python-version.patch b/tools/gnulib/patches/020-python-version.patch
new file mode 100644
index 0000000000..f0182438d5
--- /dev/null
+++ b/tools/gnulib/patches/020-python-version.patch
@@ -0,0 +1,47 @@
+--- a/pygnulib/functions.py
++++ b/pygnulib/functions.py
+@@ -16,6 +16,8 @@
+ from __future__ import annotations
+
+ import os.path
++import re
++import subprocess as sp
+ from .constants import substart
+ from .GLConfig import GLConfig
+
+@@ -50,3 +52,15 @@ def rewrite_file_name(file_name: str, co
+ else: # file is not a special file
+ result = file_name
+ return os.path.normpath(result)
++
++def get_version(app: str) -> str:
++ result = sp.run([app, '--version'], capture_output=True, text=True)
++ version = re.sub(r".*[v ]([0-9])", r"\1", result.stdout)
++ version_lines = [line for line in version.splitlines() if re.search(r"^[0-9]", line)]
++ version = '\n'.join(version_lines) + "\n"
++ version = re.sub(r"[^.a-z0-9-\n].*", r"", version)
++ version = re.sub(r"^([0-9]*)[a-z-].*", r"\1", version, 1)
++ version = re.sub(r"\.0*([1-9])", r".\1", version)
++ version_lines = [line for line in version.splitlines() if line.strip()]
++ version = ''.join(version_lines[0]) + "\n"
++ return version.strip()
+--- a/pygnulib/GLImport.py
++++ b/pygnulib/GLImport.py
+@@ -40,6 +40,7 @@ from .constants import (
+ rmtree,
+ )
+ from .functions import rewrite_file_name
++from .functions import get_version
+ from .GLError import GLError
+ from .GLConfig import GLConfig
+ from .GLModuleSystem import GLModuleTable
+@@ -125,7 +126,8 @@ class GLImport:
+ for version in versions })
+ self.config.setAutoconfVersion(version)
+ if version < 2.64:
+- raise GLError(4, version)
++ # If the version of autoconf in use is high enough, do not error.
++ if float(get_version('autoconf')) < 2.64: raise GLError(4, version)
+
+ # Get other cached variables.
+ path = joinpath(self.config['m4base'], 'gnulib-cache.m4')
diff --git a/tools/gnulib/patches/120-unmangle-darwin-fts-h.patch b/tools/gnulib/patches/120-unmangle-darwin-fts-h.patch
new file mode 100644
index 0000000000..19e46b9103
--- /dev/null
+++ b/tools/gnulib/patches/120-unmangle-darwin-fts-h.patch
@@ -0,0 +1,19 @@
+--- /dev/null
++++ b/lib/fts.h
+@@ -0,0 +1,6 @@
++#ifdef __APPLE__
++# define _FTS_H_ 1
++# include <fts_.h>
++#else
++# include_next <fts.h>
++#endif
+--- a/modules/fts
++++ b/modules/fts
+@@ -2,6 +2,7 @@ Description:
+ Traverse a file hierarchy.
+
+ Files:
++lib/fts.h
+ lib/fts_.h
+ lib/fts.c
+ lib/fts-cycle.c
diff --git a/tools/gnulib/patches/150-portable-tdestroy.patch b/tools/gnulib/patches/150-portable-tdestroy.patch
index 39c291f196..8cae7504c9 100644
--- a/tools/gnulib/patches/150-portable-tdestroy.patch
+++ b/tools/gnulib/patches/150-portable-tdestroy.patch
@@ -107,7 +107,7 @@
+#endif /* defined(_LIBC) || GNULIB_defined_tdestroy */
--- a/m4/search_h.m4
+++ b/m4/search_h.m4
-@@ -39,7 +39,7 @@ AC_DEFUN_ONCE([gl_SEARCH_H],
+@@ -41,7 +41,7 @@ AC_DEFUN_ONCE([gl_SEARCH_H],
dnl Check for declarations of anything we want to poison if the
dnl corresponding gnulib module is not in use.
gl_WARN_ON_USE_PREPARE([[#include <search.h>
@@ -116,7 +116,7 @@
AC_REQUIRE([AC_C_RESTRICT])
])
-@@ -75,8 +75,10 @@ AC_DEFUN([gl_SEARCH_H_DEFAULTS],
+@@ -77,8 +77,10 @@ AC_DEFUN([gl_SEARCH_H_DEFAULTS],
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_LFIND], [1])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_LSEARCH], [1])
dnl Assume proper GNU behavior unless another module says otherwise.
@@ -133,7 +133,7 @@
])
--- a/m4/tsearch.m4
+++ b/m4/tsearch.m4
-@@ -9,6 +9,7 @@ AC_DEFUN([gl_FUNC_TSEARCH],
+@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_TSEARCH],
AC_REQUIRE([gl_SEARCH_H_DEFAULTS])
gl_CHECK_FUNCS_ANDROID([tsearch], [[#include <search.h>]])
gl_CHECK_FUNCS_ANDROID([twalk], [[#include <search.h>]])
@@ -141,7 +141,7 @@
if test $ac_cv_func_tsearch = yes; then
dnl On OpenBSD 4.0, the return value of tdelete() is incorrect.
AC_REQUIRE([AC_PROG_CC])
-@@ -50,6 +51,7 @@ main ()
+@@ -52,6 +53,7 @@ main ()
*no)
REPLACE_TSEARCH=1
REPLACE_TWALK=1
@@ -149,7 +149,7 @@
;;
esac
else
-@@ -64,6 +66,12 @@ main ()
+@@ -66,6 +68,12 @@ main ()
future*) REPLACE_TWALK=1 ;;
esac
fi
@@ -162,8 +162,8 @@
])
# Prerequisites of lib/tsearch.c.
---- a/modules/search
-+++ b/modules/search
+--- a/modules/search-h
++++ b/modules/search-h
@@ -37,8 +37,10 @@ search.h: search.in.h $(top_builddir)/co
-e 's/@''GNULIB_MDA_LSEARCH''@/$(GNULIB_MDA_LSEARCH)/g' \
-e 's|@''HAVE_TSEARCH''@|$(HAVE_TSEARCH)|g' \
@@ -177,7 +177,7 @@
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
--- a/modules/tsearch
+++ b/modules/tsearch
-@@ -11,7 +11,12 @@ search
+@@ -11,7 +11,12 @@ search-h
configure.ac:
gl_FUNC_TSEARCH
gl_CONDITIONAL([GL_COND_OBJ_TSEARCH],
diff --git a/tools/gnulib/patches/160-flag-reallocarray.patch b/tools/gnulib/patches/160-flag-reallocarray.patch
index 8ffe273e11..7c88c0de37 100644
--- a/tools/gnulib/patches/160-flag-reallocarray.patch
+++ b/tools/gnulib/patches/160-flag-reallocarray.patch
@@ -1,6 +1,6 @@
--- a/lib/ialloc.h
+++ b/lib/ialloc.h
-@@ -106,6 +106,8 @@ icalloc (idx_t n, idx_t s)
+@@ -91,6 +91,8 @@ icalloc (idx_t n, idx_t s)
return calloc (n, s);
}
@@ -9,8 +9,8 @@
/* ireallocarray (ptr, num, size) is like reallocarray (ptr, num, size).
It returns a non-NULL pointer to num * size bytes of memory.
Upon failure, it returns NULL with errno set. */
-@@ -131,6 +133,8 @@ ireallocarray (void *p, idx_t n, idx_t s
- return _gl_alloc_nomem ();
+@@ -102,6 +104,8 @@ ireallocarray (void *p, idx_t n, idx_t s
+ : _gl_alloc_nomem ());
}
+#endif /* GNULIB_REALLOCARRAY */
@@ -21,7 +21,7 @@
--- a/lib/xmalloc.c
+++ b/lib/xmalloc.c
@@ -51,12 +51,16 @@ ximalloc (idx_t s)
- return nonnull (imalloc (s));
+ return check_nonnull (imalloc (s));
}
+#if GNULIB_REALLOCARRAY
@@ -38,7 +38,7 @@
with error checking. */
@@ -75,6 +79,8 @@ xirealloc (void *p, idx_t s)
- return nonnull (irealloc (p, s));
+ return check_nonnull (irealloc (p, s));
}
+#if GNULIB_REALLOCARRAY
@@ -57,7 +57,24 @@
new size. The new array will contain at least N_INCR_MIN more
--- a/lib/xalloc.h
+++ b/lib/xalloc.h
-@@ -129,6 +129,7 @@ char *xstrdup (char const *str)
+@@ -81,10 +81,16 @@ void *xrealloc (void *p, size_t s)
+ _GL_ATTRIBUTE_ALLOC_SIZE ((2));
+ void *xirealloc (void *p, idx_t s)
+ _GL_ATTRIBUTE_ALLOC_SIZE ((2)) _GL_ATTRIBUTE_RETURNS_NONNULL;
++
++# if GNULIB_REALLOCARRAY
++
+ void *xreallocarray (void *p, size_t n, size_t s)
+ _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
+ void *xireallocarray (void *p, idx_t n, idx_t s)
+ _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)) _GL_ATTRIBUTE_RETURNS_NONNULL;
++
++# endif /* GNULIB_REALLOCARRAY */
++
+ void *x2realloc (void *p, size_t *ps) /* superseded by xpalloc */
+ _GL_ATTRIBUTE_RETURNS_NONNULL;
+ void *x2nrealloc (void *p, size_t *pn, size_t s) /* superseded by xpalloc */
+@@ -129,6 +135,7 @@ char *xstrdup (char const *str)
# define XCALLOC(n, t) \
((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
@@ -65,7 +82,7 @@
/* Allocate an array of N objects, each with S bytes of memory,
dynamically, with error checking. S must be nonzero. */
-@@ -156,6 +157,8 @@ char *xcharalloc (size_t n)
+@@ -156,6 +163,8 @@ char *xcharalloc (size_t n)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
_GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL;
@@ -76,26 +93,15 @@
--- a/lib/safe-alloc.h
+++ b/lib/safe-alloc.h
-@@ -36,6 +36,8 @@ _GL_INLINE_HEADER_BEGIN
- # define SAFE_ALLOC_INLINE _GL_INLINE
+@@ -37,7 +37,6 @@ _GL_INLINE_HEADER_BEGIN
+ extern "C" {
#endif
-+#if GNULIB_REALLOCARRAY
-+
- /* Don't call these directly - use the macros below. */
- SAFE_ALLOC_INLINE void *
- safe_alloc_realloc_n (void *ptr, size_t count, size_t size)
-@@ -51,6 +53,9 @@ safe_alloc_realloc_n (void *ptr, size_t
- #endif
- return ptr;
- }
-+
-+#endif /* GNULIB_REALLOCARRAY */
-+
+-
+ /* Don't call this directly - use the macros below. */
_GL_ATTRIBUTE_NODISCARD SAFE_ALLOC_INLINE int
safe_alloc_check (void *ptr)
- {
-@@ -84,6 +89,8 @@ safe_alloc_check (void *ptr)
+@@ -72,6 +71,8 @@ safe_alloc_check (void *ptr)
#define ALLOC_N(ptr, count) \
safe_alloc_check ((ptr) = calloc (count, sizeof *(ptr)))
@@ -104,12 +110,85 @@
/**
* ALLOC_N_UNINITIALIZED:
* @ptr: pointer to allocated memory
-@@ -112,6 +119,8 @@ safe_alloc_check (void *ptr)
+@@ -100,6 +101,8 @@ safe_alloc_check (void *ptr)
#define REALLOC_N(ptr, count) \
- safe_alloc_check ((ptr) = safe_alloc_realloc_n (ptr, count, sizeof *(ptr)))
+ safe_alloc_check ((ptr) = reallocarray (ptr, count, sizeof *(ptr)))
+#endif /* GNULIB_REALLOCARRAY */
+
/**
* FREE:
* @ptr: pointer holding address to be freed
+--- a/lib/dfa.c
++++ b/lib/dfa.c
+@@ -1620,6 +1620,8 @@ lex (struct dfa *dfa)
+ }
+ }
+
++#if GNULIB_REALLOCARRAY
++
+ static void
+ addtok_mb (struct dfa *dfa, token t, char mbprop)
+ {
+@@ -1674,6 +1676,8 @@ addtok_mb (struct dfa *dfa, token t, cha
+ }
+ }
+
++#endif /* GNULIB_REALLOCARRAY */
++
+ static void addtok_wc (struct dfa *dfa, wint_t wc);
+
+ /* Add the given token to the parse tree, maintaining the depth count and
+@@ -2934,6 +2938,8 @@ dfaanalyze (struct dfa *d, bool searchfl
+ free (tmp.elems);
+ }
+
++#if GNULIB_REALLOCARRAY
++
+ /* Make sure D's state arrays are large enough to hold NEW_STATE. */
+ static void
+ realloc_trans_if_necessary (struct dfa *d)
+@@ -2969,6 +2975,8 @@ realloc_trans_if_necessary (struct dfa *
+ }
+ }
+
++#endif /* GNULIB_REALLOCARRAY */
++
+ /*
+ Calculate the transition table for a new state derived from state s
+ for a compiled dfa d after input character uc, and return the new
+@@ -4010,6 +4018,8 @@ freelist (char **cpp)
+ free (*cpp++);
+ }
+
++#if GNULIB_REALLOCARRAY
++
+ static char **
+ enlistnew (char **cpp, char *new)
+ {
+@@ -4046,6 +4056,8 @@ enlist (char **cpp, char const *str, idx
+ return enlistnew (cpp, ximemdup0 (str, len));
+ }
+
++#endif /* GNULIB_REALLOCARRAY */
++
+ /* Given pointers to two strings, return a pointer to an allocated
+ list of their distinct common substrings. */
+ static char **
+--- a/lib/readtokens.c
++++ b/lib/readtokens.c
+@@ -128,6 +128,8 @@ readtoken (FILE *stream,
+ return i;
+ }
+
++#if GNULIB_REALLOCARRAY
++
+ /* Build a NULL-terminated array of pointers to tokens
+ read from STREAM. Return the number of tokens read.
+ All storage is obtained through calls to xmalloc-like functions.
+@@ -190,3 +192,5 @@ readtokens (FILE *stream,
+ free (lengths);
+ return n_tokens;
+ }
++
++#endif /* GNULIB_REALLOCARRAY */
diff --git a/tools/gnulib/patches/190-stdc-m4-no-cache.patch b/tools/gnulib/patches/190-stdc-m4-no-cache.patch
new file mode 100644
index 0000000000..1505da8402
--- /dev/null
+++ b/tools/gnulib/patches/190-stdc-m4-no-cache.patch
@@ -0,0 +1,59 @@
+--- a/m4/std-gnu11.m4
++++ b/m4/std-gnu11.m4
+@@ -185,8 +185,7 @@ AC_LANG_POP(C++)dnl
+ # else ACTION-IF-UNAVAILABLE.
+ AC_DEFUN([_AC_C_STD_TRY],
+ [AC_MSG_CHECKING([for $CC option to enable ]m4_translit($1, [c], [C])[ features])
+-AC_CACHE_VAL(ac_cv_prog_cc_$1,
+-[ac_cv_prog_cc_$1=no
++ac_cv_prog_cc_$1=no
+ ac_save_CC=$CC
+ AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
+ for ac_arg in '' $4
+@@ -197,7 +196,6 @@ do
+ done
+ rm -f conftest.$ac_ext
+ CC=$ac_save_CC
+-])# AC_CACHE_VAL
+ ac_prog_cc_stdc_options=
+ case "x$ac_cv_prog_cc_$1" in
+ x)
+@@ -523,8 +521,7 @@ fi
+ AC_DEFUN([_AC_CXX_STD_TRY],
+ [AC_MSG_CHECKING([for $CXX option to enable ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[ features])
+ AC_LANG_PUSH(C++)dnl
+-AC_CACHE_VAL(ac_cv_prog_cxx_$1,
+-[ac_cv_prog_cxx_$1=no
++ac_cv_prog_cxx_$1=no
+ ac_save_CXX=$CXX
+ AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
+ for ac_arg in '' $4
+@@ -535,7 +532,6 @@ do
+ done
+ rm -f conftest.$ac_ext
+ CXX=$ac_save_CXX
+-])# AC_CACHE_VAL
+ ac_prog_cxx_stdcxx_options=
+ case "x$ac_cv_prog_cxx_$1" in
+ x)
+--- a/m4/std-gnu23.m4
++++ b/m4/std-gnu23.m4
+@@ -696,8 +696,7 @@ AC_DEFUN([_AC_PROG_CC_STDC_EDITION_TRY],
+ [AC_REQUIRE([_AC_C_C$1_TEST_PROGRAM])]dnl
+ [AS_IF([test x$ac_prog_cc_stdc = xno],
+ [AC_MSG_CHECKING([for $CC option to enable C$1 features])
+-AC_CACHE_VAL([ac_cv_prog_cc_c$1],
+-[ac_cv_prog_cc_c$1=no
++ac_cv_prog_cc_c$1=no
+ ac_save_CC=$CC
+ AC_LANG_CONFTEST([AC_LANG_DEFINES_PROVIDED][$][ac_c_conftest_c$1_program])
+ for ac_arg in '' m4_normalize(m4_defn([_AC_C_C$1_OPTIONS]))
+@@ -707,7 +706,7 @@ do
+ test "x$ac_cv_prog_cc_c$1" != "xno" && break
+ done
+ rm -f conftest.$ac_ext
+-CC=$ac_save_CC])
++CC=$ac_save_CC
+ AS_IF([test "x$ac_cv_prog_cc_c$1" = xno],
+ [AC_MSG_RESULT([unsupported])],
+ [AS_IF([test "x$ac_cv_prog_cc_c$1" = x],
diff --git a/tools/gnulib/patches/195-c99-use-std-gnu23.patch b/tools/gnulib/patches/195-c99-use-std-gnu23.patch
new file mode 100644
index 0000000000..11c2f3297c
--- /dev/null
+++ b/tools/gnulib/patches/195-c99-use-std-gnu23.patch
@@ -0,0 +1,10 @@
+--- a/modules/c99
++++ b/modules/c99
+@@ -5,6 +5,7 @@ Files:
+
+ Depends-on:
+ std-gnu11
++std-gnu23
+
+ configure.ac:
+
diff --git a/tools/gnulib/patches/200-force-disable-after-configure.patch b/tools/gnulib/patches/200-force-disable-after-configure.patch
new file mode 100644
index 0000000000..082820a344
--- /dev/null
+++ b/tools/gnulib/patches/200-force-disable-after-configure.patch
@@ -0,0 +1,57 @@
+--- a/lib/fcntl.c
++++ b/lib/fcntl.c
+@@ -198,6 +198,8 @@ static int klibc_fcntl (int fd, int acti
+ FD_CLOEXEC is portable, but other flags may be present); otherwise
+ return -1 and set errno. */
+
++#if (GNULIB_defined_fcntl || GNULIB_defined_rpl_fcntl)
++
+ int
+ fcntl (int fd, int action, /* arg */...)
+ #undef fcntl
+@@ -443,6 +445,8 @@ fcntl (int fd, int action, /* arg */...)
+ return result;
+ }
+
++#endif /* (GNULIB_defined_fcntl || GNULIB_defined_rpl_fcntl) */
++
+ static int
+ rpl_fcntl_DUPFD (int fd, int target)
+ {
+--- a/lib/stdlib.in.h
++++ b/lib/stdlib.in.h
+@@ -1549,11 +1549,17 @@ _GL_FUNCDECL_RPL (reallocarray, void *,
+ _GL_ATTRIBUTE_NODISCARD);
+ _GL_CXXALIAS_RPL (reallocarray, void *,
+ (void *ptr, size_t nmemb, size_t size));
++# if !GNULIB_defined_rpl_reallocarray
++# define GNULIB_defined_rpl_reallocarray 1
++# endif
+ # else
+ # if ! @HAVE_REALLOCARRAY@
+ _GL_FUNCDECL_SYS (reallocarray, void *,
+ (void *ptr, size_t nmemb, size_t size),
+ _GL_ATTRIBUTE_NODISCARD);
++# if !GNULIB_defined_reallocarray
++# define GNULIB_defined_reallocarray 1
++# endif
+ # endif
+ _GL_CXXALIAS_SYS (reallocarray, void *,
+ (void *ptr, size_t nmemb, size_t size));
+--- a/lib/reallocarray.c
++++ b/lib/reallocarray.c
+@@ -23,6 +23,8 @@
+ #include <stdlib.h>
+ #include <errno.h>
+
++#if (GNULIB_defined_reallocarray || GNULIB_defined_rpl_reallocarray)
++
+ void *
+ reallocarray (void *ptr, size_t nmemb, size_t size)
+ {
+@@ -36,3 +38,5 @@ reallocarray (void *ptr, size_t nmemb, s
+ /* Call realloc, setting errno to ENOMEM on failure. */
+ return realloc (ptr, nbytes);
+ }
++
++#endif /* (GNULIB_defined_reallocarray || GNULIB_defined_rpl_reallocarray) */
diff --git a/tools/gnulib/patches/320-modules-fallocate-posix.patch b/tools/gnulib/patches/320-modules-fallocate-posix.patch
new file mode 100644
index 0000000000..4cfd5bdcd6
--- /dev/null
+++ b/tools/gnulib/patches/320-modules-fallocate-posix.patch
@@ -0,0 +1,326 @@
+--- /dev/null
++++ b/modules/fallocate-posix
+@@ -0,0 +1,43 @@
++Description:
++posix_fallocate function that is glibc compatible.
++
++Files:
++lib/posix_fallocate.c
++m4/fcntl_h.m4
++m4/posix_fallocate.m4
++
++Depends-on:
++errno [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
++fcntl [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
++fstat [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
++ftruncate [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
++pread [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
++pwrite [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
++stdint [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
++sys_stat [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
++unistd [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
++fcntl-h
++
++configure.ac:
++gl_FUNC_POSIX_FALLOCATE
++gl_CONDITIONAL([GL_COND_OBJ_POSIX_FALLOCATE],
++ [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1])
++AM_COND_IF([GL_COND_OBJ_POSIX_FALLOCATE], [
++ gl_PREREQ_POSIX_FALLOCATE
++])
++gl_MODULE_INDICATOR([fallocate-posix])
++gl_FCNTL_MODULE_INDICATOR([fallocate-posix])
++
++Makefile.am:
++if GL_COND_OBJ_POSIX_FALLOCATE
++lib_SOURCES += posix_fallocate.c
++endif
++
++Include:
++<fcntl.h>
++
++License:
++LGPLv2+
++
++Maintainer:
++all
+--- /dev/null
++++ b/m4/posix_fallocate.m4
+@@ -0,0 +1,20 @@
++# posix_fallocate.m4 serial 1
++dnl Copyright (C) 2024 Free Software Foundation, Inc.
++dnl This file is free software; the Free Software Foundation
++dnl gives unlimited permission to copy and/or distribute it,
++dnl with or without modifications, as long as this notice is preserved.
++
++AC_DEFUN([gl_FUNC_POSIX_FALLOCATE],
++[
++ AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
++ gl_CHECK_FUNCS_ANDROID([posix_fallocate], [[#include <fcntl.h>]])
++ if test "$ac_cv_func_posix_fallocate" = no; then
++ HAVE_FALLOCATE_POSIX=0
++ case "$gl_cv_onwards_func_posix_fallocate" in
++ future*) REPLACE_FALLOCATE_POSIX=1 ;;
++ esac
++ fi
++])
++
++# Prerequisites of lib/posix_fallocate.c.
++AC_DEFUN([gl_PREREQ_POSIX_FALLOCATE], [:])
+--- a/m4/fcntl_h.m4
++++ b/m4/fcntl_h.m4
+@@ -26,7 +26,7 @@ AC_DEFUN_ONCE([gl_FCNTL_H],
+ dnl corresponding gnulib module is not in use, if it is not common
+ dnl enough to be declared everywhere.
+ gl_WARN_ON_USE_PREPARE([[#include <fcntl.h>
+- ]], [fcntl openat])
++ ]], [fcntl openat posix_fallocate])
+ ])
+
+ # gl_FCNTL_MODULE_INDICATOR([modulename])
+@@ -53,6 +53,7 @@ AC_DEFUN([gl_FCNTL_H_REQUIRE_DEFAULTS],
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NONBLOCKING])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPENAT])
++ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FALLOCATE_POSIX])
+ dnl Support Microsoft deprecated alias function names by default.
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CREAT], [1])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_OPEN], [1])
+@@ -64,10 +65,12 @@ AC_DEFUN([gl_FCNTL_H_REQUIRE_DEFAULTS],
+ AC_DEFUN([gl_FCNTL_H_DEFAULTS],
+ [
+ dnl Assume proper GNU behavior unless another module says otherwise.
+- HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL])
+- HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT])
+- REPLACE_CREAT=0; AC_SUBST([REPLACE_CREAT])
+- REPLACE_FCNTL=0; AC_SUBST([REPLACE_FCNTL])
+- REPLACE_OPEN=0; AC_SUBST([REPLACE_OPEN])
+- REPLACE_OPENAT=0; AC_SUBST([REPLACE_OPENAT])
++ HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL])
++ HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT])
++ HAVE_FALLOCATE_POSIX=1; AC_SUBST([HAVE_FALLOCATE_POSIX])
++ REPLACE_CREAT=0; AC_SUBST([REPLACE_CREAT])
++ REPLACE_FCNTL=0; AC_SUBST([REPLACE_FCNTL])
++ REPLACE_OPEN=0; AC_SUBST([REPLACE_OPEN])
++ REPLACE_OPENAT=0; AC_SUBST([REPLACE_OPENAT])
++ REPLACE_FALLOCATE_POSIX=0; AC_SUBST([REPLACE_FALLOCATE_POSIX])
+ ])
+--- a/modules/fcntl-h
++++ b/modules/fcntl-h
+@@ -40,14 +40,17 @@ fcntl.h: fcntl.in.h $(top_builddir)/conf
+ -e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \
+ -e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \
+ -e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \
++ -e 's/@''GNULIB_FALLOCATE_POSIX''@/$(GNULIB_FALLOCATE_POSIX)/g' \
+ -e 's/@''GNULIB_MDA_CREAT''@/$(GNULIB_MDA_CREAT)/g' \
+ -e 's/@''GNULIB_MDA_OPEN''@/$(GNULIB_MDA_OPEN)/g' \
+ -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \
+ -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \
++ -e 's|@''HAVE_FALLOCATE_POSIX''@|$(HAVE_FALLOCATE_POSIX)|g' \
+ -e 's|@''REPLACE_CREAT''@|$(REPLACE_CREAT)|g' \
+ -e 's|@''REPLACE_FCNTL''@|$(REPLACE_FCNTL)|g' \
+ -e 's|@''REPLACE_OPEN''@|$(REPLACE_OPEN)|g' \
+ -e 's|@''REPLACE_OPENAT''@|$(REPLACE_OPENAT)|g' \
++ -e 's|@''REPLACE_FALLOCATE_POSIX''@|$(REPLACE_FALLOCATE_POSIX)|g' \
+ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+--- a/lib/fcntl.in.h
++++ b/lib/fcntl.in.h
+@@ -241,6 +241,33 @@ _GL_WARN_ON_USE (openat, "openat is not
+ # endif
+ #endif
+
++#if @GNULIB_FALLOCATE_POSIX@
++# if @REPLACE_FALLOCATE_POSIX@
++# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
++# undef posix_fallocate
++# define posix_fallocate rpl_posix_fallocate
++# endif
++_GL_FUNCDECL_RPL (posix_fallocate, int,
++ (int fd, off_t offset, off_t len));
++_GL_CXXALIAS_RPL (posix_fallocate, int,
++ (int fd, off_t offset, off_t len));
++# else
++# if !@HAVE_FALLOCATE_POSIX@
++_GL_FUNCDECL_SYS (posix_fallocate, int,
++ (int fd, off_t offset, off_t len));
++# endif
++_GL_CXXALIAS_SYS (posix_fallocate, int,
++ (int fd, off_t offset, off_t len));
++# endif
++_GL_CXXALIASWARN (posix_fallocate);
++#elif defined GNULIB_POSIXCHECK
++# undef posix_fallocate
++# if HAVE_RAW_DECL_POSIX_FALLOCATE
++_GL_WARN_ON_USE (posix_fallocate, "posix_fallocate is not portable - "
++ "use gnulib module fallocate-posix for portability");
++# endif
++#endif
++
+
+ /* Fix up the FD_* macros, only known to be missing on mingw. */
+
+--- /dev/null
++++ b/lib/posix_fallocate.c
+@@ -0,0 +1,150 @@
++/* posix_fallocate function that is glibc compatible.
++
++ Copyright (C) 2024 Free Software Foundation, Inc.
++
++ This file is free software: you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation; either version 2.1 of the
++ License, or (at your option) any later version.
++
++ This file 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 Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see <https://www.gnu.org/licenses/>. */
++
++#include <config.h>
++
++#include <errno.h>
++#include <fcntl.h>
++#include <unistd.h>
++#include <stdint.h>
++#include <sys/fcntl.h>
++#include <sys/stat.h>
++
++#ifdef __APPLE__
++# include <sys/param.h>
++# include <sys/mount.h>
++#else
++# include <sys/statfs.h>
++#endif
++
++/* Reserve storage for the data of the file associated with FD. This
++ emulation is far from perfect, but the kernel cannot do not much
++ better for network file systems, either. */
++
++int
++posix_fallocate (int fd, off_t offset, off_t len)
++{
++ int ret;
++ struct stat st;
++
++ if (fd < 0 || offset < 0 || len < 0)
++ return EINVAL;
++
++ /* Perform overflow check. The outer cast relies on a GCC
++ extension. */
++ if ((off_t) ((uint64_t) offset + (uint64_t) len) < 0)
++ return EFBIG;
++
++ /* pwrite below will not do the right thing in O_APPEND mode. */
++ {
++ int flags = fcntl (fd, F_GETFL, 0);
++ if (flags < 0 || (flags & O_APPEND) != 0)
++ return EBADF;
++ }
++
++ /* We have to make sure that this is really a regular file. */
++ if (fstat (fd, &st) != 0)
++ return EBADF;
++ if (S_ISFIFO (st.st_mode))
++ return ESPIPE;
++ if (! S_ISREG (st.st_mode))
++ return ENODEV;
++
++ if (len == 0)
++ {
++ /* This is racy, but there is no good way to satisfy a
++ zero-length allocation request. */
++ if (st.st_size < offset)
++ {
++ ret = ftruncate (fd, offset);
++
++ if (ret != 0)
++ ret = errno;
++ return ret;
++ }
++ return ret;
++ }
++
++#ifdef __APPLE__
++ fstore_t sto = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, offset + len, 0};
++ /* allocate continuous */
++ ret = fcntl (fd, F_PREALLOCATE, &sto);
++ if (ret < 0)
++ {
++ /* allocate non-continuous */
++ sto.fst_flags = F_ALLOCATEALL;
++ ret = fcntl (fd, F_PREALLOCATE, &sto);
++ if (ret < 0)
++ {
++ return ret;
++ }
++ }
++ ret = ftruncate(fd, offset + len);
++#else
++
++ /* Minimize data transfer for network file systems, by issuing
++ single-byte write requests spaced by the file system block size.
++ (Most local file systems have fallocate support, so this fallback
++ code is not used there.) */
++
++ unsigned increment;
++ {
++ struct statfs f;
++
++ if (fstatfs (fd, &f) != 0)
++ return errno;
++ if (f.f_bsize == 0)
++ increment = 512;
++ else if (f.f_bsize < 4096)
++ increment = f.f_bsize;
++ else
++ /* NFS does not propagate the block size of the underlying
++ storage and may report a much larger value which would still
++ leave holes after the loop below, so we cap the increment at
++ 4096. */
++ increment = 4096;
++ }
++
++ /* Write a null byte to every block. This is racy; we currently
++ lack a better option. Compare-and-swap against a file mapping
++ might additional local races, but requires interposition of a
++ signal handler to catch SIGBUS. */
++ for (offset += (len - 1) % increment; len > 0; offset += increment)
++ {
++ len -= increment;
++
++ if (offset < st.st_size)
++ {
++ unsigned char c;
++ ssize_t rsize = pread (fd, &c, 1, offset);
++
++ if (rsize < 0)
++ return errno;
++ /* If there is a non-zero byte, the block must have been
++ allocated already. */
++ else if (rsize == 1 && c != 0)
++ continue;
++ }
++
++ if (pwrite (fd, "", 1, offset) != 1)
++ return errno;
++ }
++
++#endif /* __APPLE__ */
++
++ return ret;
++}
+--- a/MODULES.html.sh
++++ b/MODULES.html.sh
+@@ -2555,6 +2555,7 @@ func_all_modules ()
+ func_module execve
+ func_module execvp
+ func_module execvpe
++ func_module fallocate-posix
+ func_module fchdir
+ func_module fclose
+ func_module fcntl-h
diff --git a/tools/gnulib/patches/640-mem-hash-map.patch b/tools/gnulib/patches/640-mem-hash-map.patch
new file mode 100644
index 0000000000..aaebe545fa
--- /dev/null
+++ b/tools/gnulib/patches/640-mem-hash-map.patch
@@ -0,0 +1,494 @@
+From 5a842672e79a7a5f6be837c483be4f9901a4ecc0 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Wed, 30 Apr 2025 03:19:10 +0200
+Subject: [PATCH] New module mem-hash-map.
+
+* lib/mem-hash-map.h: New file, from GNU gettext.
+* lib/mem-hash-map.c: New file, from GNU gettext.
+* modules/mem-hash-map: New file, from GNU gettext.
+---
+ ChangeLog | 7 +
+ lib/mem-hash-map.c | 352 +++++++++++++++++++++++++++++++++++++++++++
+ lib/mem-hash-map.h | 90 +++++++++++
+ modules/mem-hash-map | 25 +++
+ 4 files changed, 474 insertions(+)
+ create mode 100644 lib/mem-hash-map.c
+ create mode 100644 lib/mem-hash-map.h
+ create mode 100644 modules/mem-hash-map
+
+--- /dev/null
++++ b/lib/mem-hash-map.c
+@@ -0,0 +1,352 @@
++/* Simple hash table (no removals) where the keys are memory blocks.
++ Copyright (C) 1994-2025 Free Software Foundation, Inc.
++ Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, October 1994.
++
++ This file 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.
++
++ This file 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 this program. If not, see <https://www.gnu.org/licenses/>. */
++
++#include <config.h>
++
++/* Specification. */
++#include "mem-hash-map.h"
++
++#include <stdlib.h>
++#include <string.h>
++#include <stdio.h>
++#include <limits.h>
++#include <sys/types.h>
++
++#include "next-prime.h"
++
++/* Since this simple implementation of hash tables allows only insertion, no
++ removal of entries, the right data structure for the memory holding all keys
++ is an obstack. */
++#include "obstack.h"
++
++/* Use checked memory allocation. */
++#include "xalloc.h"
++
++#define obstack_chunk_alloc xmalloc
++#define obstack_chunk_free free
++
++
++typedef struct hash_entry
++{
++ size_t used; /* Hash code of the key, or 0 for an unused entry. */
++ const void *key; /* Key. */
++ size_t keylen;
++ void *data; /* Value. */
++ struct hash_entry *next;
++}
++hash_entry;
++
++
++/* Initialize a hash table. INIT_SIZE > 1 is the initial number of available
++ entries.
++ Return 0 always. */
++int
++hash_init (hash_table *htab, size_t init_size)
++{
++ /* We need the size to be a prime. */
++ init_size = next_prime (init_size);
++
++ /* Initialize the data structure. */
++ htab->size = init_size;
++ htab->filled = 0;
++ htab->first = NULL;
++ htab->table = XCALLOC (init_size + 1, hash_entry);
++
++ obstack_init (&htab->mem_pool);
++
++ return 0;
++}
++
++
++/* Delete a hash table's contents.
++ Return 0 always. */
++int
++hash_destroy (hash_table *htab)
++{
++ free (htab->table);
++ obstack_free (&htab->mem_pool, NULL);
++ return 0;
++}
++
++
++/* Compute a hash code for a key consisting of KEYLEN bytes starting at KEY
++ in memory. */
++static size_t
++compute_hashval (const void *key, size_t keylen)
++{
++ size_t cnt;
++ size_t hval;
++
++ /* Compute the hash value for the given string. The algorithm
++ is taken from [Aho,Sethi,Ullman], fixed according to
++ https://haible.de/bruno/hashfunc.html. */
++ cnt = 0;
++ hval = keylen;
++ while (cnt < keylen)
++ {
++ hval = (hval << 9) | (hval >> (sizeof (size_t) * CHAR_BIT - 9));
++ hval += (size_t) *(((const char *) key) + cnt++);
++ }
++ return hval != 0 ? hval : ~((size_t) 0);
++}
++
++
++/* References:
++ [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
++ [Knuth] The Art of Computer Programming, part3 (6.4) */
++
++/* Look up a given key in the hash table.
++ Return the index of the entry, if present, or otherwise the index a free
++ entry where it could be inserted. */
++static size_t
++lookup (const hash_table *htab,
++ const void *key, size_t keylen,
++ size_t hval)
++{
++ size_t hash;
++ size_t idx;
++ hash_entry *table = htab->table;
++
++ /* First hash function: simply take the modul but prevent zero. */
++ hash = 1 + hval % htab->size;
++
++ idx = hash;
++
++ if (table[idx].used)
++ {
++ if (table[idx].used == hval && table[idx].keylen == keylen
++ && memcmp (table[idx].key, key, keylen) == 0)
++ return idx;
++
++ /* Second hash function as suggested in [Knuth]. */
++ hash = 1 + hval % (htab->size - 2);
++
++ do
++ {
++ if (idx <= hash)
++ idx = htab->size + idx - hash;
++ else
++ idx -= hash;
++
++ /* If entry is found use it. */
++ if (table[idx].used == hval && table[idx].keylen == keylen
++ && memcmp (table[idx].key, key, keylen) == 0)
++ return idx;
++ }
++ while (table[idx].used);
++ }
++ return idx;
++}
++
++
++/* Look up the value of a key in the given table.
++ If found, return 0 and set *RESULT to it. Otherwise return -1. */
++int
++hash_find_entry (const hash_table *htab, const void *key, size_t keylen,
++ void **result)
++{
++ hash_entry *table = htab->table;
++ size_t idx = lookup (htab, key, keylen, compute_hashval (key, keylen));
++
++ if (table[idx].used == 0)
++ return -1;
++
++ *result = table[idx].data;
++ return 0;
++}
++
++
++/* Insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table at index IDX.
++ HVAL is the key's hash code. IDX depends on it. The table entry at index
++ IDX is known to be unused. */
++static void
++insert_entry_2 (hash_table *htab,
++ const void *key, size_t keylen,
++ size_t hval, size_t idx, void *data)
++{
++ hash_entry *table = htab->table;
++
++ table[idx].used = hval;
++ table[idx].key = key;
++ table[idx].keylen = keylen;
++ table[idx].data = data;
++
++ /* List the new value in the list. */
++ if (htab->first == NULL)
++ {
++ table[idx].next = &table[idx];
++ htab->first = &table[idx];
++ }
++ else
++ {
++ table[idx].next = htab->first->next;
++ htab->first->next = &table[idx];
++ htab->first = &table[idx];
++ }
++
++ ++htab->filled;
++}
++
++
++/* Grow the hash table. */
++static void
++resize (hash_table *htab)
++{
++ size_t old_size = htab->size;
++ hash_entry *table = htab->table;
++ size_t idx;
++
++ htab->size = next_prime (htab->size * 2);
++ htab->filled = 0;
++ htab->first = NULL;
++ htab->table = XCALLOC (1 + htab->size, hash_entry);
++
++ for (idx = 1; idx <= old_size; ++idx)
++ if (table[idx].used)
++ insert_entry_2 (htab, table[idx].key, table[idx].keylen,
++ table[idx].used,
++ lookup (htab, table[idx].key, table[idx].keylen,
++ table[idx].used),
++ table[idx].data);
++
++ free (table);
++}
++
++
++/* Try to insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table.
++ Return non-NULL (more precisely, the address of the KEY inside the table's
++ memory pool) if successful, or NULL if there is already an entry with the
++ given key. */
++const void *
++hash_insert_entry (hash_table *htab,
++ const void *key, size_t keylen,
++ void *data)
++{
++ size_t hval = compute_hashval (key, keylen);
++ hash_entry *table = htab->table;
++ size_t idx = lookup (htab, key, keylen, hval);
++
++ if (table[idx].used)
++ /* We don't want to overwrite the old value. */
++ return NULL;
++ else
++ {
++ /* An empty bucket has been found. */
++ void *keycopy = obstack_copy (&htab->mem_pool, key, keylen);
++ insert_entry_2 (htab, keycopy, keylen, hval, idx, data);
++ if (100 * htab->filled > 75 * htab->size)
++ /* Table is filled more than 75%. Resize the table. */
++ resize (htab);
++ return keycopy;
++ }
++}
++
++
++/* Insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table.
++ Return 0. */
++int
++hash_set_value (hash_table *htab,
++ const void *key, size_t keylen,
++ void *data)
++{
++ size_t hval = compute_hashval (key, keylen);
++ hash_entry *table = htab->table;
++ size_t idx = lookup (htab, key, keylen, hval);
++
++ if (table[idx].used)
++ {
++ /* Overwrite the old value. */
++ table[idx].data = data;
++ return 0;
++ }
++ else
++ {
++ /* An empty bucket has been found. */
++ void *keycopy = obstack_copy (&htab->mem_pool, key, keylen);
++ insert_entry_2 (htab, keycopy, keylen, hval, idx, data);
++ if (100 * htab->filled > 75 * htab->size)
++ /* Table is filled more than 75%. Resize the table. */
++ resize (htab);
++ return 0;
++ }
++}
++
++
++/* Steps *PTR forward to the next used entry in the given hash table. *PTR
++ should be initially set to NULL. Store information about the next entry
++ in *KEY, *KEYLEN, *DATA.
++ Return 0 normally, -1 when the whole hash table has been traversed. */
++int
++hash_iterate (hash_table *htab, void **ptr, const void **key, size_t *keylen,
++ void **data)
++{
++ hash_entry *curr;
++
++ if (*ptr == NULL)
++ {
++ if (htab->first == NULL)
++ return -1;
++ curr = htab->first;
++ }
++ else
++ {
++ if (*ptr == htab->first)
++ return -1;
++ curr = (hash_entry *) *ptr;
++ }
++ curr = curr->next;
++ *ptr = (void *) curr;
++
++ *key = curr->key;
++ *keylen = curr->keylen;
++ *data = curr->data;
++ return 0;
++}
++
++
++/* Steps *PTR forward to the next used entry in the given hash table. *PTR
++ should be initially set to NULL. Store information about the next entry
++ in *KEY, *KEYLEN, *DATAP. *DATAP is set to point to the storage of the
++ value; modifying **DATAP will modify the value of the entry.
++ Return 0 normally, -1 when the whole hash table has been traversed. */
++int
++hash_iterate_modify (hash_table *htab, void **ptr,
++ const void **key, size_t *keylen,
++ void ***datap)
++{
++ hash_entry *curr;
++
++ if (*ptr == NULL)
++ {
++ if (htab->first == NULL)
++ return -1;
++ curr = htab->first;
++ }
++ else
++ {
++ if (*ptr == htab->first)
++ return -1;
++ curr = (hash_entry *) *ptr;
++ }
++ curr = curr->next;
++ *ptr = (void *) curr;
++
++ *key = curr->key;
++ *keylen = curr->keylen;
++ *datap = &curr->data;
++ return 0;
++}
+--- /dev/null
++++ b/lib/mem-hash-map.h
+@@ -0,0 +1,90 @@
++/* Simple hash table (no removals) where the keys are memory blocks.
++ Copyright (C) 1995-2025 Free Software Foundation, Inc.
++
++ This file 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.
++
++ This file 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 this program. If not, see <https://www.gnu.org/licenses/>. */
++
++#ifndef _GL_MEM_HASH_MAP_H
++#define _GL_MEM_HASH_MAP_H
++
++#include <stddef.h>
++
++#include "obstack.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++struct hash_entry;
++
++typedef struct hash_table
++{
++ size_t size; /* Number of allocated entries. */
++ size_t filled; /* Number of used entries. */
++ struct hash_entry *first; /* Pointer to head of list of entries. */
++ struct hash_entry *table; /* Pointer to array of entries. */
++ struct obstack mem_pool; /* Memory pool holding the keys. */
++}
++hash_table;
++
++/* Initialize a hash table. INIT_SIZE > 1 is the initial number of available
++ entries.
++ Return 0 always. */
++extern int hash_init (hash_table *htab, size_t init_size);
++
++/* Delete a hash table's contents.
++ Return 0 always. */
++extern int hash_destroy (hash_table *htab);
++
++/* Look up the value of a key in the given table.
++ If found, return 0 and set *RESULT to it. Otherwise return -1. */
++extern int hash_find_entry (const hash_table *htab,
++ const void *key, size_t keylen,
++ void **result);
++
++/* Try to insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table.
++ Return non-NULL (more precisely, the address of the KEY inside the table's
++ memory pool) if successful, or NULL if there is already an entry with the
++ given key. */
++extern const void * hash_insert_entry (hash_table *htab,
++ const void *key, size_t keylen,
++ void *data);
++
++/* Insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table.
++ Return 0. */
++extern int hash_set_value (hash_table *htab,
++ const void *key, size_t keylen,
++ void *data);
++
++/* Steps *PTR forward to the next used entry in the given hash table. *PTR
++ should be initially set to NULL. Store information about the next entry
++ in *KEY, *KEYLEN, *DATA.
++ Return 0 normally, -1 when the whole hash table has been traversed. */
++extern int hash_iterate (hash_table *htab, void **ptr,
++ const void **key, size_t *keylen,
++ void **data);
++
++/* Steps *PTR forward to the next used entry in the given hash table. *PTR
++ should be initially set to NULL. Store information about the next entry
++ in *KEY, *KEYLEN, *DATAP. *DATAP is set to point to the storage of the
++ value; modifying **DATAP will modify the value of the entry.
++ Return 0 normally, -1 when the whole hash table has been traversed. */
++extern int hash_iterate_modify (hash_table *htab, void **ptr,
++ const void **key, size_t *keylen,
++ void ***datap);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* not _GL_MEM_HASH_MAP_H */
+--- /dev/null
++++ b/modules/mem-hash-map
+@@ -0,0 +1,25 @@
++Description:
++Simple hash table (no removals) where the keys are memory blocks.
++
++Files:
++lib/mem-hash-map.h
++lib/mem-hash-map.c
++
++Depends-on:
++next-prime
++obstack
++xalloc
++
++configure.ac:
++
++Makefile.am:
++lib_SOURCES += mem-hash-map.h mem-hash-map.c
++
++Include:
++"mem-hash-map.h"
++
++License:
++GPL
++
++Maintainer:
++Bruno Haible
diff --git a/tools/gnulib/patches/645-next-prime.patch b/tools/gnulib/patches/645-next-prime.patch
new file mode 100644
index 0000000000..66f482f5ec
--- /dev/null
+++ b/tools/gnulib/patches/645-next-prime.patch
@@ -0,0 +1,218 @@
+From 0b953ba82830f51ce9b939700705d238f9b0c0ba Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Wed, 30 Apr 2025 01:52:17 +0200
+Subject: [PATCH] New module next-prime.
+
+* lib/next-prime.h: New file, based on lib/hash.c.
+* lib/next-prime.c: New file, based on lib/hash.c.
+* modules/next-prime: New file.
+* lib/hash.c: Include next-prime.h.
+(is_prime, next_prime): Remove functions.
+* modules/hash (Depends-on): Add next-prime.
+---
+ ChangeLog | 10 +++++++++
+ lib/hash.c | 39 +-------------------------------
+ lib/next-prime.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
+ lib/next-prime.h | 41 +++++++++++++++++++++++++++++++++
+ modules/hash | 1 +
+ modules/next-prime | 24 ++++++++++++++++++++
+ 6 files changed, 133 insertions(+), 38 deletions(-)
+ create mode 100644 lib/next-prime.c
+ create mode 100644 lib/next-prime.h
+ create mode 100644 modules/next-prime
+
+--- a/lib/hash.c
++++ b/lib/hash.c
+@@ -27,6 +27,7 @@
+ #include "hash.h"
+
+ #include "bitrotate.h"
++#include "next-prime.h"
+ #include "xalloc-oversized.h"
+
+ #include <errno.h>
+@@ -390,44 +391,6 @@ hash_string (const char *string, size_t
+
+ #endif /* not USE_DIFF_HASH */
+
+-/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd
+- number at least equal to 11. */
+-
+-static bool _GL_ATTRIBUTE_CONST
+-is_prime (size_t candidate)
+-{
+- size_t divisor = 3;
+- size_t square = divisor * divisor;
+-
+- while (square < candidate && (candidate % divisor))
+- {
+- divisor++;
+- square += 4 * divisor;
+- divisor++;
+- }
+-
+- return (candidate % divisor ? true : false);
+-}
+-
+-/* Round a given CANDIDATE number up to the nearest prime, and return that
+- prime. Primes lower than 10 are merely skipped. */
+-
+-static size_t _GL_ATTRIBUTE_CONST
+-next_prime (size_t candidate)
+-{
+- /* Skip small primes. */
+- if (candidate < 10)
+- candidate = 10;
+-
+- /* Make it definitely odd. */
+- candidate |= 1;
+-
+- while (SIZE_MAX != candidate && !is_prime (candidate))
+- candidate += 2;
+-
+- return candidate;
+-}
+-
+ void
+ hash_reset_tuning (Hash_tuning *tuning)
+ {
+--- /dev/null
++++ b/lib/next-prime.c
+@@ -0,0 +1,56 @@
++/* Finding the next prime >= a given small integer.
++ Copyright (C) 1995-2025 Free Software Foundation, Inc.
++
++ This file is free software: you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation; either version 2.1 of the
++ License, or (at your option) any later version.
++
++ This file 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 Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see <https://www.gnu.org/licenses/>. */
++
++#include <config.h>
++
++/* Specification. */
++#include "next-prime.h"
++
++#include <stdint.h> /* for SIZE_MAX */
++
++/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd
++ number at least equal to 11. */
++static bool _GL_ATTRIBUTE_CONST
++is_prime (size_t candidate)
++{
++ size_t divisor = 3;
++ size_t square = divisor * divisor;
++
++ while (square < candidate && (candidate % divisor))
++ {
++ divisor++;
++ square += 4 * divisor;
++ divisor++;
++ }
++
++ return (candidate % divisor ? true : false);
++}
++
++size_t _GL_ATTRIBUTE_CONST
++next_prime (size_t candidate)
++{
++ /* Skip small primes. */
++ if (candidate < 10)
++ candidate = 10;
++
++ /* Make it definitely odd. */
++ candidate |= 1;
++
++ while (SIZE_MAX != candidate && !is_prime (candidate))
++ candidate += 2;
++
++ return candidate;
++}
+--- /dev/null
++++ b/lib/next-prime.h
+@@ -0,0 +1,41 @@
++/* Finding the next prime >= a given small integer.
++ Copyright (C) 1995-2025 Free Software Foundation, Inc.
++
++ This file is free software: you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation; either version 2.1 of the
++ License, or (at your option) any later version.
++
++ This file 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 Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see <https://www.gnu.org/licenses/>. */
++
++#ifndef _GL_NEXT_PRIME_H
++#define _GL_NEXT_PRIME_H
++
++/* This file uses _GL_ATTRIBUTE_CONST. */
++#if !_GL_CONFIG_H_INCLUDED
++ #error "Please include config.h first."
++#endif
++
++#include <stddef.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++
++/* Round a given CANDIDATE number up to the nearest prime, and return that
++ prime. Primes lower than 10 are merely skipped. */
++extern size_t _GL_ATTRIBUTE_CONST next_prime (size_t candidate);
++
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* _GL_NEXT_PRIME_H */
+--- a/modules/hash
++++ b/modules/hash
+@@ -10,6 +10,7 @@ bitrotate
+ calloc-posix
+ free-posix
+ malloc-posix
++next-prime
+ bool
+ stdint-h
+ xalloc-oversized
+--- /dev/null
++++ b/modules/next-prime
+@@ -0,0 +1,24 @@
++Description:
++Finding the next prime >= a given small integer.
++
++Files:
++lib/next-prime.h
++lib/next-prime.c
++
++Depends-on:
++bool
++stdint-h
++
++configure.ac:
++
++Makefile.am:
++lib_SOURCES += next-prime.h next-prime.c
++
++Include:
++"next-prime.h"
++
++License:
++LGPLv2+
++
++Maintainer:
++all
diff --git a/tools/gnulib/patches/646-hashcode-string.patch b/tools/gnulib/patches/646-hashcode-string.patch
new file mode 100644
index 0000000000..ee2ebd237f
--- /dev/null
+++ b/tools/gnulib/patches/646-hashcode-string.patch
@@ -0,0 +1,294 @@
+From 64042bb91aea5f854ca8a8938e2b3f7d1935e4f1 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Wed, 30 Apr 2025 12:47:37 +0200
+Subject: [PATCH] New module hashcode-string1.
+
+* lib/hashcode-string1.h: New file.
+* lib/hashcode-string1.c: New file, based on lib/hash.c.
+* modules/hashcode-string1: New file.
+* lib/hash.h: Include hashcode-string1.h.
+(hash_string): Remove declaration.
+* lib/hash.c (hash_string): Remove function.
+* modules/hash (Depends-on): Add hashcode-string1.
+* lib/exclude.c: Include hashcode-string1.h.
+* modules/exclude (Depends-on): Add hashcode-string1.
+---
+ ChangeLog | 13 +++++++++
+ lib/exclude.c | 1 +
+ lib/hash.c | 59 ++++++--------------------------------
+ lib/hash.h | 11 +++----
+ lib/hashcode-string1.c | 62 ++++++++++++++++++++++++++++++++++++++++
+ lib/hashcode-string1.h | 38 ++++++++++++++++++++++++
+ modules/exclude | 1 +
+ modules/hash | 1 +
+ modules/hashcode-string1 | 24 ++++++++++++++++
+ 9 files changed, 154 insertions(+), 56 deletions(-)
+ create mode 100644 lib/hashcode-string1.c
+ create mode 100644 lib/hashcode-string1.h
+ create mode 100644 modules/hashcode-string1
+
+--- a/lib/exclude.c
++++ b/lib/exclude.c
+@@ -36,6 +36,7 @@
+ #include "filename.h"
+ #include <fnmatch.h>
+ #include "hash.h"
++#include "hashcode-string1.h"
+ #if GNULIB_MCEL_PREFER
+ # include "mcel.h"
+ #else
+--- a/lib/hash.c
++++ b/lib/hash.c
+@@ -345,57 +345,6 @@ hash_do_for_each (const Hash_table *tabl
+ return counter;
+ }
+
+-/* Allocation and clean-up. */
+-
+-#if USE_DIFF_HASH
+-
+-/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see
+- B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm,
+- Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash
+- algorithms tend to be domain-specific, so what's good for [diffutils'] io.c
+- may not be good for your application." */
+-
+-size_t
+-hash_string (const char *string, size_t n_buckets)
+-{
+-# define HASH_ONE_CHAR(Value, Byte) \
+- ((Byte) + rotl_sz (Value, 7))
+-
+- size_t value = 0;
+- unsigned char ch;
+-
+- for (; (ch = *string); string++)
+- value = HASH_ONE_CHAR (value, ch);
+- return value % n_buckets;
+-
+-# undef HASH_ONE_CHAR
+-}
+-
+-#else /* not USE_DIFF_HASH */
+-
+-/* This one comes from 'recode', and performs a bit better than the above as
+- per a few experiments. It is inspired from a hashing routine found in the
+- very old Cyber 'snoop', itself written in typical Greg Mansfield style.
+- (By the way, what happened to this excellent man? Is he still alive?) */
+-
+-size_t
+-hash_string (const char *string, size_t n_buckets)
+-{
+- size_t value = 0;
+- unsigned char ch;
+-
+- for (; (ch = *string); string++)
+- value = (value * 31 + ch) % n_buckets;
+- return value;
+-}
+-
+-#endif /* not USE_DIFF_HASH */
+-
+-void
+-hash_reset_tuning (Hash_tuning *tuning)
+-{
+- *tuning = default_tuning;
+-}
+
+ /* If the user passes a NULL hasher, we hash the raw pointer. */
+ static size_t
+@@ -418,6 +367,14 @@ raw_comparator (const void *a, const voi
+ }
+
+
++/* Allocation and clean-up. */
++
++void
++hash_reset_tuning (Hash_tuning *tuning)
++{
++ *tuning = default_tuning;
++}
++
+ /* For the given hash TABLE, check the user supplied tuning structure for
+ reasonable values, and return true if there is no gross error with it.
+ Otherwise, definitively reset the TUNING field to some acceptable default
+--- a/lib/hash.h
++++ b/lib/hash.h
+@@ -134,11 +134,6 @@ extern size_t hash_do_for_each (const Ha
+ * Allocation and clean-up.
+ */
+
+-/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1.
+- This is a convenience routine for constructing other hashing functions. */
+-extern size_t hash_string (const char *string, size_t n_buckets)
+- _GL_ATTRIBUTE_PURE;
+-
+ extern void hash_reset_tuning (Hash_tuning *tuning);
+
+ typedef size_t (*Hash_hasher) (const void *entry, size_t table_size);
+@@ -266,6 +261,12 @@ extern void *hash_remove (Hash_table *ta
+ _GL_ATTRIBUTE_DEPRECATED
+ extern void *hash_delete (Hash_table *table, const void *entry);
+
++
++# if GNULIB_HASHCODE_STRING1
++/* Include declarations of module 'hashcode-string1'. */
++# include "hashcode-string1.h"
++# endif
++
+ # ifdef __cplusplus
+ }
+ # endif
+--- /dev/null
++++ b/lib/hashcode-string1.c
+@@ -0,0 +1,62 @@
++/* hashcode-string1.c -- compute a hash value from a NUL-terminated string.
++
++ Copyright (C) 1998-2004, 2006-2007, 2009-2025 Free Software Foundation, Inc.
++
++ This file is free software: you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation; either version 2.1 of the
++ License, or (at your option) any later version.
++
++ This file 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 Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see <https://www.gnu.org/licenses/>. */
++
++#include <config.h>
++
++/* Specification. */
++#include "hashcode-string1.h"
++
++#if USE_DIFF_HASH
++
++# include "bitrotate.h"
++
++/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see
++ B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm,
++ Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash
++ algorithms tend to be domain-specific, so what's good for [diffutils'] io.c
++ may not be good for your application." */
++
++size_t
++hash_string (const char *string, size_t tablesize)
++{
++ size_t value = 0;
++ unsigned char ch;
++
++ for (; (ch = *string); string++)
++ value = ch + rotl_sz (value, 7);
++ return value % tablesize;
++}
++
++#else /* not USE_DIFF_HASH */
++
++/* This one comes from 'recode', and performs a bit better than the above as
++ per a few experiments. It is inspired from a hashing routine found in the
++ very old Cyber 'snoop', itself written in typical Greg Mansfield style.
++ (By the way, what happened to this excellent man? Is he still alive?) */
++
++size_t
++hash_string (const char *string, size_t tablesize)
++{
++ size_t value = 0;
++ unsigned char ch;
++
++ for (; (ch = *string); string++)
++ value = (value * 31 + ch) % tablesize;
++ return value;
++}
++
++#endif /* not USE_DIFF_HASH */
+--- /dev/null
++++ b/lib/hashcode-string1.h
+@@ -0,0 +1,38 @@
++/* hashcode-string1.h -- declaration for a simple hash function
++ Copyright (C) 1998-2004, 2006-2007, 2009-2025 Free Software Foundation, Inc.
++
++ This file is free software: you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation; either version 2.1 of the
++ License, or (at your option) any later version.
++
++ This file 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 Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see <https://www.gnu.org/licenses/>. */
++
++/* This file uses _GL_ATTRIBUTE_PURE. */
++#if !_GL_CONFIG_H_INCLUDED
++ #error "Please include config.h first."
++#endif
++
++#include <stddef.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++
++/* Compute a hash code for a NUL-terminated string S,
++ and return the hash code modulo TABLESIZE.
++ The result is platform dependent: it depends on the size of the 'size_t'
++ type. */
++extern size_t hash_string (char const *s, size_t tablesize) _GL_ATTRIBUTE_PURE;
++
++
++#ifdef __cplusplus
++}
++#endif
+--- a/modules/exclude
++++ b/modules/exclude
+@@ -12,6 +12,7 @@ filename
+ fnmatch
+ fopen-gnu
+ hash
++hashcode-string1
+ mbscasecmp
+ mbuiter [test "$GNULIB_MCEL_PREFER" != yes]
+ nullptr
+--- a/modules/hash
++++ b/modules/hash
+@@ -14,6 +14,7 @@ next-prime
+ bool
+ stdint-h
+ xalloc-oversized
++hashcode-string1
+
+ configure.ac:
+
+--- /dev/null
++++ b/modules/hashcode-string1
+@@ -0,0 +1,24 @@
++Description:
++Compute a hash value for a NUL-terminated string.
++
++Files:
++lib/hashcode-string1.h
++lib/hashcode-string1.c
++
++Depends-on:
++bitrotate
++
++configure.ac:
++gl_MODULE_INDICATOR([hashcode-string1])
++
++Makefile.am:
++lib_SOURCES += hashcode-string1.h hashcode-string1.c
++
++Include:
++"hashcode-string1.h"
++
++License:
++LGPLv2+
++
++Maintainer:
++Jim Meyering
diff --git a/tools/gnulib/patches/647-hashkey-string.patch b/tools/gnulib/patches/647-hashkey-string.patch
new file mode 100644
index 0000000000..d0cd0a6311
--- /dev/null
+++ b/tools/gnulib/patches/647-hashkey-string.patch
@@ -0,0 +1,215 @@
+From 52738dcd0f522b16653cc8b21adfcb758702f2ab Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Wed, 30 Apr 2025 01:20:17 +0200
+Subject: [PATCH] New module hashkey-string.
+
+* lib/hashkey-string.h: New file.
+* lib/hashkey-string.c: New file, based on lib/clean-temp-simple.c.
+* modules/hashkey-string: New file.
+* lib/clean-temp-simple.c: Include hashkey-string.h. Don't include
+<limits.h>.
+(clean_temp_string_equals, clean_temp_string_hash): Remove functions.
+(SIZE_BITS): Remove macro.
+(register_temporary_file): Use hashkey_string_equals and
+hashkey_string_hash.
+* modules/clean-temp-simple (Depends-on): Add hashkey-string.
+---
+ ChangeLog | 14 ++++++++++++
+ lib/clean-temp-simple.c | 33 +++------------------------
+ lib/hashkey-string.c | 48 +++++++++++++++++++++++++++++++++++++++
+ lib/hashkey-string.h | 35 ++++++++++++++++++++++++++++
+ modules/clean-temp-simple | 1 +
+ modules/hashkey-string | 23 +++++++++++++++++++
+ 6 files changed, 124 insertions(+), 30 deletions(-)
+ create mode 100644 lib/hashkey-string.c
+ create mode 100644 lib/hashkey-string.h
+ create mode 100644 modules/hashkey-string
+
+--- a/lib/clean-temp-simple.c
++++ b/lib/clean-temp-simple.c
+@@ -22,7 +22,6 @@
+ #include "clean-temp-private.h"
+
+ #include <errno.h>
+-#include <limits.h>
+ #include <signal.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -36,6 +35,7 @@
+ #include "thread-optim.h"
+ #include "gl_list.h"
+ #include "gl_linkedhash_list.h"
++#include "hashkey-string.h"
+ #include "gettext.h"
+
+ #define _(msgid) dgettext ("gnulib", msgid)
+@@ -106,33 +106,6 @@ gl_list_t /* <closeable_fd *> */ volatil
+ asynchronous signal.
+ */
+
+-/* String equality and hash code functions used by the lists. */
+-
+-bool
+-clean_temp_string_equals (const void *x1, const void *x2)
+-{
+- const char *s1 = (const char *) x1;
+- const char *s2 = (const char *) x2;
+- return strcmp (s1, s2) == 0;
+-}
+-
+-#define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
+-
+-/* A hash function for NUL-terminated char* strings using
+- the method described by Bruno Haible.
+- See https://www.haible.de/bruno/hashfunc.html. */
+-size_t
+-clean_temp_string_hash (const void *x)
+-{
+- const char *s = (const char *) x;
+- size_t h = 0;
+-
+- for (; *s; s++)
+- h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
+-
+- return h;
+-}
+-
+
+ /* The set of fatal signal handlers.
+ Cached here because we are not allowed to call get_fatal_signal_set ()
+@@ -326,8 +299,8 @@ register_temporary_file (const char *abs
+ }
+ file_cleanup_list =
+ gl_list_nx_create_empty (GL_LINKEDHASH_LIST,
+- clean_temp_string_equals,
+- clean_temp_string_hash,
++ hashkey_string_equals,
++ hashkey_string_hash,
+ NULL, false);
+ if (file_cleanup_list == NULL)
+ {
+--- /dev/null
++++ b/lib/hashkey-string.c
+@@ -0,0 +1,48 @@
++/* Support for using a string as a hash key.
++ Copyright (C) 2006-2025 Free Software Foundation, Inc.
++
++ This file is free software: you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation; either version 2.1 of the
++ License, or (at your option) any later version.
++
++ This file 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 Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see <https://www.gnu.org/licenses/>. */
++
++#include <config.h>
++
++/* Specification. */
++#include "hashkey-string.h"
++
++#include <limits.h>
++#include <string.h>
++
++bool
++hashkey_string_equals (const void *x1, const void *x2)
++{
++ const char *s1 = (const char *) x1;
++ const char *s2 = (const char *) x2;
++ return strcmp (s1, s2) == 0;
++}
++
++#define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
++
++/* A hash function for NUL-terminated 'const char *' strings using
++ the method described by Bruno Haible.
++ See https://www.haible.de/bruno/hashfunc.html. */
++size_t
++hashkey_string_hash (const void *x)
++{
++ const char *s = (const char *) x;
++ size_t h = 0;
++
++ for (; *s; s++)
++ h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
++
++ return h;
++}
+--- /dev/null
++++ b/lib/hashkey-string.h
+@@ -0,0 +1,35 @@
++/* Support for using a string as a hash key.
++ Copyright (C) 2006-2025 Free Software Foundation, Inc.
++
++ This file is free software: you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation; either version 2.1 of the
++ License, or (at your option) any later version.
++
++ This file 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 Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see <https://www.gnu.org/licenses/>. */
++
++#ifndef _GL_HASHKEY_STRING_H
++#define _GL_HASHKEY_STRING_H
++
++#include <stddef.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/* String equality and hash code functions that operate on plain C strings
++ ('const char *'). */
++extern bool hashkey_string_equals (const void *x1, const void *x2);
++extern size_t hashkey_string_hash (const void *x);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* _GL_HASHKEY_STRING_H */
+--- a/modules/clean-temp-simple
++++ b/modules/clean-temp-simple
+@@ -19,6 +19,7 @@ error
+ fatal-signal
+ rmdir
+ linkedhash-list
++hashkey-string
+ gettext-h
+ gnulib-i18n
+
+--- /dev/null
++++ b/modules/hashkey-string
+@@ -0,0 +1,23 @@
++Description:
++Support for using a string as a hash key in the hash-set and hash-map modules.
++
++Files:
++lib/hashkey-string.h
++lib/hashkey-string.c
++
++Depends-on:
++bool
++
++configure.ac:
++
++Makefile.am:
++lib_SOURCES += hashkey-string.h hashkey-string.c
++
++Include:
++"hashkey-string.h"
++
++License:
++LGPLv2+
++
++Maintainer:
++all
diff --git a/tools/gnulib/patches/650-package-version.patch b/tools/gnulib/patches/650-package-version.patch
new file mode 100644
index 0000000000..2e3e046736
--- /dev/null
+++ b/tools/gnulib/patches/650-package-version.patch
@@ -0,0 +1,176 @@
+From e518788ad085e02b046e42889039a1f671e4619a Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Wed, 22 Jan 2025 21:21:59 +0100
+Subject: New module 'package-version'.
+
+* m4/init-package-version.m4: New file, from GNU libunistring.
+* modules/package-version: New file.
+* modules/git-version-gen (Depends-on): Add it.
+---
+ ChangeLog | 7 +++
+ m4/init-package-version.m4 | 124 +++++++++++++++++++++++++++++++++++++++++++++
+ modules/git-version-gen | 1 +
+ modules/package-version | 19 +++++++
+ 4 files changed, 151 insertions(+)
+ create mode 100644 m4/init-package-version.m4
+ create mode 100644 modules/package-version
+
+--- /dev/null
++++ b/m4/init-package-version.m4
+@@ -0,0 +1,124 @@
++# init-package-version.m4
++# serial 3
++dnl Copyright (C) 1992-2025 Free Software Foundation, Inc.
++dnl This file is free software, distributed under the terms of the GNU
++dnl General Public License. As a special exception to the GNU General
++dnl Public License, this file may be distributed as part of a program
++dnl that contains a configuration script generated by Autoconf, under
++dnl the same distribution terms as the rest of that program.
++
++# Make it possible to pass version numbers extracted from a file in
++# $(srcdir) to autoconf.
++#
++# Autoconf insists on passing the package name and version number to
++# every generated .h file and every Makefile. This was a reasonable
++# design at times when a version number was changed only once a month.
++# Nowadays, people often assign a new version number once a week, or
++# even change it each time a 'git' commit is made. Regenerating all
++# the files that depend on configure.ac (aclocal.m4, configure,
++# config.status, config.h, all Makefiles) may take 15 minutes. These
++# delays can severely hamper development.
++#
++# An alternative is to store the version number in a file in $(srcdir)
++# that is separate from configure.ac. It can be a data file, a shell
++# script, a .m4 file, or other. The essential point is that the maintainer
++# is responsible for creating Makefile dependencies to this version file
++# for every file that needs to be rebuilt when the version changes. This
++# typically includes
++# - distributable documentation files that carry the version number,
++# but does not include
++# - aclocal.m4, configure, config.status, config.h, all Makefiles,
++# - executables.
++#
++# autoconf and automake make it hard to follow this approach:
++#
++# - If AC_INIT is used with arguments, there is a chicken-and-egg problem:
++# The arguments need to be read from a file in $(srcdir). The location
++# of $(srcdir) is only determined by AC_CONFIG_SRCDIR. AC_CONFIG_SRCDIR
++# can only appear after AC_INIT (otherwise aclocal gives an error:
++# "error: m4_defn: undefined macro: _m4_divert_diversion").
++# Furthermore, the arguments passed to AC_INIT must be literals; for
++# example, the assignment to PACKAGE_VERSION looks like this:
++# [PACKAGE_VERSION=']AC_PACKAGE_VERSION[']
++#
++# - If AC_INIT is used without arguments:
++# Automake provides its own variables, PACKAGE and VERSION, and uses them
++# instead of PACKAGE_NAME and PACKAGE_VERSION that come from Autoconf.
++# - If AM_INIT_AUTOMAKE is used with two arguments, automake options
++# like 'silent-rules' cannot be specified.
++# - If AM_INIT_AUTOMAKE is used in its one-argument form or without
++# arguments at all, it triggers an error
++# "error: AC_INIT should be called with package and version arguments".
++# - If AM_INIT_AUTOMAKE is used in its one-argument form or without
++# arguments at all, and _AC_INIT_PACKAGE is used before it, with
++# the package and version number from the file as arguments, we get
++# a warning: "warning: AC_INIT: not a literal: $VERSION_NUMBER".
++# The arguments passed to _AC_INIT_PACKAGE must be literals.
++#
++# With the macro defined in this file, the approach can be coded like this:
++#
++# AC_INIT
++# AC_CONFIG_SRCDIR(WITNESS)
++# . $srcdir/../version.sh
++# gl_INIT_PACKAGE(PACKAGE, $VERSION_NUMBER)
++# AM_INIT_AUTOMAKE([OPTIONS])
++#
++# and after changing version.sh, the developer can directly configure and build:
++#
++# make distclean
++# ./configure
++# make
++#
++# Some other packages use another approach:
++#
++# AC_INIT(PACKAGE,
++# m4_normalize(m4_esyscmd([. ./version.sh; echo $VERSION_NUMBER])))
++# AC_CONFIG_SRCDIR(WITNESS)
++# AM_INIT_AUTOMAKE([OPTIONS])
++#
++# but here, after changing version.sh, the developer must first regenerate the
++# configure file:
++#
++# make distclean
++# ./autogen.sh --skip-gnulib
++# ./configure
++# make
++#
++
++# gl_INIT_PACKAGE(PACKAGE-NAME, VERSION)
++# --------------------------------------
++# followed by an AM_INIT_AUTOMAKE invocation,
++# is like calling AM_INIT_AUTOMAKE(PACKAGE-NAME, VERSION)
++# except that it can use computed non-literal arguments.
++AC_DEFUN([gl_INIT_PACKAGE],
++[
++ AC_BEFORE([$0], [AM_INIT_AUTOMAKE])
++ dnl Redefine AM_INIT_AUTOMAKE.
++ m4_define([gl_AM_INIT_AUTOMAKE],
++ m4_bpatsubst(m4_dquote(
++ m4_bpatsubst(m4_dquote(
++ m4_bpatsubst(m4_dquote(
++ m4_defn([AM_INIT_AUTOMAKE])),
++ [AC_PACKAGE_NAME], [gl_INIT_DUMMY])),
++ [AC_PACKAGE_TARNAME], [gl_INIT_EMPTY])),
++ [AC_PACKAGE_VERSION], [gl_INIT_DUMMY])
++ [AC_SUBST([PACKAGE], [$1])
++ AC_SUBST([VERSION], [$2])
++ ])
++ m4_define([AM_INIT_AUTOMAKE],
++ m4_defn([gl_RPL_INIT_AUTOMAKE]))
++])
++m4_define([gl_INIT_EMPTY], [])
++dnl Automake 1.16.4 no longer accepts an empty value for gl_INIT_DUMMY.
++dnl But a macro that later expands to empty works.
++m4_define([gl_INIT_DUMMY], [gl_INIT_DUMMY2])
++m4_define([gl_INIT_DUMMY2], [])
++AC_DEFUN([gl_RPL_INIT_AUTOMAKE], [
++ m4_ifval([$2],
++ [m4_fatal([After gl_INIT_PACKAGE, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])])
++ gl_AM_INIT_AUTOMAKE([$1 no-define])
++ m4_if(m4_index([ $1 ], [ no-define ]), [-1],
++ [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
++ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])
++ ])
++])
+--- a/modules/git-version-gen
++++ b/modules/git-version-gen
+@@ -5,6 +5,7 @@ Files:
+ build-aux/git-version-gen
+
+ Depends-on:
++package-version
+
+ configure.ac:
+
+--- /dev/null
++++ b/modules/package-version
+@@ -0,0 +1,19 @@
++Description:
++Support for a computed version string.
++
++Files:
++m4/init-package-version.m4
++
++Depends-on:
++
++configure.ac:
++
++Makefile.am:
++
++Include:
++
++License:
++GPLed build tool
++
++Maintainer:
++Bruno Haible
diff --git a/tools/gnulib/patches/651-package-version-simplify.patch b/tools/gnulib/patches/651-package-version-simplify.patch
new file mode 100644
index 0000000000..bed3e65c41
--- /dev/null
+++ b/tools/gnulib/patches/651-package-version-simplify.patch
@@ -0,0 +1,66 @@
+From bb0f82be83d43db9cd77049be32ffd0b92ab5bb7 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Fri, 24 Jan 2025 22:03:29 +0100
+Subject: package-version: Simplify its use.
+
+Reported by Basil L. Contovounesios <basil@contovou.net> in
+<https://lists.gnu.org/archive/html/bug-gnulib/2025-01/msg00195.html>.
+
+* doc/package-version.texi (Propagating the package version): Recommend
+to pass the usual arguments to AC_INIT.
+* m4/init-package-version.m4: Likewise.
+(gl_INIT_PACKAGE): Define PACKAGE_VERSION and PACKAGE_STRING as needed.
+(gl_RPL_INIT_AUTOMAKE): Improve quoting.
+---
+ ChangeLog | 11 +++++++++++
+ doc/package-version.texi | 2 +-
+ m4/init-package-version.m4 | 20 ++++++++++++++------
+ 3 files changed, 26 insertions(+), 7 deletions(-)
+
+--- a/m4/init-package-version.m4
++++ b/m4/init-package-version.m4
+@@ -1,5 +1,5 @@
+ # init-package-version.m4
+-# serial 3
++# serial 4
+ dnl Copyright (C) 1992-2025 Free Software Foundation, Inc.
+ dnl This file is free software, distributed under the terms of the GNU
+ dnl General Public License. As a special exception to the GNU General
+@@ -57,7 +57,7 @@ dnl the same distribution terms as the r
+ #
+ # With the macro defined in this file, the approach can be coded like this:
+ #
+-# AC_INIT
++# AC_INIT(PACKAGE, [dummy], [MORE OPTIONS])
+ # AC_CONFIG_SRCDIR(WITNESS)
+ # . $srcdir/../version.sh
+ # gl_INIT_PACKAGE(PACKAGE, $VERSION_NUMBER)
+@@ -102,8 +102,16 @@ AC_DEFUN([gl_INIT_PACKAGE],
+ [AC_PACKAGE_NAME], [gl_INIT_DUMMY])),
+ [AC_PACKAGE_TARNAME], [gl_INIT_EMPTY])),
+ [AC_PACKAGE_VERSION], [gl_INIT_DUMMY])
+- [AC_SUBST([PACKAGE], [$1])
+- AC_SUBST([VERSION], [$2])
++ [dnl Set variables documented in Automake.
++ AC_SUBST([PACKAGE], [$1])
++ AC_SUBST([VERSION], ["$2"])
++ dnl Set variables documented in Autoconf.
++ AC_SUBST([PACKAGE_VERSION], ["$2"])
++ AC_SUBST([PACKAGE_STRING], ["$1 $2"])
++ AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$2"],
++ [Define to the version of this package.])
++ AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["$1 $2"],
++ [Define to the full name and version of this package.])
+ ])
+ m4_define([AM_INIT_AUTOMAKE],
+ m4_defn([gl_RPL_INIT_AUTOMAKE]))
+@@ -118,7 +126,7 @@ AC_DEFUN([gl_RPL_INIT_AUTOMAKE], [
+ [m4_fatal([After gl_INIT_PACKAGE, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])])
+ gl_AM_INIT_AUTOMAKE([$1 no-define])
+ m4_if(m4_index([ $1 ], [ no-define ]), [-1],
+- [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])
++ [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
++ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])
+ ])
+ ])
diff --git a/tools/gnulib/patches/652-package-version-simplify-further.patch b/tools/gnulib/patches/652-package-version-simplify-further.patch
new file mode 100644
index 0000000000..5458918246
--- /dev/null
+++ b/tools/gnulib/patches/652-package-version-simplify-further.patch
@@ -0,0 +1,89 @@
+From 48648b4b9b3fd79a5c68913deb28678bd9d8eb34 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Sat, 25 Jan 2025 04:07:32 +0100
+Subject: package-version: Simplify further.
+
+* doc/package-version.texi (Propagating the package version): Recommend
+use of gl_INIT_PACKAGE_VERSION instead of gl_INIT_PACKAGE.
+* build-aux/git-version-gen: Likewise.
+* m4/init-package-version.m4: Likewise.
+(gl_INIT_PACKAGE_VERSION): Renamed from gl_INIT_PACKAGE. Take only one
+argument. Don't fiddle with AC_PACKAGE_NAME, AC_PACKAGE_TARNAME,
+PACKAGE.
+(gl_RPL_INIT_AUTOMAKE): Update.
+---
+ ChangeLog | 10 ++++++++++
+ build-aux/git-version-gen | 4 ++--
+ doc/package-version.texi | 4 ++--
+ m4/init-package-version.m4 | 30 ++++++++++++------------------
+ 4 files changed, 26 insertions(+), 22 deletions(-)
+
+--- a/m4/init-package-version.m4
++++ b/m4/init-package-version.m4
+@@ -1,5 +1,5 @@
+ # init-package-version.m4
+-# serial 4
++# serial 5
+ dnl Copyright (C) 1992-2025 Free Software Foundation, Inc.
+ dnl This file is free software, distributed under the terms of the GNU
+ dnl General Public License. As a special exception to the GNU General
+@@ -60,7 +60,7 @@ dnl the same distribution terms as the r
+ # AC_INIT(PACKAGE, [dummy], [MORE OPTIONS])
+ # AC_CONFIG_SRCDIR(WITNESS)
+ # . $srcdir/../version.sh
+-# gl_INIT_PACKAGE(PACKAGE, $VERSION_NUMBER)
++# gl_INIT_PACKAGE_VERSION($VERSION_NUMBER)
+ # AM_INIT_AUTOMAKE([OPTIONS])
+ #
+ # and after changing version.sh, the developer can directly configure and build:
+@@ -85,32 +85,26 @@ dnl the same distribution terms as the r
+ # make
+ #
+
+-# gl_INIT_PACKAGE(PACKAGE-NAME, VERSION)
+-# --------------------------------------
++# gl_INIT_PACKAGE_VERSION(VERSION)
++# --------------------------------
+ # followed by an AM_INIT_AUTOMAKE invocation,
+ # is like calling AM_INIT_AUTOMAKE(PACKAGE-NAME, VERSION)
+ # except that it can use computed non-literal arguments.
+-AC_DEFUN([gl_INIT_PACKAGE],
++AC_DEFUN([gl_INIT_PACKAGE_VERSION],
+ [
+ AC_BEFORE([$0], [AM_INIT_AUTOMAKE])
+ dnl Redefine AM_INIT_AUTOMAKE.
+ m4_define([gl_AM_INIT_AUTOMAKE],
+- m4_bpatsubst(m4_dquote(
+- m4_bpatsubst(m4_dquote(
+- m4_bpatsubst(m4_dquote(
+- m4_defn([AM_INIT_AUTOMAKE])),
+- [AC_PACKAGE_NAME], [gl_INIT_DUMMY])),
+- [AC_PACKAGE_TARNAME], [gl_INIT_EMPTY])),
++ m4_bpatsubst(m4_dquote(m4_defn([AM_INIT_AUTOMAKE])),
+ [AC_PACKAGE_VERSION], [gl_INIT_DUMMY])
+ [dnl Set variables documented in Automake.
+- AC_SUBST([PACKAGE], [$1])
+- AC_SUBST([VERSION], ["$2"])
++ AC_SUBST([VERSION], ["$1"])
+ dnl Set variables documented in Autoconf.
+- AC_SUBST([PACKAGE_VERSION], ["$2"])
+- AC_SUBST([PACKAGE_STRING], ["$1 $2"])
+- AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$2"],
++ AC_SUBST([PACKAGE_VERSION], ["$1"])
++ AC_SUBST([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"])
++ AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$1"],
+ [Define to the version of this package.])
+- AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["$1 $2"],
++ AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"],
+ [Define to the full name and version of this package.])
+ ])
+ m4_define([AM_INIT_AUTOMAKE],
+@@ -123,7 +117,7 @@ m4_define([gl_INIT_DUMMY], [gl_INIT_DUMM
+ m4_define([gl_INIT_DUMMY2], [])
+ AC_DEFUN([gl_RPL_INIT_AUTOMAKE], [
+ m4_ifval([$2],
+- [m4_fatal([After gl_INIT_PACKAGE, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])])
++ [m4_fatal([After gl_INIT_PACKAGE_VERSION, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])])
+ gl_AM_INIT_AUTOMAKE([$1 no-define])
+ m4_if(m4_index([ $1 ], [ no-define ]), [-1],
+ [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
diff --git a/tools/gnulib/patches/653-package-version-warning.patch b/tools/gnulib/patches/653-package-version-warning.patch
new file mode 100644
index 0000000000..4baa21ce65
--- /dev/null
+++ b/tools/gnulib/patches/653-package-version-warning.patch
@@ -0,0 +1,32 @@
+From 2e46209809f751087ca27523283bd5c3e9071d31 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Sun, 26 Jan 2025 13:26:35 +0100
+Subject: package-version: Avoid compiler warnings in config.log.
+
+* m4/init-package-version.m4 (gl_INIT_PACKAGE_VERSION): Undefine
+PACKAGE_VERSION and PACKAGE_STRING before redefining them.
+---
+ ChangeLog | 6 ++++++
+ m4/init-package-version.m4 | 4 +++-
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+--- a/m4/init-package-version.m4
++++ b/m4/init-package-version.m4
+@@ -1,5 +1,5 @@
+ # init-package-version.m4
+-# serial 5
++# serial 6
+ dnl Copyright (C) 1992-2025 Free Software Foundation, Inc.
+ dnl This file is free software, distributed under the terms of the GNU
+ dnl General Public License. As a special exception to the GNU General
+@@ -102,8 +102,10 @@ AC_DEFUN([gl_INIT_PACKAGE_VERSION],
+ dnl Set variables documented in Autoconf.
+ AC_SUBST([PACKAGE_VERSION], ["$1"])
+ AC_SUBST([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"])
++ _AC_DEFINE([#undef PACKAGE_VERSION])
+ AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$1"],
+ [Define to the version of this package.])
++ _AC_DEFINE([#undef PACKAGE_STRING])
+ AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"],
+ [Define to the full name and version of this package.])
+ ])
diff --git a/tools/gnulib/patches/660-version-stamp.patch b/tools/gnulib/patches/660-version-stamp.patch
new file mode 100644
index 0000000000..d85c0455cf
--- /dev/null
+++ b/tools/gnulib/patches/660-version-stamp.patch
@@ -0,0 +1,75 @@
+From 85599643e2fbf70f7f0bd58831993132ef335705 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Wed, 22 Jan 2025 21:25:27 +0100
+Subject: New module 'version-stamp'.
+
+* m4/version-stamp.m4: New file.
+* modules/version-stamp: New file.
+---
+ ChangeLog | 6 ++++++
+ m4/version-stamp.m4 | 35 +++++++++++++++++++++++++++++++++++
+ modules/version-stamp | 19 +++++++++++++++++++
+ 3 files changed, 60 insertions(+)
+ create mode 100644 m4/version-stamp.m4
+ create mode 100644 modules/version-stamp
+
+--- /dev/null
++++ b/m4/version-stamp.m4
+@@ -0,0 +1,35 @@
++# version-stamp.m4
++# serial 1
++dnl Copyright (C) 2025 Free Software Foundation, Inc.
++dnl This file is free software, distributed under the terms of the GNU
++dnl General Public License. As a special exception to the GNU General
++dnl Public License, this file may be distributed as part of a program
++dnl that contains a configuration script generated by Autoconf, under
++dnl the same distribution terms as the rest of that program.
++
++# Manages a stamp file, that keeps track when $(VERSION) was last changed.
++#
++# gl_CONFIG_VERSION_STAMP
++# needs to be invoked near the end of the package's top-level configure.ac,
++# before AC_OUTPUT.
++# It makes sure that during the build,
++# - $(top_srcdir)/.version exists, and
++# - when $(VERSION) is changed, $(top_srcdir)/.version gets modified.
++#
++# $(top_srcdir)/.version is a stamp file. Its contents wouldn't matter,
++# except that for detecting the change, we store the value of $(VERSION)
++# in it (but we could just as well store it in a different file).
++AC_DEFUN([gl_CONFIG_VERSION_STAMP],
++[
++ AC_CONFIG_COMMANDS([version-timestamp],
++ [if test -f "$ac_top_srcdir/.version" \
++ && test `cat "$ac_top_srcdir/.version"` = "$gl_version"; then
++ # The value of $(VERSION) is the same as last time.
++ :
++ else
++ # The value of $(VERSION) has changed. Update the stamp.
++ echo "$gl_version" > "$ac_top_srcdir/.version"
++ fi
++ ],
++ [gl_version="$VERSION"])
++])
+--- /dev/null
++++ b/modules/version-stamp
+@@ -0,0 +1,19 @@
++Description:
++Optimized rebuilding of artifacts that depend on $(VERSION).
++
++Files:
++m4/version-stamp.m4
++
++Depends-on:
++
++configure.ac:
++
++Makefile.am:
++
++Include:
++
++License:
++GPLed build tool
++
++Maintainer:
++Bruno Haible
diff --git a/tools/gnulib/patches/689-vc-mtime.patch b/tools/gnulib/patches/689-vc-mtime.patch
new file mode 100644
index 0000000000..62638d7ff4
--- /dev/null
+++ b/tools/gnulib/patches/689-vc-mtime.patch
@@ -0,0 +1,366 @@
+From 701d20aaf579bb71f35209dd63a272c3d9d21096 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Mon, 24 Feb 2025 19:03:17 +0100
+Subject: [PATCH] vc-mtime: New module.
+
+* lib/vc-mtime.h: New file.
+* lib/vc-mtime.c: New file.
+* modules/vc-mtime: New file.
+---
+ ChangeLog | 7 ++
+ lib/vc-mtime.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++
+ lib/vc-mtime.h | 97 ++++++++++++++++++++++
+ modules/vc-mtime | 34 ++++++++
+ 4 files changed, 346 insertions(+)
+ create mode 100644 lib/vc-mtime.c
+ create mode 100644 lib/vc-mtime.h
+ create mode 100644 modules/vc-mtime
+
+--- /dev/null
++++ b/lib/vc-mtime.c
+@@ -0,0 +1,208 @@
++/* Return the version-control based modification time of a file.
++ Copyright (C) 2025 Free Software Foundation, Inc.
++
++ This program 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.
++
++ This program 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 this program. If not, see <https://www.gnu.org/licenses/>. */
++
++/* Written by Bruno Haible <bruno@clisp.org>, 2025. */
++
++#include <config.h>
++
++/* Specification. */
++#include "vc-mtime.h"
++
++#include <stdlib.h>
++#include <unistd.h>
++
++#include <error.h>
++#include "spawn-pipe.h"
++#include "wait-process.h"
++#include "execute.h"
++#include "safe-read.h"
++#include "xstrtol.h"
++#include "stat-time.h"
++#include "gettext.h"
++
++#define _(msgid) dgettext ("gnulib", msgid)
++
++
++/* Determines whether the specified file is under version control. */
++static bool
++git_vc_controlled (const char *filename)
++{
++ /* Run "git ls-files FILENAME" and return true if the exit code is 0
++ and the output is non-empty. */
++ const char *argv[4];
++ pid_t child;
++ int fd[1];
++
++ argv[0] = "git";
++ argv[1] = "ls-files";
++ argv[2] = filename;
++ argv[3] = NULL;
++ child = create_pipe_in ("git", "git", argv, NULL, NULL,
++ DEV_NULL, true, true, false, fd);
++ if (child == -1)
++ return false;
++
++ /* Read the subprocess output, and test whether it is non-empty. */
++ size_t count = 0;
++ char c;
++
++ while (safe_read (fd[0], &c, 1) > 0)
++ count++;
++
++ close (fd[0]);
++
++ /* Remove zombie process from process list, and retrieve exit status. */
++ int exitstatus =
++ wait_subprocess (child, "git", false, true, true, false, NULL);
++ return (exitstatus == 0 && count > 0);
++}
++
++/* Determines whether the specified file is unmodified, compared to the
++ last version in version control. */
++static bool
++git_unmodified (const char *filename)
++{
++ /* Run "git diff --quiet -- HEAD FILENAME"
++ (or "git diff --quiet HEAD FILENAME")
++ and return true if the exit code is 0.
++ The '--' option is for the case that the specified file was removed. */
++ const char *argv[7];
++ int exitstatus;
++
++ argv[0] = "git";
++ argv[1] = "diff";
++ argv[2] = "--quiet";
++ argv[3] = "--";
++ argv[4] = "HEAD";
++ argv[5] = filename;
++ argv[6] = NULL;
++ exitstatus = execute ("git", "git", argv, NULL, NULL,
++ false, false, true, true,
++ true, false, NULL);
++ return (exitstatus == 0);
++}
++
++/* Stores in *MTIME the time of last modification in version control of the
++ specified file, and returns 0.
++ Upon failure, it returns -1. */
++static int
++git_mtime (struct timespec *mtime, const char *filename)
++{
++ /* Run "git log -1 --format=%ct -- FILENAME". It prints the time of last
++ modification, as the number of seconds since the Epoch.
++ The '--' option is for the case that the specified file was removed. */
++ const char *argv[7];
++ pid_t child;
++ int fd[1];
++
++ argv[0] = "git";
++ argv[1] = "log";
++ argv[2] = "-1";
++ argv[3] = "--format=%ct";
++ argv[4] = "--";
++ argv[5] = filename;
++ argv[6] = NULL;
++ child = create_pipe_in ("git", "git", argv, NULL, NULL,
++ DEV_NULL, true, true, false, fd);
++ if (child == -1)
++ return -1;
++
++ /* Retrieve its result. */
++ FILE *fp;
++ char *line;
++ size_t linesize;
++ size_t linelen;
++
++ fp = fdopen (fd[0], "r");
++ if (fp == NULL)
++ error (EXIT_FAILURE, errno, _("fdopen() failed"));
++
++ line = NULL; linesize = 0;
++ linelen = getline (&line, &linesize, fp);
++ if (linelen == (size_t)(-1))
++ {
++ error (0, 0, _("%s subprocess I/O error"), "git");
++ fclose (fp);
++ wait_subprocess (child, "git", true, false, true, false, NULL);
++ }
++ else
++ {
++ int exitstatus;
++
++ if (linelen > 0 && line[linelen - 1] == '\n')
++ line[linelen - 1] = '\0';
++
++ fclose (fp);
++
++ /* Remove zombie process from process list, and retrieve exit status. */
++ exitstatus =
++ wait_subprocess (child, "git", true, false, true, false, NULL);
++ if (exitstatus == 0)
++ {
++ char *endptr;
++ unsigned long git_log_time;
++ if (xstrtoul (line, &endptr, 10, &git_log_time, NULL) == LONGINT_OK
++ && endptr == line + strlen (line))
++ {
++ mtime->tv_sec = git_log_time;
++ mtime->tv_nsec = 0;
++ free (line);
++ return 0;
++ }
++ }
++ }
++ free (line);
++ return -1;
++}
++
++int
++vc_mtime (struct timespec *mtime, const char *filename)
++{
++ static bool git_tested;
++ static bool git_present;
++
++ if (!git_tested)
++ {
++ /* Test for presence of git:
++ "git --version >/dev/null 2>/dev/null" */
++ const char *argv[3];
++ int exitstatus;
++
++ argv[0] = "git";
++ argv[1] = "--version";
++ argv[2] = NULL;
++ exitstatus = execute ("git", "git", argv, NULL, NULL,
++ false, false, true, true,
++ true, false, NULL);
++ git_present = (exitstatus == 0);
++ git_tested = true;
++ }
++
++ if (git_present
++ && git_vc_controlled (filename)
++ && git_unmodified (filename))
++ {
++ if (git_mtime (mtime, filename) == 0)
++ return 0;
++ }
++ struct stat statbuf;
++ if (stat (filename, &statbuf) == 0)
++ {
++ *mtime = get_stat_mtime (&statbuf);
++ return 0;
++ }
++ return -1;
++}
+--- /dev/null
++++ b/lib/vc-mtime.h
+@@ -0,0 +1,97 @@
++/* Return the version-control based modification time of a file.
++ Copyright (C) 2025 Free Software Foundation, Inc.
++
++ This program 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.
++
++ This program 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 this program. If not, see <https://www.gnu.org/licenses/>. */
++
++/* Written by Bruno Haible <bruno@clisp.org>, 2025. */
++
++#ifndef _VC_MTIME_H
++#define _VC_MTIME_H
++
++/* Get struct timespec. */
++#include <time.h>
++
++/* The "version-controlled modification time" vc_mtime(F) of a file F
++ is defined as:
++ - If F is under version control and not modified locally:
++ the time of the last change of F in the version control system.
++ - Otherwise: The modification time of F on disk.
++
++ For now, the only VCS supported by this module is git. (hg and svn are
++ hardly in use any more.)
++
++ This has the properties that:
++ - Different users who have checked out the same git repo on different
++ machines, at different times, and not done local modifications,
++ get the same vc_mtime(F).
++ - If a user has modified F locally, the modification time of that file
++ counts.
++ - If that user then reverts the modification, they then again get the
++ same vc_mtime(F) as everyone else.
++ - Different users who have unpacked the same tarball (without .git
++ directory) on different machines, at different times, also get the same
++ vc_mtime(F) [but possibly a different one than when the .git directory
++ was present]. (Assuming a POSIX compliant file system.)
++ - When a user commits local modifications into git, this only increases
++ (not decreases) the vc_mtime(F).
++
++ The purpose of the version-controlled modification time is to produce a
++ reproducible timestamp(Z) of a file Z that depends on files X1, ..., Xn,
++ in such a way that
++ - timestamp(Z) is reproducible, that is, different users on different
++ machines get the same value.
++ - timestamp(Z) is related to reality. It's not just a dummy, like what
++ is suggested in <https://reproducible-builds.org/docs/timestamps/>.
++ - One can arrange for timestamp(Z) to respect the modification time
++ relations of a build system.
++
++ There are two uses of such a timestamp:
++ - It can be set as the modification time of file Z in a file system, or
++ - It can be embedded in Z, with the purpose of telling a user how old
++ the file Z is. For example, in PDF files or in generated documentation,
++ such a time is embedded in a special place.
++
++ The simplest example is a file Z that depends on files X1, ..., Xn.
++ Generally one will define
++ timestamp(Z) = max (vc_mtime(X1), ..., vc_mtime(Xn))
++ for an embedded timestamp, or
++ timestamp(Z) = max (vc_mtime(X1), ..., vc_mtime(Xn)) + 1 second
++ for a time stamp in a file system. The added second
++ 1. accounts for fractional seconds in mtime(X1), ..., mtime(Xn),
++ 2. allows for 'make' implementation that attempt to rebuild Z
++ if mtime(Z) == mtime(Xi).
++
++ A more complicated example is when there are intermediate built files, not
++ under version control. For example, if the build process produces
++ X1, X2 -> Y1
++ X3, X4 -> Y2
++ Y1, Y2, X5 -> Z
++ where Y1 and Y2 are intermediate built files, you should ignore the
++ mtime(Y1), mtime(Y2), and consider only the vc_mtime(X1), ..., vc_mtime(X5).
++ */
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/* Determines the version-controlled modification time of FILENAME, stores it
++ in *MTIME, and returns 0.
++ Upon failure, it returns -1. */
++extern int vc_mtime (struct timespec *mtime, const char *filename);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* _VC_MTIME_H */
+--- /dev/null
++++ b/modules/vc-mtime
+@@ -0,0 +1,34 @@
++Description:
++Returns the version-control based modification time of a file.
++
++Files:
++lib/vc-mtime.h
++lib/vc-mtime.c
++
++Depends-on:
++time-h
++bool
++spawn-pipe
++wait-process
++execute
++safe-read
++error
++getline
++xstrtol
++stat-time
++gettext-h
++gnulib-i18n
++
++configure.ac:
++
++Makefile.am:
++lib_SOURCES += vc-mtime.c
++
++Include:
++"vm-mtime.h"
++
++License:
++GPL
++
++Maintainer:
++Bruno Haible
diff --git a/tools/gnulib/patches/755-clean-temp-hashkey.patch b/tools/gnulib/patches/755-clean-temp-hashkey.patch
new file mode 100644
index 0000000000..7a4774c9b3
--- /dev/null
+++ b/tools/gnulib/patches/755-clean-temp-hashkey.patch
@@ -0,0 +1,64 @@
+From f47c5f2e21d0ccedb271b406e35b6963b23a64c4 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Wed, 30 Apr 2025 13:11:01 +0200
+Subject: [PATCH] clean-temp: Fix link error (regression yesterday).
+
+* lib/clean-temp.c: Include hashkey-string.h.
+(create_temp_dir): Use hashkey_string_* functions instead of
+clean_temp_string_*.
+* lib/clean-temp-private.h (clean_temp_string_equals,
+clean_temp_string_hash): Remove declarations.
+* modules/clean-temp (Depends-on): Add hashkey-string.
+---
+ ChangeLog | 10 ++++++++++
+ lib/clean-temp-private.h | 3 ---
+ lib/clean-temp.c | 5 +++--
+ modules/clean-temp | 1 +
+ 4 files changed, 14 insertions(+), 5 deletions(-)
+
+--- a/lib/clean-temp-private.h
++++ b/lib/clean-temp-private.h
+@@ -68,9 +68,6 @@ struct closeable_fd
+ #define descriptors clean_temp_descriptors
+ extern gl_list_t /* <closeable_fd *> */ volatile descriptors;
+
+-extern bool clean_temp_string_equals (const void *x1, const void *x2);
+-extern size_t clean_temp_string_hash (const void *x);
+-
+ extern _GL_ASYNC_SAFE int clean_temp_asyncsafe_close (struct closeable_fd *element);
+ extern void clean_temp_init_asyncsafe_close (void);
+
+--- a/lib/clean-temp.c
++++ b/lib/clean-temp.c
+@@ -45,6 +45,7 @@
+ #include "xmalloca.h"
+ #include "glthread/lock.h"
+ #include "thread-optim.h"
++#include "hashkey-string.h"
+ #include "gl_xlist.h"
+ #include "gl_linkedhash_list.h"
+ #include "gl_linked_list.h"
+@@ -221,11 +222,11 @@ create_temp_dir (const char *prefix, con
+ tmpdir->cleanup_verbose = cleanup_verbose;
+ tmpdir->subdirs =
+ gl_list_create_empty (GL_LINKEDHASH_LIST,
+- clean_temp_string_equals, clean_temp_string_hash,
++ hashkey_string_equals, hashkey_string_hash,
+ NULL, false);
+ tmpdir->files =
+ gl_list_create_empty (GL_LINKEDHASH_LIST,
+- clean_temp_string_equals, clean_temp_string_hash,
++ hashkey_string_equals, hashkey_string_hash,
+ NULL, false);
+
+ /* Create the temporary directory. */
+--- a/modules/clean-temp
++++ b/modules/clean-temp
+@@ -24,6 +24,7 @@ rmdir
+ xalloc
+ xalloc-die
+ xmalloca
++hashkey-string
+ linkedhash-list
+ linked-list
+ xlist
diff --git a/tools/gnulib/patches/795-string-desc-rename-functions.patch b/tools/gnulib/patches/795-string-desc-rename-functions.patch
new file mode 100644
index 0000000000..032545b063
--- /dev/null
+++ b/tools/gnulib/patches/795-string-desc-rename-functions.patch
@@ -0,0 +1,1137 @@
+From 9a26e7043fa95b4c9ee4576ce8c0ac15668e695e Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Thu, 2 Jan 2025 13:54:54 +0100
+Subject: [PATCH] string-desc, xstring-desc, string-desc-quotearg: Rename
+ functions.
+
+* lib/string-desc.h (sd_equals): Renamed from string_desc_equals.
+(sd_startswith): Renamed from string_desc_startswith.
+(sd_endswith): Renamed from string_desc_endswith.
+(sd_cmp): Renamed from string_desc_cmp.
+(sd_c_casecmp): Renamed from string_desc_c_casecmp.
+(sd_index): Renamed from string_desc_index.
+(sd_last_index): Renamed from string_desc_last_index.
+(sd_contains): Renamed from string_desc_contains.
+(sd_new_empty): Renamed from string_desc_new_empty.
+(sd_new_addr): Renamed from string_desc_new_addr.
+(sd_from_c): Renamed from string_desc_from_c.
+(sd_substring): Renamed from string_desc_substring.
+(sd_write): Renamed from string_desc_write.
+(sd_fwrite): Renamed from string_desc_fwrite.
+(sd_new): Renamed from string_desc_new.
+(sd_new_filled): Renamed from string_desc_new_filled.
+(sd_copy): Renamed from string_desc_copy.
+(sd_concat): Renamed from string_desc_concat.
+(sd_c): Renamed from string_desc_c.
+(sd_set_char_at): Renamed from string_desc_set_char_at.
+(sd_fill): Renamed from string_desc_fill.
+(sd_overwrite): Renamed from string_desc_overwrite.
+(sd_free): Renamed from string_desc_free.
+(sd_length): Renamed from string_desc_length.
+(sd_char_at): Renamed from string_desc_char_at.
+(sd_data): Renamed from string_desc_data.
+(sd_is_empty): Renamed from string_desc_is_empty.
+* lib/string-desc.c (sd_equals): Renamed from string_desc_equals.
+(sd_startswith): Renamed from string_desc_startswith.
+(sd_endswith): Renamed from string_desc_endswith.
+(sd_cmp): Renamed from string_desc_cmp.
+(sd_c_casecmp): Renamed from string_desc_c_casecmp.
+(sd_index): Renamed from string_desc_index.
+(sd_last_index): Renamed from string_desc_last_index.
+(sd_new_empty): Renamed from string_desc_new_empty.
+(sd_new_addr): Renamed from string_desc_new_addr.
+(sd_from_c): Renamed from string_desc_from_c.
+(sd_substring): Renamed from string_desc_substring.
+(sd_write): Renamed from string_desc_write.
+(sd_fwrite): Renamed from string_desc_fwrite.
+(sd_new): Renamed from string_desc_new.
+(sd_new_filled): Renamed from string_desc_new_filled.
+(sd_copy): Renamed from string_desc_copy.
+(sd_concat): Renamed from string_desc_concat.
+(sd_c): Renamed from string_desc_c.
+(sd_set_char_at): Renamed from string_desc_set_char_at.
+(sd_fill): Renamed from string_desc_fill.
+(sd_overwrite): Renamed from string_desc_overwrite.
+(sd_free): Renamed from string_desc_free.
+* lib/xstring-desc.h (xsd_concat): Renamed from xstring_desc_concat.
+(xsd_new): Renamed from xstring_desc_new.
+(xsd_new_filled): Renamed from xstring_desc_new_filled.
+(xsd_copy): Renamed from xstring_desc_copy.
+(xsd_c): Renamed from xstring_desc_c.
+* lib/xstring-desc.c (xsd_concat): Renamed from xstring_desc_concat.
+* lib/string-desc-quotearg.h (sd_quotearg_buffer): Renamed from
+string_desc_quotearg_buffer.
+(sd_quotearg_alloc): Renamed from string_desc_quotearg_alloc.
+(sd_quotearg_n): Renamed from string_desc_quotearg_n.
+(sd_quotearg): Renamed from string_desc_quotearg.
+(sd_quotearg_n_style): Renamed from string_desc_quotearg_n_style.
+(sd_quotearg_style): Renamed from string_desc_quotearg_style.
+(sd_quotearg_char): Renamed from string_desc_quotearg_char.
+(sd_quotearg_colon): Renamed from string_desc_quotearg_colon.
+(sd_quotearg_n_custom): Renamed from string_desc_quotearg_n_custom.
+(sd_quotearg_custom): Renamed from sd_quotearg_n_custom.
+* lib/string-desc-contains.c (sd_contains): Renamed from
+string_desc_contains.
+* lib/string-buffer.h: Update.
+* lib/string-buffer.c (sb_append_desc, sb_contents, sb_dupfree): Update.
+* lib/xstring-buffer.c (sb_xdupfree): Update.
+* lib/sf-istream.c (sf_istream_init_from_string_desc): Update.
+* tests/test-string-desc.c (main): Update.
+* tests/test-string-desc.sh: Update.
+* tests/test-xstring-desc.c (main): Update.
+* tests/test-string-desc-quotearg.c (main): Update.
+* tests/test-string-buffer.c (main): Update.
+* tests/test-sf-istream.c (main): Update.
+* tests/test-sfl-istream.c (main): Update.
+* doc/string-desc.texi: Update.
+* doc/strings.texi: Update.
+* NEWS: Mention the change.
+---
+ ChangeLog | 86 +++++++++
+ NEWS | 4 +
+ doc/string-desc.texi | 4 +-
+ doc/strings.texi | 18 +-
+ lib/sf-istream.c | 4 +-
+ lib/string-buffer.c | 12 +-
+ lib/string-buffer.h | 4 +-
+ lib/string-desc-contains.c | 2 +-
+ lib/string-desc-quotearg.h | 114 ++++++------
+ lib/string-desc.c | 52 +++---
+ lib/string-desc.h | 62 +++----
+ lib/xstring-buffer.c | 4 +-
+ lib/xstring-desc.c | 2 +-
+ lib/xstring-desc.h | 26 +--
+ tests/test-sf-istream.c | 4 +-
+ tests/test-sfl-istream.c | 4 +-
+ tests/test-string-buffer.c | 18 +-
+ tests/test-string-desc-quotearg.c | 44 ++---
+ tests/test-string-desc.c | 296 +++++++++++++++---------------
+ tests/test-string-desc.sh | 4 +-
+ tests/test-xstring-desc.c | 68 +++----
+ 21 files changed, 461 insertions(+), 371 deletions(-)
+
+--- a/lib/sf-istream.c
++++ b/lib/sf-istream.c
+@@ -46,8 +46,8 @@ sf_istream_init_from_string_desc (sf_ist
+ string_desc_t input)
+ {
+ stream->fp = NULL;
+- stream->input = string_desc_data (input);
+- stream->input_end = stream->input + string_desc_length (input);
++ stream->input = sd_data (input);
++ stream->input_end = stream->input + sd_length (input);
+ }
+
+ int
+--- a/lib/string-buffer.c
++++ b/lib/string-buffer.c
+@@ -101,13 +101,13 @@ sb_append1 (struct string_buffer *buffer
+ int
+ sb_append_desc (struct string_buffer *buffer, string_desc_t s)
+ {
+- size_t len = string_desc_length (s);
++ size_t len = sd_length (s);
+ if (sb_ensure_more_bytes (buffer, len) < 0)
+ {
+ buffer->error = true;
+ return -1;
+ }
+- memcpy (buffer->data + buffer->length, string_desc_data (s), len);
++ memcpy (buffer->data + buffer->length, sd_data (s), len);
+ buffer->length += len;
+ return 0;
+ }
+@@ -136,7 +136,7 @@ sb_free (struct string_buffer *buffer)
+ string_desc_t
+ sb_contents (struct string_buffer *buffer)
+ {
+- return string_desc_new_addr (buffer->length, buffer->data);
++ return sd_new_addr (buffer->length, buffer->data);
+ }
+
+ const char *
+@@ -162,7 +162,7 @@ sb_dupfree (struct string_buffer *buffer
+ if (copy == NULL)
+ goto fail;
+ memcpy (copy, buffer->data, length);
+- return string_desc_new_addr (length, copy);
++ return sd_new_addr (length, copy);
+ }
+ else
+ {
+@@ -174,12 +174,12 @@ sb_dupfree (struct string_buffer *buffer
+ if (contents == NULL)
+ goto fail;
+ }
+- return string_desc_new_addr (length, contents);
++ return sd_new_addr (length, contents);
+ }
+
+ fail:
+ sb_free (buffer);
+- return string_desc_new_addr (0, NULL);
++ return sd_new_addr (0, NULL);
+ }
+
+ char *
+--- a/lib/string-buffer.h
++++ b/lib/string-buffer.h
+@@ -115,7 +115,7 @@ extern const char * sb_contents_c (struc
+
+ /* Returns the contents of BUFFER and frees all other memory held by BUFFER.
+ Returns NULL upon failure or if there was an error earlier.
+- It is the responsibility of the caller to string_desc_free() the result. */
++ It is the responsibility of the caller to sd_free() the result. */
+ extern string_desc_t sb_dupfree (struct string_buffer *buffer)
+ _GL_ATTRIBUTE_RELEASE_CAPABILITY (buffer->data);
+
+@@ -182,7 +182,7 @@ extern const char * sb_xcontents_c (stru
+
+ /* Returns the contents of BUFFER and frees all other memory held by BUFFER.
+ Returns (0, NULL) if there was an error earlier.
+- It is the responsibility of the caller to string_desc_free() the result. */
++ It is the responsibility of the caller to sd_free() the result. */
+ extern string_desc_t sb_xdupfree (struct string_buffer *buffer)
+ _GL_ATTRIBUTE_RELEASE_CAPABILITY (buffer->data);
+
+--- a/lib/string-desc-contains.c
++++ b/lib/string-desc-contains.c
+@@ -31,7 +31,7 @@
+ which — depending on platforms — costs up to 2 KB of binary code. */
+
+ ptrdiff_t
+-string_desc_contains (string_desc_t haystack, string_desc_t needle)
++sd_contains (string_desc_t haystack, string_desc_t needle)
+ {
+ if (needle._nbytes == 0)
+ return 0;
+--- a/lib/string-desc-quotearg.h
++++ b/lib/string-desc-quotearg.h
+@@ -50,22 +50,22 @@ extern "C" {
+ does not use backslash escapes and the flags of O do not request
+ elision of null bytes. */
+ #if 0
+-extern size_t string_desc_quotearg_buffer (char *restrict buffer,
+- size_t buffersize,
+- string_desc_t arg,
+- struct quoting_options const *o);
++extern size_t sd_quotearg_buffer (char *restrict buffer,
++ size_t buffersize,
++ string_desc_t arg,
++ struct quoting_options const *o);
+ #endif
+
+-/* Like string_desc_quotearg_buffer, except return the result in a newly
++/* Like sd_quotearg_buffer, except return the result in a newly
+ allocated buffer and store its length, excluding the terminating null
+ byte, in *SIZE. It is the caller's responsibility to free the result.
+ The result might contain embedded null bytes if the style of O does
+ not use backslash escapes and the flags of O do not request elision
+ of null bytes. */
+ #if 0
+-extern char *string_desc_quotearg_alloc (string_desc_t arg,
+- size_t *size,
+- struct quoting_options const *o)
++extern char *sd_quotearg_alloc (string_desc_t arg,
++ size_t *size,
++ struct quoting_options const *o)
+ _GL_ATTRIBUTE_NONNULL ((2))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
+ _GL_ATTRIBUTE_RETURNS_NONNULL;
+@@ -77,68 +77,68 @@ extern char *string_desc_quotearg_alloc
+ reused by the next call to this function with the same value of N.
+ N must be nonnegative. */
+ #if 0
+-extern char *string_desc_quotearg_n (int n, string_desc_t arg);
++extern char *sd_quotearg_n (int n, string_desc_t arg);
+ #endif
+
+-/* Equivalent to string_desc_quotearg_n (0, ARG). */
++/* Equivalent to sd_quotearg_n (0, ARG). */
+ #if 0
+-extern char *string_desc_quotearg (string_desc_t arg);
++extern char *sd_quotearg (string_desc_t arg);
+ #endif
+
+ /* Use style S and storage slot N to return a quoted version of the string ARG.
+- This is like string_desc_quotearg_n (N, ARG), except that it uses S
++ This is like sd_quotearg_n (N, ARG), except that it uses S
+ with no other options to specify the quoting method. */
+ #if 0
+-extern char *string_desc_quotearg_n_style (int n, enum quoting_style s,
+- string_desc_t arg);
++extern char *sd_quotearg_n_style (int n, enum quoting_style s,
++ string_desc_t arg);
+ #endif
+
+-/* Equivalent to string_desc_quotearg_n_style (0, S, ARG). */
++/* Equivalent to sd_quotearg_n_style (0, S, ARG). */
+ #if 0
+-extern char *string_desc_quotearg_style (enum quoting_style s,
+- string_desc_t arg);
++extern char *sd_quotearg_style (enum quoting_style s,
++ string_desc_t arg);
+ #endif
+
+-/* Like string_desc_quotearg (ARG), except also quote any instances of CH.
++/* Like sd_quotearg (ARG), except also quote any instances of CH.
+ See set_char_quoting for a description of acceptable CH values. */
+ #if 0
+-extern char *string_desc_quotearg_char (string_desc_t arg, char ch);
++extern char *sd_quotearg_char (string_desc_t arg, char ch);
+ #endif
+
+-/* Equivalent to string_desc_quotearg_char (ARG, ':'). */
++/* Equivalent to sd_quotearg_char (ARG, ':'). */
+ #if 0
+-extern char *string_desc_quotearg_colon (string_desc_t arg);
++extern char *sd_quotearg_colon (string_desc_t arg);
+ #endif
+
+-/* Like string_desc_quotearg_n_style (N, S, ARG) but with S as
++/* Like sd_quotearg_n_style (N, S, ARG) but with S as
+ custom_quoting_style with left quote as LEFT_QUOTE and right quote
+ as RIGHT_QUOTE. See set_custom_quoting for a description of acceptable
+ LEFT_QUOTE and RIGHT_QUOTE values. */
+ #if 0
+-extern char *string_desc_quotearg_n_custom (int n,
+- char const *left_quote,
+- char const *right_quote,
+- string_desc_t arg);
++extern char *sd_quotearg_n_custom (int n,
++ char const *left_quote,
++ char const *right_quote,
++ string_desc_t arg);
+ #endif
+
+ /* Equivalent to
+- string_desc_quotearg_n_custom (0, LEFT_QUOTE, RIGHT_QUOTE, ARG). */
++ sd_quotearg_n_custom (0, LEFT_QUOTE, RIGHT_QUOTE, ARG). */
+ #if 0
+-extern char *string_desc_quotearg_custom (char const *left_quote,
+- char const *right_quote,
+- string_desc_t arg);
++extern char *sd_quotearg_custom (char const *left_quote,
++ char const *right_quote,
++ string_desc_t arg);
+ #endif
+
+
+ /* ==== Inline function definitions ==== */
+
+ GL_STRING_DESC_QUOTEARG_INLINE size_t
+-string_desc_quotearg_buffer (char *restrict buffer, size_t buffersize,
+- string_desc_t arg,
+- struct quoting_options const *o)
++sd_quotearg_buffer (char *restrict buffer, size_t buffersize,
++ string_desc_t arg,
++ struct quoting_options const *o)
+ {
+ return quotearg_buffer (buffer, buffersize,
+- string_desc_data (arg), string_desc_length (arg),
++ sd_data (arg), sd_length (arg),
+ o);
+ }
+
+@@ -147,69 +147,69 @@ _GL_ATTRIBUTE_NONNULL ((2))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
+ _GL_ATTRIBUTE_RETURNS_NONNULL
+ char *
+-string_desc_quotearg_alloc (string_desc_t arg,
+- size_t *size,
+- struct quoting_options const *o)
++sd_quotearg_alloc (string_desc_t arg,
++ size_t *size,
++ struct quoting_options const *o)
+ {
+- return quotearg_alloc_mem (string_desc_data (arg), string_desc_length (arg),
++ return quotearg_alloc_mem (sd_data (arg), sd_length (arg),
+ size,
+ o);
+ }
+
+ GL_STRING_DESC_QUOTEARG_INLINE char *
+-string_desc_quotearg_n (int n, string_desc_t arg)
++sd_quotearg_n (int n, string_desc_t arg)
+ {
+- return quotearg_n_mem (n, string_desc_data (arg), string_desc_length (arg));
++ return quotearg_n_mem (n, sd_data (arg), sd_length (arg));
+ }
+
+ GL_STRING_DESC_QUOTEARG_INLINE char *
+-string_desc_quotearg (string_desc_t arg)
++sd_quotearg (string_desc_t arg)
+ {
+- return quotearg_mem (string_desc_data (arg), string_desc_length (arg));
++ return quotearg_mem (sd_data (arg), sd_length (arg));
+ }
+
+ GL_STRING_DESC_QUOTEARG_INLINE char *
+-string_desc_quotearg_n_style (int n, enum quoting_style s, string_desc_t arg)
++sd_quotearg_n_style (int n, enum quoting_style s, string_desc_t arg)
+ {
+ return quotearg_n_style_mem (n, s,
+- string_desc_data (arg), string_desc_length (arg));
++ sd_data (arg), sd_length (arg));
+ }
+
+ GL_STRING_DESC_QUOTEARG_INLINE char *
+-string_desc_quotearg_style (enum quoting_style s, string_desc_t arg)
++sd_quotearg_style (enum quoting_style s, string_desc_t arg)
+ {
+ return quotearg_style_mem (s,
+- string_desc_data (arg), string_desc_length (arg));
++ sd_data (arg), sd_length (arg));
+ }
+
+ GL_STRING_DESC_QUOTEARG_INLINE char *
+-string_desc_quotearg_char (string_desc_t arg, char ch)
++sd_quotearg_char (string_desc_t arg, char ch)
+ {
+- return quotearg_char_mem (string_desc_data (arg), string_desc_length (arg),
++ return quotearg_char_mem (sd_data (arg), sd_length (arg),
+ ch);
+ }
+
+ GL_STRING_DESC_QUOTEARG_INLINE char *
+-string_desc_quotearg_colon (string_desc_t arg)
++sd_quotearg_colon (string_desc_t arg)
+ {
+- return quotearg_colon_mem (string_desc_data (arg), string_desc_length (arg));
++ return quotearg_colon_mem (sd_data (arg), sd_length (arg));
+ }
+
+ GL_STRING_DESC_QUOTEARG_INLINE char *
+-string_desc_quotearg_n_custom (int n,
+- char const *left_quote, char const *right_quote,
+- string_desc_t arg)
++sd_quotearg_n_custom (int n,
++ char const *left_quote, char const *right_quote,
++ string_desc_t arg)
+ {
+ return quotearg_n_custom_mem (n, left_quote, right_quote,
+- string_desc_data (arg), string_desc_length (arg));
++ sd_data (arg), sd_length (arg));
+ }
+
+ GL_STRING_DESC_QUOTEARG_INLINE char *
+-string_desc_quotearg_custom (char const *left_quote, char const *right_quote,
+- string_desc_t arg)
++sd_quotearg_custom (char const *left_quote, char const *right_quote,
++ string_desc_t arg)
+ {
+ return quotearg_custom_mem (left_quote, right_quote,
+- string_desc_data (arg), string_desc_length (arg));
++ sd_data (arg), sd_length (arg));
+ }
+
+
+--- a/lib/string-desc.c
++++ b/lib/string-desc.c
+@@ -39,14 +39,14 @@
+
+ /* Return true if A and B are equal. */
+ bool
+-string_desc_equals (string_desc_t a, string_desc_t b)
++sd_equals (string_desc_t a, string_desc_t b)
+ {
+ return (a._nbytes == b._nbytes
+ && (a._nbytes == 0 || memcmp (a._data, b._data, a._nbytes) == 0));
+ }
+
+ bool
+-string_desc_startswith (string_desc_t s, string_desc_t prefix)
++sd_startswith (string_desc_t s, string_desc_t prefix)
+ {
+ return (s._nbytes >= prefix._nbytes
+ && (prefix._nbytes == 0
+@@ -54,7 +54,7 @@ string_desc_startswith (string_desc_t s,
+ }
+
+ bool
+-string_desc_endswith (string_desc_t s, string_desc_t suffix)
++sd_endswith (string_desc_t s, string_desc_t suffix)
+ {
+ return (s._nbytes >= suffix._nbytes
+ && (suffix._nbytes == 0
+@@ -63,7 +63,7 @@ string_desc_endswith (string_desc_t s, s
+ }
+
+ int
+-string_desc_cmp (string_desc_t a, string_desc_t b)
++sd_cmp (string_desc_t a, string_desc_t b)
+ {
+ if (a._nbytes > b._nbytes)
+ {
+@@ -86,14 +86,14 @@ string_desc_cmp (string_desc_t a, string
+ }
+
+ int
+-string_desc_c_casecmp (string_desc_t a, string_desc_t b)
++sd_c_casecmp (string_desc_t a, string_desc_t b)
+ {
+ /* Don't use memcasecmp here, since it uses the current locale, not the
+ "C" locale. */
+- idx_t an = string_desc_length (a);
+- idx_t bn = string_desc_length (b);
+- const char *ap = string_desc_data (a);
+- const char *bp = string_desc_data (b);
++ idx_t an = sd_length (a);
++ idx_t bn = sd_length (b);
++ const char *ap = sd_data (a);
++ const char *bp = sd_data (b);
+ idx_t n = (an < bn ? an : bn);
+ idx_t i;
+ for (i = 0; i < n; i++)
+@@ -108,7 +108,7 @@ string_desc_c_casecmp (string_desc_t a,
+ }
+
+ ptrdiff_t
+-string_desc_index (string_desc_t s, char c)
++sd_index (string_desc_t s, char c)
+ {
+ if (s._nbytes > 0)
+ {
+@@ -120,7 +120,7 @@ string_desc_index (string_desc_t s, char
+ }
+
+ ptrdiff_t
+-string_desc_last_index (string_desc_t s, char c)
++sd_last_index (string_desc_t s, char c)
+ {
+ if (s._nbytes > 0)
+ {
+@@ -132,7 +132,7 @@ string_desc_last_index (string_desc_t s,
+ }
+
+ string_desc_t
+-string_desc_new_empty (void)
++sd_new_empty (void)
+ {
+ string_desc_t result;
+
+@@ -144,7 +144,7 @@ string_desc_new_empty (void)
+ }
+
+ string_desc_t
+-string_desc_new_addr (idx_t n, char *addr)
++sd_new_addr (idx_t n, char *addr)
+ {
+ string_desc_t result;
+
+@@ -158,7 +158,7 @@ string_desc_new_addr (idx_t n, char *add
+ }
+
+ string_desc_t
+-string_desc_from_c (const char *s)
++sd_from_c (const char *s)
+ {
+ string_desc_t result;
+
+@@ -169,7 +169,7 @@ string_desc_from_c (const char *s)
+ }
+
+ string_desc_t
+-string_desc_substring (string_desc_t s, idx_t start, idx_t end)
++sd_substring (string_desc_t s, idx_t start, idx_t end)
+ {
+ string_desc_t result;
+
+@@ -184,7 +184,7 @@ string_desc_substring (string_desc_t s,
+ }
+
+ int
+-string_desc_write (int fd, string_desc_t s)
++sd_write (int fd, string_desc_t s)
+ {
+ if (s._nbytes > 0)
+ if (full_write (fd, s._data, s._nbytes) != s._nbytes)
+@@ -194,7 +194,7 @@ string_desc_write (int fd, string_desc_t
+ }
+
+ int
+-string_desc_fwrite (FILE *fp, string_desc_t s)
++sd_fwrite (FILE *fp, string_desc_t s)
+ {
+ if (s._nbytes > 0)
+ if (fwrite (s._data, 1, s._nbytes, fp) != s._nbytes)
+@@ -206,7 +206,7 @@ string_desc_fwrite (FILE *fp, string_des
+ /* ==== Memory-allocating operations on string descriptors ==== */
+
+ int
+-string_desc_new (string_desc_t *resultp, idx_t n)
++sd_new (string_desc_t *resultp, idx_t n)
+ {
+ string_desc_t result;
+
+@@ -230,7 +230,7 @@ string_desc_new (string_desc_t *resultp,
+ }
+
+ int
+-string_desc_new_filled (string_desc_t *resultp, idx_t n, char c)
++sd_new_filled (string_desc_t *resultp, idx_t n, char c)
+ {
+ string_desc_t result;
+
+@@ -251,7 +251,7 @@ string_desc_new_filled (string_desc_t *r
+ }
+
+ int
+-string_desc_copy (string_desc_t *resultp, string_desc_t s)
++sd_copy (string_desc_t *resultp, string_desc_t s)
+ {
+ string_desc_t result;
+ idx_t n = s._nbytes;
+@@ -273,7 +273,7 @@ string_desc_copy (string_desc_t *resultp
+ }
+
+ int
+-string_desc_concat (string_desc_t *resultp, idx_t n, string_desc_t string1, ...)
++sd_concat (string_desc_t *resultp, idx_t n, string_desc_t string1, ...)
+ {
+ if (n <= 0)
+ /* Invalid argument. */
+@@ -327,7 +327,7 @@ string_desc_concat (string_desc_t *resul
+ }
+
+ char *
+-string_desc_c (string_desc_t s)
++sd_c (string_desc_t s)
+ {
+ idx_t n = s._nbytes;
+ char *result = (char *) imalloc (n + 1);
+@@ -345,7 +345,7 @@ string_desc_c (string_desc_t s)
+ /* ==== Operations with side effects on string descriptors ==== */
+
+ void
+-string_desc_set_char_at (string_desc_t s, idx_t i, char c)
++sd_set_char_at (string_desc_t s, idx_t i, char c)
+ {
+ if (!(i >= 0 && i < s._nbytes))
+ /* Invalid argument. */
+@@ -354,7 +354,7 @@ string_desc_set_char_at (string_desc_t s
+ }
+
+ void
+-string_desc_fill (string_desc_t s, idx_t start, idx_t end, char c)
++sd_fill (string_desc_t s, idx_t start, idx_t end, char c)
+ {
+ if (!(start >= 0 && start <= end))
+ /* Invalid arguments. */
+@@ -365,7 +365,7 @@ string_desc_fill (string_desc_t s, idx_t
+ }
+
+ void
+-string_desc_overwrite (string_desc_t s, idx_t start, string_desc_t t)
++sd_overwrite (string_desc_t s, idx_t start, string_desc_t t)
+ {
+ if (!(start >= 0 && start + t._nbytes <= s._nbytes))
+ /* Invalid arguments. */
+@@ -376,7 +376,7 @@ string_desc_overwrite (string_desc_t s,
+ }
+
+ void
+-string_desc_free (string_desc_t s)
++sd_free (string_desc_t s)
+ {
+ free (s._data);
+ }
+--- a/lib/string-desc.h
++++ b/lib/string-desc.h
+@@ -69,82 +69,82 @@ struct string_desc_t
+
+ /* Return the length of the string S. */
+ #if 0 /* Defined inline below. */
+-extern idx_t string_desc_length (string_desc_t s);
++extern idx_t sd_length (string_desc_t s);
+ #endif
+
+ /* Return the byte at index I of string S.
+ I must be < length(S). */
+ #if 0 /* Defined inline below. */
+-extern char string_desc_char_at (string_desc_t s, idx_t i);
++extern char sd_char_at (string_desc_t s, idx_t i);
+ #endif
+
+ /* Return a read-only view of the bytes of S. */
+ #if 0 /* Defined inline below. */
+-extern const char * string_desc_data (string_desc_t s);
++extern const char * sd_data (string_desc_t s);
+ #endif
+
+ /* Return true if S is the empty string. */
+ #if 0 /* Defined inline below. */
+-extern bool string_desc_is_empty (string_desc_t s);
++extern bool sd_is_empty (string_desc_t s);
+ #endif
+
+ /* Return true if A and B are equal. */
+-extern bool string_desc_equals (string_desc_t a, string_desc_t b);
++extern bool sd_equals (string_desc_t a, string_desc_t b);
+
+ /* Return true if S starts with PREFIX. */
+-extern bool string_desc_startswith (string_desc_t s, string_desc_t prefix);
++extern bool sd_startswith (string_desc_t s, string_desc_t prefix);
+
+ /* Return true if S ends with SUFFIX. */
+-extern bool string_desc_endswith (string_desc_t s, string_desc_t suffix);
++extern bool sd_endswith (string_desc_t s, string_desc_t suffix);
+
+ /* Return > 0, == 0, or < 0 if A > B, A == B, A < B.
+ This uses a lexicographic ordering, where the bytes are compared as
+ 'unsigned char'. */
+-extern int string_desc_cmp (string_desc_t a, string_desc_t b);
++extern int sd_cmp (string_desc_t a, string_desc_t b);
+
+ /* Return > 0, == 0, or < 0 if A > B, A == B, A < B.
+ Either A or B must be entirely ASCII.
+ This uses a lexicographic ordering, where the bytes are compared as
+ 'unsigned char', ignoring case, in the "C" locale. */
+-extern int string_desc_c_casecmp (string_desc_t a, string_desc_t b);
++extern int sd_c_casecmp (string_desc_t a, string_desc_t b);
+
+ /* Return the index of the first occurrence of C in S,
+ or -1 if there is none. */
+-extern ptrdiff_t string_desc_index (string_desc_t s, char c);
++extern ptrdiff_t sd_index (string_desc_t s, char c);
+
+ /* Return the index of the last occurrence of C in S,
+ or -1 if there is none. */
+-extern ptrdiff_t string_desc_last_index (string_desc_t s, char c);
++extern ptrdiff_t sd_last_index (string_desc_t s, char c);
+
+ /* Return the index of the first occurrence of NEEDLE in HAYSTACK,
+ or -1 if there is none. */
+-extern ptrdiff_t string_desc_contains (string_desc_t haystack, string_desc_t needle);
++extern ptrdiff_t sd_contains (string_desc_t haystack, string_desc_t needle);
+
+ /* Return an empty string. */
+-extern string_desc_t string_desc_new_empty (void);
++extern string_desc_t sd_new_empty (void);
+
+ /* Construct and return a string of length N, at the given memory address. */
+-extern string_desc_t string_desc_new_addr (idx_t n, char *addr);
++extern string_desc_t sd_new_addr (idx_t n, char *addr);
+
+ /* Return a string that represents the C string S, of length strlen (S). */
+-extern string_desc_t string_desc_from_c (const char *s);
++extern string_desc_t sd_from_c (const char *s);
+
+ /* Return the substring of S, starting at offset START and ending at offset END.
+ START must be <= END.
+ The result is of length END - START.
+ The result must not be freed (since its storage is part of the storage
+ of S). */
+-extern string_desc_t string_desc_substring (string_desc_t s, idx_t start, idx_t end);
++extern string_desc_t sd_substring (string_desc_t s, idx_t start, idx_t end);
+
+ /* Output S to the file descriptor FD.
+ Return 0 if successful.
+ Upon error, return -1 with errno set. */
+-extern int string_desc_write (int fd, string_desc_t s);
++extern int sd_write (int fd, string_desc_t s);
+
+ /* Output S to the FILE stream FP.
+ Return 0 if successful.
+ Upon error, return -1. */
+-extern int string_desc_fwrite (FILE *fp, string_desc_t s);
++extern int sd_fwrite (FILE *fp, string_desc_t s);
+
+
+ /* ==== Memory-allocating operations on string descriptors ==== */
+@@ -153,61 +153,61 @@ extern int string_desc_fwrite (FILE *fp,
+ Return 0 if successful.
+ Upon error, return -1 with errno set. */
+ _GL_ATTRIBUTE_NODISCARD
+-extern int string_desc_new (string_desc_t *resultp, idx_t n);
++extern int sd_new (string_desc_t *resultp, idx_t n);
+
+ /* Construct a string of length N, filled with C.
+ Return 0 if successful.
+ Upon error, return -1 with errno set. */
+ _GL_ATTRIBUTE_NODISCARD
+-extern int string_desc_new_filled (string_desc_t *resultp, idx_t n, char c);
++extern int sd_new_filled (string_desc_t *resultp, idx_t n, char c);
+
+ /* Construct a copy of string S.
+ Return 0 if successful.
+ Upon error, return -1 with errno set. */
+ _GL_ATTRIBUTE_NODISCARD
+-extern int string_desc_copy (string_desc_t *resultp, string_desc_t s);
++extern int sd_copy (string_desc_t *resultp, string_desc_t s);
+
+ /* Construct the concatenation of N strings. N must be > 0.
+ Return 0 if successful.
+ Upon error, return -1 with errno set. */
+ _GL_ATTRIBUTE_NODISCARD
+-extern int string_desc_concat (string_desc_t *resultp, idx_t n, string_desc_t string1, ...);
++extern int sd_concat (string_desc_t *resultp, idx_t n, string_desc_t string1, ...);
+
+ /* Construct a copy of string S, as a NUL-terminated C string.
+ Return it is successful.
+ Upon error, return NULL with errno set. */
+-extern char * string_desc_c (string_desc_t s) _GL_ATTRIBUTE_DEALLOC_FREE;
++extern char * sd_c (string_desc_t s) _GL_ATTRIBUTE_DEALLOC_FREE;
+
+
+ /* ==== Operations with side effects on string descriptors ==== */
+
+ /* Overwrite the byte at index I of string S with C.
+ I must be < length(S). */
+-extern void string_desc_set_char_at (string_desc_t s, idx_t i, char c);
++extern void sd_set_char_at (string_desc_t s, idx_t i, char c);
+
+ /* Fill part of S, starting at offset START and ending at offset END,
+ with copies of C.
+ START must be <= END. */
+-extern void string_desc_fill (string_desc_t s, idx_t start, idx_t end, char c);
++extern void sd_fill (string_desc_t s, idx_t start, idx_t end, char c);
+
+ /* Overwrite part of S with T, starting at offset START.
+ START + length(T) must be <= length (S). */
+-extern void string_desc_overwrite (string_desc_t s, idx_t start, string_desc_t t);
++extern void sd_overwrite (string_desc_t s, idx_t start, string_desc_t t);
+
+ /* Free S. */
+-extern void string_desc_free (string_desc_t s);
++extern void sd_free (string_desc_t s);
+
+
+ /* ==== Inline function definitions ==== */
+
+ GL_STRING_DESC_INLINE idx_t
+-string_desc_length (string_desc_t s)
++sd_length (string_desc_t s)
+ {
+ return s._nbytes;
+ }
+
+ GL_STRING_DESC_INLINE char
+-string_desc_char_at (string_desc_t s, idx_t i)
++sd_char_at (string_desc_t s, idx_t i)
+ {
+ if (!(i >= 0 && i < s._nbytes))
+ /* Invalid argument. */
+@@ -216,13 +216,13 @@ string_desc_char_at (string_desc_t s, id
+ }
+
+ GL_STRING_DESC_INLINE const char *
+-string_desc_data (string_desc_t s)
++sd_data (string_desc_t s)
+ {
+ return s._data;
+ }
+
+ GL_STRING_DESC_INLINE bool
+-string_desc_is_empty (string_desc_t s)
++sd_is_empty (string_desc_t s)
+ {
+ return s._nbytes == 0;
+ }
+--- a/lib/xstring-buffer.c
++++ b/lib/xstring-buffer.c
+@@ -59,10 +59,10 @@ sb_xdupfree (struct string_buffer *buffe
+ if (buffer->error)
+ {
+ sb_free (buffer);
+- return string_desc_new_addr (0, NULL);
++ return sd_new_addr (0, NULL);
+ }
+ string_desc_t contents = sb_dupfree (buffer);
+- if (string_desc_data (contents) == NULL)
++ if (sd_data (contents) == NULL)
+ xalloc_die ();
+ return contents;
+ }
+--- a/lib/xstring-desc.c
++++ b/lib/xstring-desc.c
+@@ -22,7 +22,7 @@
+ #include "ialloc.h"
+
+ string_desc_t
+-xstring_desc_concat (idx_t n, string_desc_t string1, ...)
++xsd_concat (idx_t n, string_desc_t string1, ...)
+ {
+ if (n <= 0)
+ /* Invalid argument. */
+--- a/lib/xstring-desc.h
++++ b/lib/xstring-desc.h
+@@ -43,53 +43,53 @@ extern "C" {
+
+ /* Return a string of length N, with uninitialized contents. */
+ #if 0 /* Defined inline below. */
+-extern string_desc_t xstring_desc_new (idx_t n);
++extern string_desc_t xsd_new (idx_t n);
+ #endif
+
+ /* Return a string of length N, filled with C. */
+ #if 0 /* Defined inline below. */
+-extern string_desc_t xstring_desc_new_filled (idx_t n, char c);
++extern string_desc_t xsd_new_filled (idx_t n, char c);
+ #endif
+
+ /* Return a copy of string S. */
+ #if 0 /* Defined inline below. */
+-extern string_desc_t xstring_desc_copy (string_desc_t s);
++extern string_desc_t xsd_copy (string_desc_t s);
+ #endif
+
+ /* Return the concatenation of N strings. N must be > 0. */
+-extern string_desc_t xstring_desc_concat (idx_t n, string_desc_t string1, ...);
++extern string_desc_t xsd_concat (idx_t n, string_desc_t string1, ...);
+
+ /* Construct and return a copy of string S, as a NUL-terminated C string. */
+ #if 0 /* Defined inline below. */
+-extern char * xstring_desc_c (string_desc_t s) _GL_ATTRIBUTE_DEALLOC_FREE;
++extern char * xsd_c (string_desc_t s) _GL_ATTRIBUTE_DEALLOC_FREE;
+ #endif
+
+
+ /* ==== Inline function definitions ==== */
+
+ GL_XSTRING_DESC_INLINE string_desc_t
+-xstring_desc_new (idx_t n)
++xsd_new (idx_t n)
+ {
+ string_desc_t result;
+- if (string_desc_new (&result, n) < 0)
++ if (sd_new (&result, n) < 0)
+ xalloc_die ();
+ return result;
+ }
+
+ GL_XSTRING_DESC_INLINE string_desc_t
+-xstring_desc_new_filled (idx_t n, char c)
++xsd_new_filled (idx_t n, char c)
+ {
+ string_desc_t result;
+- if (string_desc_new_filled (&result, n, c) < 0)
++ if (sd_new_filled (&result, n, c) < 0)
+ xalloc_die ();
+ return result;
+ }
+
+ GL_XSTRING_DESC_INLINE string_desc_t
+-xstring_desc_copy (string_desc_t s)
++xsd_copy (string_desc_t s)
+ {
+ string_desc_t result;
+- if (string_desc_copy (&result, s) < 0)
++ if (sd_copy (&result, s) < 0)
+ xalloc_die ();
+ return result;
+ }
+@@ -97,9 +97,9 @@ xstring_desc_copy (string_desc_t s)
+ GL_XSTRING_DESC_INLINE
+ _GL_ATTRIBUTE_DEALLOC_FREE
+ char *
+-xstring_desc_c (string_desc_t s)
++xsd_c (string_desc_t s)
+ {
+- char *result = string_desc_c (s);
++ char *result = sd_c (s);
+ if (result == NULL)
+ xalloc_die ();
+ return result;
+--- a/tests/test-string-desc-quotearg.c
++++ b/tests/test-string-desc-quotearg.c
+@@ -28,75 +28,75 @@
+ int
+ main (void)
+ {
+- string_desc_t s1 = string_desc_from_c ("Hello world!");
+- string_desc_t s2 = string_desc_new_addr (21, "The\0quick\0brown\0\0fox");
++ string_desc_t s1 = sd_from_c ("Hello world!");
++ string_desc_t s2 = sd_new_addr (21, "The\0quick\0brown\0\0fox");
+
+- /* Test string_desc_quotearg_buffer. */
++ /* Test sd_quotearg_buffer. */
+ {
+ char buf[80];
+- size_t n = string_desc_quotearg_buffer (buf, sizeof (buf), s2, NULL);
++ size_t n = sd_quotearg_buffer (buf, sizeof (buf), s2, NULL);
+ ASSERT (n == 21);
+ ASSERT (memcmp (buf, "The\0quick\0brown\0\0fox", n) == 0);
+ }
+
+- /* Test string_desc_quotearg_alloc. */
++ /* Test sd_quotearg_alloc. */
+ {
+ size_t n;
+- char *ret = string_desc_quotearg_alloc (s2, &n, NULL);
++ char *ret = sd_quotearg_alloc (s2, &n, NULL);
+ ASSERT (n == 21);
+ ASSERT (memcmp (ret, "The\0quick\0brown\0\0fox", n) == 0);
+ free (ret);
+ }
+
+- /* Test string_desc_quotearg_n. */
++ /* Test sd_quotearg_n. */
+ {
+- char *ret = string_desc_quotearg_n (1, s2);
++ char *ret = sd_quotearg_n (1, s2);
+ ASSERT (memcmp (ret, "Thequickbrownfox", 16 + 1) == 0);
+ }
+
+- /* Test string_desc_quotearg. */
++ /* Test sd_quotearg. */
+ {
+- char *ret = string_desc_quotearg (s2);
++ char *ret = sd_quotearg (s2);
+ ASSERT (memcmp (ret, "Thequickbrownfox", 16 + 1) == 0);
+ }
+
+- /* Test string_desc_quotearg_n_style. */
++ /* Test sd_quotearg_n_style. */
+ {
+- char *ret = string_desc_quotearg_n_style (1, clocale_quoting_style, s2);
++ char *ret = sd_quotearg_n_style (1, clocale_quoting_style, s2);
+ ASSERT (memcmp (ret, "\"The\\0quick\\0brown\\0\\0fox\\0\"", 28 + 1) == 0
+ || /* if the locale has UTF-8 encoding */
+ memcmp (ret, "\342\200\230The\\0quick\\0brown\\0\\0fox\\0\342\200\231", 32 + 1) == 0);
+ }
+
+- /* Test string_desc_quotearg_style. */
++ /* Test sd_quotearg_style. */
+ {
+- char *ret = string_desc_quotearg_style (clocale_quoting_style, s2);
++ char *ret = sd_quotearg_style (clocale_quoting_style, s2);
+ ASSERT (memcmp (ret, "\"The\\0quick\\0brown\\0\\0fox\\0\"", 28 + 1) == 0
+ || /* if the locale has UTF-8 encoding */
+ memcmp (ret, "\342\200\230The\\0quick\\0brown\\0\\0fox\\0\342\200\231", 32 + 1) == 0);
+ }
+
+- /* Test string_desc_quotearg_char. */
++ /* Test sd_quotearg_char. */
+ {
+- char *ret = string_desc_quotearg_char (s1, ' ');
++ char *ret = sd_quotearg_char (s1, ' ');
+ ASSERT (memcmp (ret, "Hello world!", 12 + 1) == 0); /* ' ' not quoted?! */
+ }
+
+- /* Test string_desc_quotearg_colon. */
++ /* Test sd_quotearg_colon. */
+ {
+- char *ret = string_desc_quotearg_colon (string_desc_from_c ("a:b"));
++ char *ret = sd_quotearg_colon (sd_from_c ("a:b"));
+ ASSERT (memcmp (ret, "a:b", 3 + 1) == 0); /* ':' not quoted?! */
+ }
+
+- /* Test string_desc_quotearg_n_custom. */
++ /* Test sd_quotearg_n_custom. */
+ {
+- char *ret = string_desc_quotearg_n_custom (2, "<", ">", s1);
++ char *ret = sd_quotearg_n_custom (2, "<", ">", s1);
+ ASSERT (memcmp (ret, "<Hello world!>", 14 + 1) == 0);
+ }
+
+- /* Test string_desc_quotearg_n_custom. */
++ /* Test sd_quotearg_n_custom. */
+ {
+- char *ret = string_desc_quotearg_custom ("[[", "]]", s1);
++ char *ret = sd_quotearg_custom ("[[", "]]", s1);
+ ASSERT (memcmp (ret, "[[Hello world!]]", 16 + 1) == 0);
+ }
+
+--- a/tests/test-string-desc.sh
++++ b/tests/test-string-desc.sh
+@@ -6,7 +6,7 @@ ${CHECKER} test-string-desc${EXEEXT} tes
+ printf 'Hello world!The\0quick\0brown\0\0fox\0' > test-string-desc.ok
+
+ : "${DIFF=diff}"
+-${DIFF} test-string-desc.ok test-string-desc-1.tmp || { echo "string_desc_fwrite KO" 1>&2; Exit 1; }
+-${DIFF} test-string-desc.ok test-string-desc-3.tmp || { echo "string_desc_write KO" 1>&2; Exit 1; }
++${DIFF} test-string-desc.ok test-string-desc-1.tmp || { echo "sd_fwrite KO" 1>&2; Exit 1; }
++${DIFF} test-string-desc.ok test-string-desc-3.tmp || { echo "sd_write KO" 1>&2; Exit 1; }
+
+ Exit 0
+--- a/tests/test-xstring-desc.c
++++ b/tests/test-xstring-desc.c
+@@ -28,53 +28,53 @@
+ int
+ main (void)
+ {
+- string_desc_t s0 = string_desc_new_empty ();
+- string_desc_t s1 = string_desc_from_c ("Hello world!");
+- string_desc_t s2 = string_desc_new_addr (21, "The\0quick\0brown\0\0fox");
++ string_desc_t s0 = sd_new_empty ();
++ string_desc_t s1 = sd_from_c ("Hello world!");
++ string_desc_t s2 = sd_new_addr (21, "The\0quick\0brown\0\0fox");
+
+- /* Test xstring_desc_new. */
+- string_desc_t s4 = xstring_desc_new (5);
+- string_desc_set_char_at (s4, 0, 'H');
+- string_desc_set_char_at (s4, 4, 'o');
+- string_desc_set_char_at (s4, 1, 'e');
+- string_desc_fill (s4, 2, 4, 'l');
+- ASSERT (string_desc_length (s4) == 5);
+- ASSERT (string_desc_startswith (s1, s4));
++ /* Test xsd_new. */
++ string_desc_t s4 = xsd_new (5);
++ sd_set_char_at (s4, 0, 'H');
++ sd_set_char_at (s4, 4, 'o');
++ sd_set_char_at (s4, 1, 'e');
++ sd_fill (s4, 2, 4, 'l');
++ ASSERT (sd_length (s4) == 5);
++ ASSERT (sd_startswith (s1, s4));
+
+- /* Test xstring_desc_new_filled. */
+- string_desc_t s5 = xstring_desc_new_filled (5, 'l');
+- string_desc_set_char_at (s5, 0, 'H');
+- string_desc_set_char_at (s5, 4, 'o');
+- string_desc_set_char_at (s5, 1, 'e');
+- ASSERT (string_desc_length (s5) == 5);
+- ASSERT (string_desc_startswith (s1, s5));
++ /* Test xsd_new_filled. */
++ string_desc_t s5 = xsd_new_filled (5, 'l');
++ sd_set_char_at (s5, 0, 'H');
++ sd_set_char_at (s5, 4, 'o');
++ sd_set_char_at (s5, 1, 'e');
++ ASSERT (sd_length (s5) == 5);
++ ASSERT (sd_startswith (s1, s5));
+
+- /* Test xstring_desc_copy. */
++ /* Test xsd_copy. */
+ {
+- string_desc_t s6 = xstring_desc_copy (s0);
+- ASSERT (string_desc_is_empty (s6));
+- string_desc_free (s6);
++ string_desc_t s6 = xsd_copy (s0);
++ ASSERT (sd_is_empty (s6));
++ sd_free (s6);
+ }
+ {
+- string_desc_t s6 = xstring_desc_copy (s2);
+- ASSERT (string_desc_equals (s6, s2));
+- string_desc_free (s6);
++ string_desc_t s6 = xsd_copy (s2);
++ ASSERT (sd_equals (s6, s2));
++ sd_free (s6);
+ }
+
+- /* Test xstring_desc_concat. */
++ /* Test xsd_concat. */
+ {
+ string_desc_t s8 =
+- xstring_desc_concat (3, string_desc_new_addr (10, "The\0quick"),
+- string_desc_new_addr (7, "brown\0"),
+- string_desc_new_addr (4, "fox"),
+- string_desc_new_addr (7, "unused"));
+- ASSERT (string_desc_equals (s8, s2));
+- string_desc_free (s8);
++ xsd_concat (3, sd_new_addr (10, "The\0quick"),
++ sd_new_addr (7, "brown\0"),
++ sd_new_addr (4, "fox"),
++ sd_new_addr (7, "unused"));
++ ASSERT (sd_equals (s8, s2));
++ sd_free (s8);
+ }
+
+- /* Test xstring_desc_c. */
++ /* Test xsd_c. */
+ {
+- char *ptr = xstring_desc_c (s2);
++ char *ptr = xsd_c (s2);
+ ASSERT (ptr != NULL);
+ ASSERT (memcmp (ptr, "The\0quick\0brown\0\0fox\0", 22) == 0);
+ free (ptr);
diff --git a/tools/gnulib/patches/796-vc-mtime-less-read.patch b/tools/gnulib/patches/796-vc-mtime-less-read.patch
new file mode 100644
index 0000000000..3fabe10369
--- /dev/null
+++ b/tools/gnulib/patches/796-vc-mtime-less-read.patch
@@ -0,0 +1,44 @@
+From 60cd34886c2c9f509974239fcf64a61f9a507d14 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Tue, 25 Feb 2025 09:04:28 +0100
+Subject: [PATCH] vc-mtime: Reduce number of read() system calls.
+
+* lib/vc-mtime.c: Include <stddef.h>.
+(git_vc_controlled): Read bytes into a buffer, not one-by-one.
+---
+ ChangeLog | 6 ++++++
+ lib/vc-mtime.c | 15 +++++++++++----
+ 2 files changed, 17 insertions(+), 4 deletions(-)
+
+--- a/lib/vc-mtime.c
++++ b/lib/vc-mtime.c
+@@ -21,6 +21,7 @@
+ /* Specification. */
+ #include "vc-mtime.h"
+
++#include <stddef.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+
+@@ -56,11 +57,17 @@ git_vc_controlled (const char *filename)
+ return false;
+
+ /* Read the subprocess output, and test whether it is non-empty. */
+- size_t count = 0;
+- char c;
++ ptrdiff_t count = 0;
+
+- while (safe_read (fd[0], &c, 1) > 0)
+- count++;
++ for (;;)
++ {
++ char buf[1024];
++ ptrdiff_t n = safe_read (fd[0], buf, sizeof (buf));
++ if (n > 0)
++ count += n;
++ else
++ break;
++ }
+
+ close (fd[0]);
+
diff --git a/tools/gnulib/patches/797-vc-mtime-add-api.patch b/tools/gnulib/patches/797-vc-mtime-add-api.patch
new file mode 100644
index 0000000000..eeb6636e67
--- /dev/null
+++ b/tools/gnulib/patches/797-vc-mtime-add-api.patch
@@ -0,0 +1,968 @@
+From 78269749030dde23182c29376d1410592436eb5d Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Thu, 1 May 2025 17:26:27 +0200
+Subject: [PATCH] vc-mtime: Add API for more efficient use of git.
+
+Reported by Serhii Tereshchenko, Arthur, Adam YS, Foucauld Degeorges
+at <https://savannah.gnu.org/bugs/?66865>.
+
+* lib/vc-mtime.h (max_vc_mtime): New declaration.
+* lib/vc-mtime.c: Include <errno.h>, <stdio.h>, <string.h>, filename.h,
+xalloc.h, xgetcwd.h, xvasprintf.h, gl_map.h, gl_xmap.h, gl_hash_map.h,
+hashkey-string.h, unlocked-io.h.
+(is_git_present): New function, extracted from vc_mtime.
+(vc_mtime): Invoke it.
+(MAX_COMMAND_LENGTH, MAX_CMD_LEN): New macros.
+(abs_git_checkout): New function, based on execute_and_read_line in
+lib/javacomp.c.
+(ancestor_level, relativize): New functions.
+(struct accumulator): New type.
+(accumulate): New function.
+(max_vc_mtime): New function.
+(test_ancestor_level, test_relativize, main) [TEST]: New functions.
+* modules/vc-mtime (Depends-on): Add filename, xalloc, xgetcwd,
+canonicalize-lgpl, xvasprintf, str_startswith, map, xmap, hash-map,
+hashkey-string, getdelim.
+---
+ ChangeLog | 23 ++
+ lib/vc-mtime.c | 866 +++++++++++++++++++++++++++++++++++++++++++++--
+ lib/vc-mtime.h | 7 +
+ modules/vc-mtime | 11 +
+ 4 files changed, 886 insertions(+), 21 deletions(-)
+
+--- a/lib/vc-mtime.c
++++ b/lib/vc-mtime.c
+@@ -21,8 +21,11 @@
+ /* Specification. */
+ #include "vc-mtime.h"
+
++#include <errno.h>
+ #include <stddef.h>
++#include <stdio.h>
+ #include <stdlib.h>
++#include <string.h>
+ #include <unistd.h>
+
+ #include <error.h>
+@@ -32,11 +35,51 @@
+ #include "safe-read.h"
+ #include "xstrtol.h"
+ #include "stat-time.h"
++#include "filename.h"
++#include "xalloc.h"
++#include "xgetcwd.h"
++#include "xvasprintf.h"
++#include "gl_map.h"
++#include "gl_xmap.h"
++#include "gl_hash_map.h"
++#include "hashkey-string.h"
++#if USE_UNLOCKED_IO
++# include "unlocked-io.h"
++#endif
+ #include "gettext.h"
+
+ #define _(msgid) dgettext ("gnulib", msgid)
+
+
++/* ========================================================================== */
++
++/* Determines whether git is present. */
++static bool
++is_git_present (void)
++{
++ static bool git_tested;
++ static bool git_present;
++
++ if (!git_tested)
++ {
++ /* Test for presence of git:
++ "git --version >/dev/null 2>/dev/null" */
++ const char *argv[3];
++ int exitstatus;
++
++ argv[0] = "git";
++ argv[1] = "--version";
++ argv[2] = NULL;
++ exitstatus = execute ("git", "git", argv, NULL, NULL,
++ false, false, true, true,
++ true, false, NULL);
++ git_present = (exitstatus == 0);
++ git_tested = true;
++ }
++
++ return git_present;
++}
++
+ /* Determines whether the specified file is under version control. */
+ static bool
+ git_vc_controlled (const char *filename)
+@@ -178,27 +221,7 @@ git_mtime (struct timespec *mtime, const
+ int
+ vc_mtime (struct timespec *mtime, const char *filename)
+ {
+- static bool git_tested;
+- static bool git_present;
+-
+- if (!git_tested)
+- {
+- /* Test for presence of git:
+- "git --version >/dev/null 2>/dev/null" */
+- const char *argv[3];
+- int exitstatus;
+-
+- argv[0] = "git";
+- argv[1] = "--version";
+- argv[2] = NULL;
+- exitstatus = execute ("git", "git", argv, NULL, NULL,
+- false, false, true, true,
+- true, false, NULL);
+- git_present = (exitstatus == 0);
+- git_tested = true;
+- }
+-
+- if (git_present
++ if (is_git_present ()
+ && git_vc_controlled (filename)
+ && git_unmodified (filename))
+ {
+@@ -213,3 +236,804 @@ vc_mtime (struct timespec *mtime, const
+ }
+ return -1;
+ }
++
++/* ========================================================================== */
++
++/* Maximum length of a command that is guaranteed to work. */
++#if defined _WIN32 || defined __CYGWIN__
++/* Windows */
++# define MAX_COMMAND_LENGTH 8192
++#else
++/* Unix platforms */
++# define MAX_COMMAND_LENGTH 32768
++#endif
++/* Keep some safe distance to this maximum. */
++#define MAX_CMD_LEN ((int) (MAX_COMMAND_LENGTH * 0.8))
++
++/* Returns the directory name of the git checkout that contains tha current
++ directory, as an absolute file name, or NULL if the current directory is
++ not in a git checkout. */
++static char *
++abs_git_checkout (void)
++{
++ /* Run "git rev-parse --show-toplevel 2>/dev/null" and return its output,
++ without the trailing newline. */
++ const char *argv[4];
++ pid_t child;
++ int fd[1];
++
++ argv[0] = "git";
++ argv[1] = "rev-parse";
++ argv[2] = "--show-toplevel";
++ argv[3] = NULL;
++ child = create_pipe_in ("git", "git", argv, NULL, NULL,
++ DEV_NULL, true, true, false, fd);
++
++ if (child == -1)
++ return NULL;
++
++ /* Retrieve its result. */
++ FILE *fp = fdopen (fd[0], "r");
++ if (fp == NULL)
++ error (EXIT_FAILURE, errno, _("fdopen() failed"));
++
++ char *line = NULL;
++ size_t linesize = 0;
++ size_t linelen = getline (&line, &linesize, fp);
++ if (linelen == (size_t)(-1))
++ {
++ fclose (fp);
++ wait_subprocess (child, "git", true, true, true, false, NULL);
++ return NULL;
++ }
++ else
++ {
++ int exitstatus;
++
++ if (linelen > 0 && line[linelen - 1] == '\n')
++ line[linelen - 1] = '\0';
++
++ /* Read until EOF (otherwise the child process may get a SIGPIPE signal). */
++ while (getc (fp) != EOF)
++ ;
++
++ fclose (fp);
++
++ /* Remove zombie process from process list, and retrieve exit status. */
++ exitstatus =
++ wait_subprocess (child, "git", true, true, true, false, NULL);
++ if (exitstatus == 0)
++ return line;
++ }
++ free (line);
++ return NULL;
++}
++
++/* Given an absolute canonicalized directory DIR1 and an absolute canonicalized
++ directory DIR2, returns N where DIR1 = DIR2 "/.." ... "/.." with N times
++ "/..", or -1 if DIR1 is not an ancestor directory of DIR2. */
++static long
++ancestor_level (const char *dir1, const char *dir2)
++{
++ if (strcmp (dir1, "/") == 0)
++ dir1 = "";
++ if (strcmp (dir2, "/") == 0)
++ dir2 = "";
++ size_t dir1_len = strlen (dir1);
++ if (strncmp (dir1, dir2, dir1_len) == 0)
++ {
++ /* DIR2 starts with DIR1. */
++ const char *p = dir2 + dir1_len;
++ if (*p == '\0')
++ /* DIR2 and DIR1 are the same. */
++ return 0;
++ if (ISSLASH (*p))
++ {
++ /* Return the number of slashes in the tail of DIR2 that starts
++ at P. */
++ long n = 1;
++ p++;
++ for (; *p != '\0'; p++)
++ if (ISSLASH (*p))
++ n++;
++ return n;
++ }
++ }
++ return -1;
++}
++
++/* Given an absolute canolicalized FILENAME that starts with DIR1, returns the
++ same file name relative to DIR2, where DIR1 = DIR2 "/.." ... "/.." with
++ N times "/..", as a freshly allocated string. */
++static char *
++relativize (const char *filename,
++ unsigned long n, const char *dir1, const char *dir2)
++{
++ if (strcmp (dir1, "/") == 0)
++ dir1 = "";
++ size_t dir1_len = strlen (dir1);
++ if (!(strncmp (filename, dir1, dir1_len) == 0
++ && (filename[dir1_len] == '\0' || ISSLASH (filename[dir1_len]))))
++ /* Invalid argument. */
++ abort ();
++ if (strcmp (dir2, "/") == 0)
++ dir2 = "";
++
++ dir2 += dir1_len;
++ filename += dir1_len;
++ for (;;)
++ {
++ /* Invariant: The result will be N times "../" followed by FILENAME. */
++ if (*filename == '\0')
++ break;
++ if (!ISSLASH (*filename))
++ abort ();
++ filename++;
++ if (*dir2 == '\0')
++ break;
++ if (!ISSLASH (*dir2))
++ abort ();
++ dir2++;
++ /* Skip one component in DIR2. */
++ const char *dir2_s;
++ for (dir2_s = dir2; *dir2_s != '\0'; dir2_s++)
++ if (ISSLASH (*dir2_s))
++ break;
++ /* Skip one component in FILENAME, at P. */
++ const char *filename_s;
++ for (filename_s = filename; *filename_s != '\0'; filename_s++)
++ if (ISSLASH (*filename_s))
++ break;
++ /* Did the components match? */
++ if (!(filename_s - filename == dir2_s - dir2
++ && memcmp (filename, dir2, dir2_s - dir2) == 0))
++ break;
++ dir2 = dir2_s;
++ filename = filename_s;
++ n--;
++ }
++
++ if (n == 0 && *filename == '\0')
++ return xstrdup (".");
++
++ char *result = (char *) xmalloc (3 * n + strlen (filename) + 1);
++ {
++ char *q = result;
++ for (; n > 0; n--)
++ {
++ q[0] = '.'; q[1] = '.'; q[2] = '/'; q += 3;
++ }
++ strcpy (q, filename);
++ }
++ return result;
++}
++
++/* Accumulating mtimes. */
++struct accumulator
++{
++ bool has_some_mtimes;
++ struct timespec max_of_mtimes;
++};
++
++static void
++accumulate (struct accumulator *accu, struct timespec mtime)
++{
++ if (accu->has_some_mtimes)
++ {
++ /* Compute the maximum of accu->max_of_mtimes and mtime. */
++ if (accu->max_of_mtimes.tv_sec < mtime.tv_sec
++ || (accu->max_of_mtimes.tv_sec == mtime.tv_sec
++ && accu->max_of_mtimes.tv_nsec < mtime.tv_nsec))
++ accu->max_of_mtimes = mtime;
++ }
++ else
++ {
++ accu->max_of_mtimes = mtime;
++ accu->has_some_mtimes = true;
++ }
++}
++
++int
++max_vc_mtime (struct timespec *max_of_mtimes,
++ size_t nfiles, const char * const *filenames)
++{
++ if (nfiles == 0)
++ /* Invalid argument. */
++ abort ();
++
++ struct accumulator accu = { false };
++
++ /* Determine which of the specified files are under version control,
++ and which are duplicates. (The case of duplicates is rare, but it needs
++ special attention, because 'git ls-files' eliminates duplicates.)
++ vc_controlled[n] = 1 means that filenames[n] is under version control.
++ vc_controlled[n] = 0 means that filenames[n] is not under version control.
++ vc_controlled[n] = -1 means that filenames[n] is a duplicate. */
++ signed char *vc_controlled = XNMALLOC (nfiles, signed char);
++ for (size_t n = 0; n < nfiles; n++)
++ vc_controlled[n] = 0;
++
++ if (is_git_present ())
++ {
++ /* Since 'git ls-files' produces an error when at least one of the files
++ is outside the git checkout that contains tha current directory, we
++ need to filter out such files. This is most easily done by converting
++ each file name to a canonical file name first and then comparing with
++ the directory name of said git checkout. */
++ char *git_checkout = abs_git_checkout ();
++ if (git_checkout != NULL)
++ {
++ char *currdir = xgetcwd ();
++ /* git_checkout is expected to be an ancestor directory of the
++ current directory. */
++ long ancestor = ancestor_level (git_checkout, currdir);
++ if (ancestor >= 0)
++ {
++ char **canonical_filenames = XNMALLOC (nfiles, char *);
++ for (size_t n = 0; n < nfiles; n++)
++ {
++ char *canonical = canonicalize_file_name (filenames[n]);
++ if (canonical == NULL)
++ {
++ if (errno == ENOMEM)
++ xalloc_die ();
++ /* The file filenames[n] does not exist. */
++ for (size_t k = n; k > 0; )
++ free (canonical_filenames[--k]);
++ free (canonical_filenames);
++ free (currdir);
++ free (git_checkout);
++ free (vc_controlled);
++ return -1;
++ }
++ canonical_filenames[n] = canonical;
++ }
++
++ /* Test which of these absolute file names are outside of the
++ git_checkout. */
++ char *git_checkout_slash =
++ (strcmp (git_checkout, "/") == 0
++ ? xstrdup (git_checkout)
++ : xasprintf ("%s/", git_checkout));
++
++ char **checkout_relative_filenames = XNMALLOC (nfiles, char *);
++ char **currdir_relative_filenames = XNMALLOC (nfiles, char *);
++ for (size_t n = 0; n < nfiles; n++)
++ {
++ if (str_startswith (canonical_filenames[n], git_checkout_slash))
++ {
++ vc_controlled[n] = 1;
++ checkout_relative_filenames[n] =
++ relativize (canonical_filenames[n],
++ 0, git_checkout, git_checkout);
++ currdir_relative_filenames[n] =
++ relativize (canonical_filenames[n],
++ ancestor, git_checkout, currdir);
++ }
++ else
++ {
++ vc_controlled[n] = 0;
++ checkout_relative_filenames[n] = NULL;
++ currdir_relative_filenames[n] = NULL;
++ }
++ }
++
++ /* Room for passing arguments to git commands. */
++ const char **argv = XNMALLOC (6 + nfiles + 1, const char *);
++
++ {
++ /* Put the relative file names into a hash table. This is needed
++ because 'git ls-files' returns the files in a different order
++ than the one we provide in the command. */
++ gl_map_t relative_filenames_ht =
++ gl_map_create_empty (GL_HASH_MAP,
++ hashkey_string_equals, hashkey_string_hash,
++ NULL, NULL);
++ for (size_t n = 0; n < nfiles; n++)
++ if (currdir_relative_filenames[n] != NULL)
++ {
++ if (gl_map_get (relative_filenames_ht, currdir_relative_filenames[n]) != NULL)
++ {
++ /* It's already in the table. */
++ vc_controlled[n] = -1;
++ }
++ else
++ gl_map_put (relative_filenames_ht, currdir_relative_filenames[n], &vc_controlled[n]);
++ }
++
++ /* Run "git ls-files -c -o -t -z FILE1..." for as many files as
++ possible, and inspect the output. */
++ size_t n0 = 0;
++ do
++ {
++ size_t i = 0;
++ argv[i++] = "git";
++ argv[i++] = "ls-files";
++ argv[i++] = "-c";
++ argv[i++] = "-o";
++ argv[i++] = "-t";
++ argv[i++] = "-z";
++ size_t i0 = i;
++
++ size_t n = n0;
++ size_t cmd_len = 25;
++ for (; n < nfiles; n++)
++ {
++ if (vc_controlled[n] == 1)
++ {
++ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
++ && i > i0)
++ break;
++ argv[i++] = currdir_relative_filenames[n];
++ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
++ }
++ n++;
++ }
++ if (i > i0)
++ {
++ pid_t child;
++ int fd[1];
++
++ argv[i] = NULL;
++ child = create_pipe_in ("git", "git", argv, NULL, NULL,
++ DEV_NULL, true, true, false, fd);
++ if (child == -1)
++ break;
++
++ /* Read the subprocess output. It is expected to be of the form
++ T1 <space> <currdir_relative_filename1> NUL
++ T2 <space> <currdir_relative_filename2> NUL
++ ...
++ where the relative filenames correspond to the given file
++ names (because we have already relativized them). */
++ FILE *fp = fdopen (fd[0], "r");
++ if (fp == NULL)
++ error (EXIT_FAILURE, errno, _("fdopen() failed"));
++
++ char *fn = NULL;
++ size_t fn_size = 0;
++ for (;;)
++ {
++ int status = fgetc (fp);
++ if (status == EOF)
++ break;
++ /* status is a status tag, as documented in
++ "man git-ls-files". */
++
++ int space = fgetc (fp);
++ if (space != ' ')
++ {
++ fprintf (stderr, "vc-mtime: git ls-files output not as expected\n");
++ break;
++ }
++
++ if (getdelim (&fn, &fn_size, '\0', fp) == -1)
++ {
++ if (errno == ENOMEM)
++ xalloc_die ();
++ fprintf (stderr, "vc-mtime: failed to read git ls-files output\n");
++ break;
++ }
++ signed char *vc_controlled_p =
++ (signed char *) gl_map_get (relative_filenames_ht, fn);
++ if (vc_controlled_p == NULL)
++ fprintf (stderr, "vc-mtime: git ls-files returned an unexpected file name: %s\n", fn);
++ else
++ *vc_controlled_p = (status == 'H' ? 1 : 0);
++ }
++
++ free (fn);
++ fclose (fp);
++
++ /* Remove zombie process from process list, and retrieve exit status. */
++ int exitstatus =
++ wait_subprocess (child, "git", false, true, true, false, NULL);
++ if (exitstatus != 0)
++ fprintf (stderr, "vc-mtime: git ls-files failed with exit code %d\n", exitstatus);
++ }
++ n0 = n;
++ }
++ while (n0 < nfiles);
++
++ gl_map_free (relative_filenames_ht);
++ }
++
++ {
++ /* Put the relative file names into a hash table. This is needed
++ because 'git diff' returns the files in a different order
++ than the one we provide in the command. */
++ gl_map_t relative_filenames_ht =
++ gl_map_create_empty (GL_HASH_MAP,
++ hashkey_string_equals, hashkey_string_hash,
++ NULL, NULL);
++ for (size_t n = 0; n < nfiles; n++)
++ if (vc_controlled[n] == 1)
++ {
++ /* No need to test for duplicates here. We have already set
++ vc_controlled[n] to -1 for duplicates, above. */
++ gl_map_put (relative_filenames_ht, checkout_relative_filenames[n], &vc_controlled[n]);
++ }
++
++ /* Run "git diff --name-only --no-relative -z HEAD -- FILE1..." for
++ as many files as possible, and inspect the output. */
++ size_t n0 = 0;
++ do
++ {
++ size_t i = 0;
++ argv[i++] = "git";
++ argv[i++] = "diff";
++ argv[i++] = "--name-only";
++ argv[i++] = "--no-relative";
++ argv[i++] = "-z";
++ argv[i++] = "HEAD";
++ argv[i++] = "--";
++ size_t i0 = i;
++
++ size_t n = n0;
++ size_t cmd_len = 46;
++ for (; n < nfiles; n++)
++ {
++ if (vc_controlled[n] == 1)
++ {
++ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
++ && i > i0)
++ break;
++ argv[i++] = currdir_relative_filenames[n];
++ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
++ }
++ n++;
++ }
++ if (i > i0)
++ {
++ pid_t child;
++ int fd[1];
++
++ argv[i] = NULL;
++ child = create_pipe_in ("git", "git", argv, NULL, NULL,
++ DEV_NULL, true, true, false, fd);
++ if (child == -1)
++ break;
++
++ /* Read the subprocess output. It is expected to be of the form
++ <checkout_relative_filename1> NUL
++ <checkout_relative_filename2> NUL
++ ...
++ where the relative filenames are relative to the git
++ checkout dir, not to currdir! */
++ FILE *fp = fdopen (fd[0], "r");
++ if (fp == NULL)
++ error (EXIT_FAILURE, errno, _("fdopen() failed"));
++
++ char *fn = NULL;
++ size_t fn_size = 0;
++ for (;;)
++ {
++ /* Test for EOF. */
++ int c = fgetc (fp);
++ if (c == EOF)
++ break;
++ ungetc (c, fp);
++
++ if (getdelim (&fn, &fn_size, '\0', fp) == -1)
++ {
++ if (errno == ENOMEM)
++ xalloc_die ();
++ fprintf (stderr, "vc-mtime: failed to read git diff output\n");
++ break;
++ }
++ signed char *vc_controlled_p =
++ (signed char *) gl_map_get (relative_filenames_ht, fn);
++ if (vc_controlled_p == NULL)
++ fprintf (stderr, "vc-mtime: git diff returned an unexpected file name: %s\n", fn);
++ else
++ /* filenames[n] is under version control but is modified.
++ Treat it like a file not under version control. */
++ *vc_controlled_p = 0;
++ }
++
++ free (fn);
++ fclose (fp);
++
++ /* Remove zombie process from process list, and retrieve exit status. */
++ int exitstatus =
++ wait_subprocess (child, "git", false, true, true, false, NULL);
++ if (exitstatus != 0)
++ fprintf (stderr, "vc-mtime: git diff failed with exit code %d\n", exitstatus);
++ }
++ n0 = n;
++ }
++ while (n0 < nfiles);
++
++ gl_map_free (relative_filenames_ht);
++ }
++
++ {
++ /* Run "git log -1 --format=%ct -- FILE1...". It prints the
++ time of last modification (the 'CommitDate', not the
++ 'AuthorDate' which merely represents the time at which the
++ author locally committed the first version of the change),
++ as the number of seconds since the Epoch. The '--' option
++ is for the case that the specified file was removed. */
++ size_t n0 = 0;
++ do
++ {
++ size_t i = 0;
++ argv[i++] = "git";
++ argv[i++] = "log";
++ argv[i++] = "-1";
++ argv[i++] = "--format=%ct";
++ argv[i++] = "--";
++ size_t i0 = i;
++
++ size_t n = n0;
++ size_t cmd_len = 27;
++ for (; n < nfiles; n++)
++ {
++ if (vc_controlled[n] == 1)
++ {
++ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
++ && i > i0)
++ break;
++ argv[i++] = currdir_relative_filenames[n];
++ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
++ }
++ n++;
++ }
++ if (i > i0)
++ {
++ pid_t child;
++ int fd[1];
++
++ argv[i] = NULL;
++ child = create_pipe_in ("git", "git", argv, NULL, NULL,
++ DEV_NULL, true, true, false, fd);
++ if (child == -1)
++ break;
++
++ /* Read the subprocess output. It is expected to be a
++ single line, containing a positive integer. */
++ FILE *fp = fdopen (fd[0], "r");
++ if (fp == NULL)
++ error (EXIT_FAILURE, errno, _("fdopen() failed"));
++
++ char *line = NULL;
++ size_t linesize = 0;
++ size_t linelen = getline (&line, &linesize, fp);
++ if (linelen == (size_t)(-1))
++ {
++ if (errno == ENOMEM)
++ xalloc_die ();
++ fprintf (stderr, "vc-mtime: failed to read git log output\n");
++ git_log_fail1:
++ free (line);
++ fclose (fp);
++ wait_subprocess (child, "git", true, false, true, false, NULL);
++ git_log_fail2:
++ free (argv);
++ for (size_t k = nfiles; k > 0; )
++ free (currdir_relative_filenames[--k]);
++ free (currdir_relative_filenames);
++ for (size_t k = nfiles; k > 0; )
++ free (checkout_relative_filenames[--k]);
++ free (checkout_relative_filenames);
++ free (git_checkout_slash);
++ for (size_t k = nfiles; k > 0; )
++ free (canonical_filenames[--k]);
++ free (canonical_filenames);
++ free (currdir);
++ free (git_checkout);
++ free (vc_controlled);
++ return -1;
++ }
++ if (linelen > 0 && line[linelen - 1] == '\n')
++ line[linelen - 1] = '\0';
++
++ char *endptr;
++ unsigned long git_log_time;
++ if (!(xstrtoul (line, &endptr, 10, &git_log_time, NULL) == LONGINT_OK
++ && endptr == line + strlen (line)))
++ {
++ fprintf (stderr, "vc-mtime: git log output not as expected\n");
++ goto git_log_fail1;
++ }
++
++ struct timespec mtime;
++ mtime.tv_sec = git_log_time;
++ mtime.tv_nsec = 0;
++ accumulate (&accu, mtime);
++
++ free (line);
++ fclose (fp);
++
++ /* Remove zombie process from process list, and retrieve exit status. */
++ int exitstatus =
++ wait_subprocess (child, "git", false, true, true, false, NULL);
++ if (exitstatus != 0)
++ {
++ fprintf (stderr, "vc-mtime: git log failed with exit code %d\n", exitstatus);
++ goto git_log_fail2;
++ }
++ }
++ n0 = n;
++ }
++ while (n0 < nfiles);
++ }
++
++ free (argv);
++ for (size_t k = nfiles; k > 0; )
++ free (currdir_relative_filenames[--k]);
++ free (currdir_relative_filenames);
++ for (size_t k = nfiles; k > 0; )
++ free (checkout_relative_filenames[--k]);
++ free (checkout_relative_filenames);
++ free (git_checkout_slash);
++ for (size_t k = nfiles; k > 0; )
++ free (canonical_filenames[--k]);
++ free (canonical_filenames);
++ }
++ free (currdir);
++ }
++ free (git_checkout);
++ }
++
++ /* For the files that are not under version control, or that are modified
++ compared to HEAD, use the file's time stamp. */
++ for (size_t n = 0; n < nfiles; n++)
++ if (vc_controlled[n] == 0)
++ {
++ struct stat statbuf;
++ if (stat (filenames[n], &statbuf) < 0)
++ {
++ free (vc_controlled);
++ return -1;
++ }
++
++ struct timespec mtime = get_stat_mtime (&statbuf);
++ accumulate (&accu, mtime);
++ }
++
++ free (vc_controlled);
++
++ /* Since nfiles > 0, we must have accumulated at least one mtime. */
++ if (!accu.has_some_mtimes)
++ abort ();
++ *max_of_mtimes = accu.max_of_mtimes;
++ return 0;
++}
++
++/* ========================================================================== */
++
++#ifdef TEST
++
++#include <assert.h>
++#include <stdio.h>
++#include <time.h>
++
++/* Some unit tests for internal functions. */
++
++static void
++test_ancestor_level (void)
++{
++ assert (ancestor_level ("/home/user/projects/gnulib", "/home/user/projects/gnulib") == 0);
++ assert (ancestor_level ("/", "/") == 0);
++
++ assert (ancestor_level ("/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto") == 2);
++ assert (ancestor_level ("/", "/home/user") == 2);
++
++ assert (ancestor_level ("/home/user/.local", "/home/user/projects/gnulib") == -1);
++ assert (ancestor_level ("/.local", "/home/user") == -1);
++ assert (ancestor_level ("/.local", "/") == -1);
++}
++
++static void
++test_relativize (void)
++{
++ assert (strcmp (relativize ("/home/user/projects/gnulib",
++ 0, "/home/user/projects/gnulib", "/home/user/projects/gnulib"),
++ ".") == 0);
++ assert (strcmp (relativize ("/home/user/projects/gnulib/NEWS",
++ 0, "/home/user/projects/gnulib", "/home/user/projects/gnulib"),
++ "NEWS") == 0);
++ assert (strcmp (relativize ("/home/user/projects/gnulib/doc/Makefile",
++ 0, "/home/user/projects/gnulib", "/home/user/projects/gnulib"),
++ "doc/Makefile") == 0);
++
++ assert (strcmp (relativize ("/",
++ 0, "/", "/"),
++ ".") == 0);
++ assert (strcmp (relativize ("/swapfile",
++ 0, "/", "/"),
++ "swapfile") == 0);
++ assert (strcmp (relativize ("/etc/passwd",
++ 0, "/", "/"),
++ "etc/passwd") == 0);
++
++ assert (strcmp (relativize ("/home/user/projects/gnulib",
++ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
++ "../../") == 0);
++ assert (strcmp (relativize ("/home/user/projects/gnulib/lib",
++ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
++ "../") == 0);
++ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/crypto",
++ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
++ ".") == 0);
++ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/malloc",
++ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
++ "../malloc") == 0);
++ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/cr",
++ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
++ "../cr") == 0);
++ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/cryptography",
++ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
++ "../cryptography") == 0);
++ assert (strcmp (relativize ("/home/user/projects/gnulib/doc",
++ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
++ "../../doc") == 0);
++ assert (strcmp (relativize ("/home/user/projects/gnulib/doc/Makefile",
++ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
++ "../../doc/Makefile") == 0);
++
++ assert (strcmp (relativize ("/",
++ 2, "/", "/home/user"),
++ "../../") == 0);
++ assert (strcmp (relativize ("/home",
++ 2, "/", "/home/user"),
++ "../") == 0);
++ assert (strcmp (relativize ("/home/user",
++ 2, "/", "/home/user"),
++ ".") == 0);
++ assert (strcmp (relativize ("/home/root",
++ 2, "/", "/home/user"),
++ "../root") == 0);
++ assert (strcmp (relativize ("/home/us",
++ 2, "/", "/home/user"),
++ "../us") == 0);
++ assert (strcmp (relativize ("/home/users",
++ 2, "/", "/home/user"),
++ "../users") == 0);
++ assert (strcmp (relativize ("/etc",
++ 2, "/", "/home/user"),
++ "../../etc") == 0);
++ assert (strcmp (relativize ("/etc/passwd",
++ 2, "/", "/home/user"),
++ "../../etc/passwd") == 0);
++}
++
++/* Usage: ./a.out FILE[...]
++ */
++int
++main (int argc, char *argv[])
++{
++ test_ancestor_level ();
++ test_relativize ();
++
++ if (argc == 1)
++ {
++ fprintf (stderr, "Usage: ./a.out FILE[...]\n");
++ return 1;
++ }
++ struct timespec mtime;
++ int ret = max_vc_mtime (&mtime, argc - 1, (const char **) argv + 1);
++ if (ret == 0)
++ {
++ time_t t = mtime.tv_sec;
++ struct tm *gmt = gmtime (&t);
++ printf ("mtime = %04d-%02d-%02d %02d:%02d:%02d UTC\n",
++ gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday,
++ gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
++ return 0;
++ }
++ else
++ {
++ printf ("failed\n");
++ return 1;
++ }
++}
++
++/*
++ * Local Variables:
++ * compile-command: "gcc -ggdb -DTEST -Wall -I. -I.. vc-mtime.c libgnu.a"
++ * End:
++ */
++
++#endif
+--- a/lib/vc-mtime.h
++++ b/lib/vc-mtime.h
+@@ -90,6 +90,13 @@ extern "C" {
+ Upon failure, it returns -1. */
+ extern int vc_mtime (struct timespec *mtime, const char *filename);
+
++/* Determines the maximum of the version-controlled modification times of
++ FILENAMES[0..NFILES-1], and returns 0.
++ Upon failure, it returns -1.
++ NFILES must be > 0. */
++extern int max_vc_mtime (struct timespec *max_of_mtimes,
++ size_t nfiles, const char * const *filenames);
++
+ #ifdef __cplusplus
+ }
+ #endif
+--- a/modules/vc-mtime
++++ b/modules/vc-mtime
+@@ -16,6 +16,17 @@ error
+ getline
+ xstrtol
+ stat-time
++filename
++xalloc
++xgetcwd
++canonicalize-lgpl
++xvasprintf
++str_startswith
++map
++xmap
++hash-map
++hashkey-string
++getdelim
+ gettext-h
+ gnulib-i18n
+
diff --git a/tools/gnulib/patches/798-vc-mtime-add-api.patch b/tools/gnulib/patches/798-vc-mtime-add-api.patch
new file mode 100644
index 0000000000..2cf7edab4e
--- /dev/null
+++ b/tools/gnulib/patches/798-vc-mtime-add-api.patch
@@ -0,0 +1,91 @@
+From f4c40c2d6aabef8e587176bbf5226c8bc6649574 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Fri, 2 May 2025 02:43:23 +0200
+Subject: [PATCH] vc-mtime: Add API for more efficient use of git, part 2.
+
+* lib/vc-mtime.c (max_vc_mtime): Don't skip the odd-numbered arguments.
+---
+ ChangeLog | 5 +++++
+ lib/vc-mtime.c | 57 +++++++++++++++++++++-----------------------------
+ 2 files changed, 29 insertions(+), 33 deletions(-)
+
+--- a/lib/vc-mtime.c
++++ b/lib/vc-mtime.c
+@@ -558,17 +558,14 @@ max_vc_mtime (struct timespec *max_of_mt
+ size_t n = n0;
+ size_t cmd_len = 25;
+ for (; n < nfiles; n++)
+- {
+- if (vc_controlled[n] == 1)
+- {
+- if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
+- && i > i0)
+- break;
+- argv[i++] = currdir_relative_filenames[n];
+- cmd_len += 1 + strlen (currdir_relative_filenames[n]);
+- }
+- n++;
+- }
++ if (vc_controlled[n] == 1)
++ {
++ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
++ && i > i0)
++ break;
++ argv[i++] = currdir_relative_filenames[n];
++ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
++ }
+ if (i > i0)
+ {
+ pid_t child;
+@@ -672,17 +669,14 @@ max_vc_mtime (struct timespec *max_of_mt
+ size_t n = n0;
+ size_t cmd_len = 46;
+ for (; n < nfiles; n++)
+- {
+- if (vc_controlled[n] == 1)
+- {
+- if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
+- && i > i0)
+- break;
+- argv[i++] = currdir_relative_filenames[n];
+- cmd_len += 1 + strlen (currdir_relative_filenames[n]);
+- }
+- n++;
+- }
++ if (vc_controlled[n] == 1)
++ {
++ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
++ && i > i0)
++ break;
++ argv[i++] = currdir_relative_filenames[n];
++ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
++ }
+ if (i > i0)
+ {
+ pid_t child;
+@@ -768,17 +762,14 @@ max_vc_mtime (struct timespec *max_of_mt
+ size_t n = n0;
+ size_t cmd_len = 27;
+ for (; n < nfiles; n++)
+- {
+- if (vc_controlled[n] == 1)
+- {
+- if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
+- && i > i0)
+- break;
+- argv[i++] = currdir_relative_filenames[n];
+- cmd_len += 1 + strlen (currdir_relative_filenames[n]);
+- }
+- n++;
+- }
++ if (vc_controlled[n] == 1)
++ {
++ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
++ && i > i0)
++ break;
++ argv[i++] = currdir_relative_filenames[n];
++ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
++ }
+ if (i > i0)
+ {
+ pid_t child;
diff --git a/tools/gnulib/patches/799-vc-mtime-old-git.patch b/tools/gnulib/patches/799-vc-mtime-old-git.patch
new file mode 100644
index 0000000000..4c2082504b
--- /dev/null
+++ b/tools/gnulib/patches/799-vc-mtime-old-git.patch
@@ -0,0 +1,125 @@
+From 47548a77525a0f4489c9c420ccc2159079365da8 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Fri, 2 May 2025 12:09:40 +0200
+Subject: [PATCH] vc-mtime: Make it work with git versions < 2.28.
+
+* lib/vc-mtime.c (git_version): New variable.
+(is_git_present): Read the output of "git --version", and set
+git_version.
+(max_vc_mtime): Don't pass option --no-relative if the git version
+is < 2.28.
+---
+ ChangeLog | 9 ++++++
+ lib/vc-mtime.c | 82 +++++++++++++++++++++++++++++++++++++++++++++-----
+ 2 files changed, 83 insertions(+), 8 deletions(-)
+
+--- a/lib/vc-mtime.c
++++ b/lib/vc-mtime.c
+@@ -53,7 +53,9 @@
+
+ /* ========================================================================== */
+
+-/* Determines whether git is present. */
++static const char *git_version;
++
++/* Determines whether git is present, and sets git_version if so. */
+ static bool
+ is_git_present (void)
+ {
+@@ -63,17 +65,67 @@ is_git_present (void)
+ if (!git_tested)
+ {
+ /* Test for presence of git:
+- "git --version >/dev/null 2>/dev/null" */
++ "git --version 2>/dev/null" */
+ const char *argv[3];
+- int exitstatus;
++ pid_t child;
++ int fd[1];
+
+ argv[0] = "git";
+ argv[1] = "--version";
+ argv[2] = NULL;
+- exitstatus = execute ("git", "git", argv, NULL, NULL,
+- false, false, true, true,
+- true, false, NULL);
+- git_present = (exitstatus == 0);
++ child = create_pipe_in ("git", "git", argv, NULL, NULL,
++ DEV_NULL, true, true, false, fd);
++ if (child == -1)
++ git_present = false;
++ else
++ {
++ /* Retrieve its result. */
++ FILE *fp = fdopen (fd[0], "r");
++ if (fp == NULL)
++ error (EXIT_FAILURE, errno, _("fdopen() failed"));
++
++ char *line = NULL;
++ size_t linesize = 0;
++ size_t linelen = getline (&line, &linesize, fp);
++ if (linelen == (size_t)(-1))
++ {
++ fclose (fp);
++ wait_subprocess (child, "git", true, true, true, false, NULL);
++ git_present = false;
++ }
++ else
++ {
++ if (linelen > 0 && line[linelen - 1] == '\n')
++ line[linelen - 1] = '\0';
++
++ /* Read until EOF (otherwise the child process may get a SIGPIPE
++ signal). */
++ while (getc (fp) != EOF)
++ ;
++
++ fclose (fp);
++
++ /* Remove zombie process from process list, and retrieve exit
++ status. */
++ int exitstatus =
++ wait_subprocess (child, "git", true, true, true, false, NULL);
++ if (exitstatus != 0)
++ {
++ free (line);
++ git_present = false;
++ }
++ else
++ {
++ /* The version starts at the first digit in the line. */
++ const char *p = line;
++ for (; *p != '0'; p++)
++ if (*p >= '0' && *p <= '9')
++ break;
++ git_version = p;
++ git_present = true;
++ }
++ }
++ }
+ git_tested = true;
+ }
+
+@@ -660,7 +712,21 @@ max_vc_mtime (struct timespec *max_of_mt
+ argv[i++] = "git";
+ argv[i++] = "diff";
+ argv[i++] = "--name-only";
+- argv[i++] = "--no-relative";
++ /* With git versions >= 2.28, we pass option --no-relative,
++ in order to neutralize any possible customization of the
++ "diff.relative" property. With git versions < 2.28, this
++ is not needed, and the option --no-relative does not
++ exist. */
++ if (!(git_version[0] <= '1'
++ || (git_version[0] == '2' && git_version[1] == '.'
++ && ((git_version[2] >= '0' && git_version[2] <= '9'
++ && !(git_version[3] >= '0' && git_version[3] <= '9'))
++ || (((git_version[2] == '1'
++ && git_version[3] >= '0' && git_version[3] <= '9')
++ || (git_version[2] == '2'
++ && git_version[3] >= '0' && git_version[3] <= '7'))
++ && !(git_version[4] >= '0' && git_version[4] <= '9'))))))
++ argv[i++] = "--no-relative";
+ argv[i++] = "-z";
+ argv[i++] = "HEAD";
+ argv[i++] = "--";
diff --git a/tools/gnulib/patches/900-str_startswith-module.patch b/tools/gnulib/patches/900-str_startswith-module.patch
new file mode 100644
index 0000000000..c9af62710a
--- /dev/null
+++ b/tools/gnulib/patches/900-str_startswith-module.patch
@@ -0,0 +1,117 @@
+From 24010120fab36721caaf92be076655571e44da07 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Fri, 3 Jan 2025 09:26:14 +0100
+Subject: [PATCH] str_startswith: New module.
+
+* lib/string.in.h (str_startswith): New declaration.
+* lib/str_startswith.c: New file.
+* m4/string_h.m4 (gl_STRING_H_REQUIRE_DEFAULTS): Initialize
+GNULIB_STR_STARTSWITH.
+* modules/string-h (Makefile.am): Substitute GNULIB_STR_STARTSWITH.
+* modules/str_startswith: New file.
+---
+ ChangeLog | 10 ++++++++++
+ lib/str_startswith.c | 29 +++++++++++++++++++++++++++++
+ lib/string.in.h | 8 ++++++++
+ m4/string_h.m4 | 3 ++-
+ modules/str_startswith | 23 +++++++++++++++++++++++
+ modules/string-h | 1 +
+ 6 files changed, 73 insertions(+), 1 deletion(-)
+ create mode 100644 lib/str_startswith.c
+ create mode 100644 modules/str_startswith
+
+--- /dev/null
++++ b/lib/str_startswith.c
+@@ -0,0 +1,29 @@
++/* str_startswith function.
++ Copyright (C) 2025 Free Software Foundation, Inc.
++
++ This file is free software: you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation, either version 3 of the
++ License, or (at your option) any later version.
++
++ This file 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 Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see <https://www.gnu.org/licenses/>. */
++
++/* Written by Bruno Haible <bruno@clisp.org>, 2025. */
++
++#include "config.h"
++
++/* Specification. */
++#include <string.h>
++
++
++int
++str_startswith (const char *string, const char *prefix)
++{
++ return strncmp (string, prefix, strlen (prefix)) == 0;
++}
+--- a/lib/string.in.h
++++ b/lib/string.in.h
+@@ -1079,6 +1079,14 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is
+ /* The following functions are not specified by POSIX. They are gnulib
+ extensions. */
+
++#if @GNULIB_STR_STARTSWITH@
++/* Returns true if STRING starts with PREFIX.
++ Returns false otherwise. */
++_GL_EXTERN_C int str_startswith (const char *string, const char *prefix)
++ _GL_ATTRIBUTE_PURE
++ _GL_ARG_NONNULL ((1, 2));
++#endif
++
+ #if @GNULIB_MBSLEN@
+ /* Return the number of multibyte characters in the character string STRING.
+ This considers multibyte characters, unlike strlen, which counts bytes. */
+--- a/m4/string_h.m4
++++ b/m4/string_h.m4
+@@ -70,6 +70,7 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS],
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSTR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R])
++ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_STARTSWITH])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR])
+--- /dev/null
++++ b/modules/str_startswith
+@@ -0,0 +1,23 @@
++Description:
++str_startswith() function: test whether a string starts with a given prefix.
++
++Files:
++lib/str_startswith.c
++
++Depends-on:
++string-h
++
++configure.ac:
++gl_STRING_MODULE_INDICATOR([str_startswith])
++
++Makefile.am:
++lib_SOURCES += str_startswith.c
++
++Include:
++<string.h>
++
++License:
++LGPLv2+
++
++Maintainer:
++all
+--- a/modules/string-h
++++ b/modules/string-h
+@@ -69,6 +69,7 @@ string.h: string.in.h $(top_builddir)/co
+ -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \
+ -e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \
+ -e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \
++ -e 's/@''GNULIB_STR_STARTSWITH''@/$(GNULIB_STR_STARTSWITH)/g' \
+ -e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \
+ -e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \
+ -e 's/@''GNULIB_STRERRORNAME_NP''@/$(GNULIB_STRERRORNAME_NP)/g' \
diff --git a/tools/gnulib/patches/901-str_endswith-module.patch b/tools/gnulib/patches/901-str_endswith-module.patch
new file mode 100644
index 0000000000..00db5cdce0
--- /dev/null
+++ b/tools/gnulib/patches/901-str_endswith-module.patch
@@ -0,0 +1,119 @@
+From d89ac9373d9748f7601babf52c9129fcbcf0c907 Mon Sep 17 00:00:00 2001
+From: Bruno Haible <bruno@clisp.org>
+Date: Fri, 3 Jan 2025 09:54:14 +0100
+Subject: [PATCH] str_endswith: New module.
+
+* lib/string.in.h (str_endswith): New declaration.
+* lib/str_endswith.c: New file.
+* m4/string_h.m4 (gl_STRING_H_REQUIRE_DEFAULTS): Initialize
+GNULIB_STR_ENDSWITH.
+* modules/string-h (Makefile.am): Substitute GNULIB_STR_ENDSWITH.
+* modules/str_endswith: New file.
+---
+ ChangeLog | 10 ++++++++++
+ lib/str_endswith.c | 31 +++++++++++++++++++++++++++++++
+ lib/string.in.h | 8 ++++++++
+ m4/string_h.m4 | 3 ++-
+ modules/str_endswith | 23 +++++++++++++++++++++++
+ modules/string-h | 1 +
+ 6 files changed, 75 insertions(+), 1 deletion(-)
+ create mode 100644 lib/str_endswith.c
+ create mode 100644 modules/str_endswith
+
+--- /dev/null
++++ b/lib/str_endswith.c
+@@ -0,0 +1,31 @@
++/* str_endswith function.
++ Copyright (C) 2025 Free Software Foundation, Inc.
++
++ This file is free software: you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation, either version 3 of the
++ License, or (at your option) any later version.
++
++ This file 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 Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see <https://www.gnu.org/licenses/>. */
++
++/* Written by Bruno Haible <bruno@clisp.org>, 2025. */
++
++#include "config.h"
++
++/* Specification. */
++#include <string.h>
++
++
++int
++str_endswith (const char *string, const char *suffix)
++{
++ size_t len = strlen (string);
++ size_t n = strlen (suffix);
++ return len >= n && strcmp (string + len - n, suffix) == 0;
++}
+--- a/lib/string.in.h
++++ b/lib/string.in.h
+@@ -1087,6 +1087,14 @@ _GL_EXTERN_C int str_startswith (const c
+ _GL_ARG_NONNULL ((1, 2));
+ #endif
+
++#if @GNULIB_STR_ENDSWITH@
++/* Returns true if STRING ends with SUFFIX.
++ Returns false otherwise. */
++_GL_EXTERN_C int str_endswith (const char *string, const char *prefix)
++ _GL_ATTRIBUTE_PURE
++ _GL_ARG_NONNULL ((1, 2));
++#endif
++
+ #if @GNULIB_MBSLEN@
+ /* Return the number of multibyte characters in the character string STRING.
+ This considers multibyte characters, unlike strlen, which counts bytes. */
+--- a/m4/string_h.m4
++++ b/m4/string_h.m4
+@@ -71,6 +71,7 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS],
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_STARTSWITH])
++ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_ENDSWITH])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR])
+--- /dev/null
++++ b/modules/str_endswith
+@@ -0,0 +1,23 @@
++Description:
++str_endswith() function: test whether a string ends with a given suffix.
++
++Files:
++lib/str_endswith.c
++
++Depends-on:
++string-h
++
++configure.ac:
++gl_STRING_MODULE_INDICATOR([str_endswith])
++
++Makefile.am:
++lib_SOURCES += str_endswith.c
++
++Include:
++<string.h>
++
++License:
++LGPLv2+
++
++Maintainer:
++all
+--- a/modules/string-h
++++ b/modules/string-h
+@@ -69,6 +69,7 @@ string.h: string.in.h $(top_builddir)/co
+ -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \
+ -e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \
+ -e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \
++ -e 's/@''GNULIB_STR_ENDSWITH''@/$(GNULIB_STR_ENDSWITH)/g' \
+ -e 's/@''GNULIB_STR_STARTSWITH''@/$(GNULIB_STR_STARTSWITH)/g' \
+ -e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \
+ -e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \
diff --git a/tools/include/byteswap.h b/tools/include/byteswap.h
index 015f09740a..a1b9677b98 100644
--- a/tools/include/byteswap.h
+++ b/tools/include/byteswap.h
@@ -1,4 +1,4 @@
-#if defined(__linux__) || defined(__CYGWIN__)
+#if defined(__linux__) || defined(__CYGWIN__)
#include_next <byteswap.h>
#else
#include <endian.h>
diff --git a/tools/isl/Makefile b/tools/isl/Makefile
index 1ce20fb49c..481c29634e 100644
--- a/tools/isl/Makefile
+++ b/tools/isl/Makefile
@@ -7,11 +7,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=isl
-PKG_VERSION:=0.26
+PKG_VERSION:=0.27
PKG_SOURCE_URL:=https://libisl.sourceforge.io/
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_HASH:=b10473024cbf17d7db85323121eff0e50f03de14342a03738b4d384b587ce212
+PKG_HASH:=7a1a3f04d57c7c72fee5a6148cd3b02b05db6a6dd9a58def7bdc00972a6301c3
HOST_BUILD_PARALLEL:=1
diff --git a/tools/kernel2minor/Makefile b/tools/kernel2minor/Makefile
deleted file mode 100644
index 69108f43df..0000000000
--- a/tools/kernel2minor/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Copyright (C) 2016 adron@yapic.net
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=kernel2minor
-PKG_VERSION:=0.25
-PKG_RELEASE:=1
-
-PKG_SOURCE_URL:=https://github.com/adron-s/kernel2minor.git
-PKG_MIRROR_HASH:=4e59e6e9883a17b90d09d4b6df0cbff83badad9a0e148dfa730abafce000128d
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_VERSION:=1e5a52c7941945f6d64807ebca4a5923ba5466bd
-PKG_HASH:=33ca413403a3341af0c9a8e6d9bb58f4ad080a5339e8a8729b83637d35bfaf1b
-
-include $(INCLUDE_DIR)/host-build.mk
-
-define Host/Install
- $(INSTALL_BIN) $(HOST_BUILD_DIR)/kernel2minor $(STAGING_DIR_HOST)/bin/
-endef
-
-define Host/Clean
- rm -f $(STAGING_DIR_HOST)/bin/kernel2minor
-endef
-
-$(eval $(call HostBuild))
diff --git a/tools/libdeflate/Makefile b/tools/libdeflate/Makefile
index 6bf25d134d..ba379dfad8 100644
--- a/tools/libdeflate/Makefile
+++ b/tools/libdeflate/Makefile
@@ -7,12 +7,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libdeflate
-PKG_VERSION:=1.20
-PKG_RELEASE:=2
+PKG_VERSION:=1.24
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/ebiggers/libdeflate/releases/download/v$(PKG_VERSION)
-PKG_HASH:=c52cf0239fd644d71c9e88613dd7431a5306ebee1280c5791c71ca264869250a
+PKG_HASH:=a0dda1c4b804742066db07b9510876edd09cc0ca06cdc32c5dfe1b2016a26463
include $(INCLUDE_DIR)/host-build.mk
diff --git a/tools/libdeflate/patches/0001-lib-x86-increase-AVX-VNNI-gcc-prerequisite-to-12.1.patch b/tools/libdeflate/patches/0001-lib-x86-increase-AVX-VNNI-gcc-prerequisite-to-12.1.patch
deleted file mode 100644
index ea4f4dc4c1..0000000000
--- a/tools/libdeflate/patches/0001-lib-x86-increase-AVX-VNNI-gcc-prerequisite-to-12.1.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From e522b1d09d3536ddc15459b4259150f4a53ee65a Mon Sep 17 00:00:00 2001
-From: Eric Biggers <ebiggers@google.com>
-Date: Thu, 4 Apr 2024 20:16:33 -0400
-Subject: [PATCH] lib/x86: increase AVX-VNNI gcc prerequisite to 12.1
-
-Although gcc 11.1 supports AVX-VNNI, a popular distro pairs it with a
-binutils version that does not. Require gcc 12 instead.
-
-Resolves https://github.com/ebiggers/libdeflate/issues/365
----
- lib/x86/adler32_impl.h | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
---- a/lib/x86/adler32_impl.h
-+++ b/lib/x86/adler32_impl.h
-@@ -52,8 +52,15 @@
- /*
- * AVX-VNNI implementation. This is used on CPUs that have AVX2 and AVX-VNNI
- * but don't have AVX-512, for example Intel Alder Lake.
-+ *
-+ * Unusually for a new CPU feature, gcc added support for the AVX-VNNI
-+ * intrinsics (in gcc 11.1) slightly before binutils added support for
-+ * assembling AVX-VNNI instructions (in binutils 2.36). Distros can reasonably
-+ * have gcc 11 with binutils 2.35. Because of this issue, we check for gcc 12
-+ * instead of gcc 11. (libdeflate supports direct compilation without a
-+ * configure step, so checking the binutils version is not always an option.)
- */
--#if GCC_PREREQ(11, 1) || CLANG_PREREQ(12, 0, 13000000) || MSVC_PREREQ(1930)
-+#if GCC_PREREQ(12, 1) || CLANG_PREREQ(12, 0, 13000000) || MSVC_PREREQ(1930)
- # define adler32_x86_avx2_vnni adler32_x86_avx2_vnni
- # define SUFFIX _avx2_vnni
- # define ATTRIBUTES _target_attribute("avx2,avxvnni")
diff --git a/tools/liblzo/patches/001-add-cmake-ENABLE-configurables.patch b/tools/liblzo/patches/001-add-cmake-ENABLE-configurables.patch
index 9ab27fc924..e0ba410167 100644
--- a/tools/liblzo/patches/001-add-cmake-ENABLE-configurables.patch
+++ b/tools/liblzo/patches/001-add-cmake-ENABLE-configurables.patch
@@ -1,6 +1,6 @@
---- a/CMakeLists.txt 2022-11-28 06:34:39.171209779 -0800
-+++ b/CMakeLists.txt 2022-11-28 06:33:13.368239757 -0800
-@@ -51,8 +51,11 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -51,8 +51,11 @@ endif()
project(lzo VERSION 2.10 LANGUAGES C)
# configuration options
@@ -14,7 +14,7 @@
if(NOT ENABLE_STATIC AND NOT ENABLE_SHARED)
set(ENABLE_STATIC ON)
endif()
-@@ -127,14 +130,20 @@
+@@ -127,14 +130,20 @@ macro(lzo_add_executable t)
endif()
endmacro()
# main test driver
@@ -35,7 +35,7 @@
# some boring internal test programs
if(0)
lzo_add_executable(align tests/align.c)
-@@ -144,7 +153,7 @@
+@@ -144,7 +153,7 @@ if(0)
endif()
# miniLZO
@@ -44,7 +44,7 @@
add_executable(testmini minilzo/testmini.c minilzo/minilzo.c)
target_include_directories(testmini PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include/lzo") # needed for "lzoconf.h"
endif()
-@@ -263,8 +272,10 @@
+@@ -263,8 +272,10 @@ add_test(NAME lzotest-03 COMMAND lzotest
if(DEFINED CMAKE_INSTALL_FULL_LIBDIR)
@@ -57,7 +57,7 @@
set(f include/lzo/lzo1.h include/lzo/lzo1a.h include/lzo/lzo1b.h
include/lzo/lzo1c.h include/lzo/lzo1f.h include/lzo/lzo1x.h
-@@ -285,7 +296,7 @@
+@@ -285,7 +296,7 @@ if(ENABLE_SHARED)
)
endif()
diff --git a/tools/libtool/Makefile b/tools/libtool/Makefile
index dd9afc05bd..dde4ff3130 100644
--- a/tools/libtool/Makefile
+++ b/tools/libtool/Makefile
@@ -8,13 +8,11 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=libtool
PKG_CPE_ID:=cpe:/a:gnu:libtool
-PKG_VERSION:=2.4.7
+PKG_VERSION:=2.5.4
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
-PKG_HASH:=04e96c2404ea70c590c546eba4202a4e12722c640016c12b9b2f1ce3d481e9a8
-
-HOST_BUILD_PARALLEL:=1
+PKG_HASH:=da8ebb2ce4dcf46b90098daf962cffa68f4b4f62ea60f798d0ef12929ede6adf
include $(INCLUDE_DIR)/host-build.mk
@@ -23,11 +21,16 @@ export GNULIB_SRCDIR:=$(HOST_GNULIB_SRCDIR)
HOST_CONFIGURE_VARS += \
lt_cv_sys_dlsearch_path=""
+HOST_MAKE_FLAGS += \
+ am__CONFIG_DISTCLEAN_FILES= \
+ CONFIG_STATUS_DEPENDENCIES=
+
define Host/Bootstrap
( \
cd $(HOST_BUILD_DIR); \
$(AM_TOOL_PATHS) \
./bootstrap \
+ --copy \
--force \
--skip-git \
--skip-po \
@@ -44,6 +47,7 @@ endef
define Host/Configure
$(if $(QUILT),$(call Host/Bootstrap))
$(call Host/Configure/Default)
+ $(call Host/Uninstall)
endef
define Host/Install
@@ -53,6 +57,7 @@ endef
define Host/Uninstall
-$(call Host/Compile/Default,uninstall)
+ -$(call Host/Compile/Default,maintainer-clean) # Clean bootstrap files from the release
(cd $(STAGING_DIR_HOST)/share/aclocal/ && rm -f libtool.m4 ltdl.m4 lt~obsolete.m4 ltoptions.m4 ltsugar.m4 ltversion.m4)
endef
diff --git a/tools/libtool/patches/000-relocatable.patch b/tools/libtool/patches/000-relocatable.patch
index 9c3bcb69ff..20d35718a3 100644
--- a/tools/libtool/patches/000-relocatable.patch
+++ b/tools/libtool/patches/000-relocatable.patch
@@ -40,7 +40,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
## -------------------------- ##
## Source external libraries. ##
-@@ -1903,11 +1912,21 @@ func_require_seen_libtool ()
+@@ -1934,11 +1943,21 @@ func_require_seen_libtool ()
pkgmacro_files="@pkgmacro_files@"
# Locations for important files:
@@ -69,7 +69,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
if test -n "$_lt_pkgdatadir"; then
--- a/m4/libtool.m4
+++ b/m4/libtool.m4
-@@ -933,7 +933,7 @@ m4_defun([_LT_TAG_COMPILER],
+@@ -932,7 +932,7 @@ m4_defun([_LT_TAG_COMPILER],
[AC_REQUIRE([AC_PROG_CC])dnl
_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
@@ -78,7 +78,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
-@@ -8183,9 +8183,9 @@ m4_defun([_LT_DECL_EGREP],
+@@ -8338,9 +8338,9 @@ m4_defun([_LT_DECL_EGREP],
[AC_REQUIRE([AC_PROG_EGREP])dnl
AC_REQUIRE([AC_PROG_FGREP])dnl
test -z "$GREP" && GREP=grep
@@ -91,7 +91,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
AC_SUBST([GREP])
])
-@@ -8226,9 +8226,8 @@ _LT_DECL([], [FILECMD], [1], [A file(cmd
+@@ -8381,9 +8381,8 @@ _LT_DECL([], [FILECMD], [1], [A file(cmd
# as few characters as possible. Prefer GNU sed if found.
m4_defun([_LT_DECL_SED],
[AC_PROG_SED
diff --git a/tools/libtool/patches/001-always-install-aux.patch b/tools/libtool/patches/001-always-install-aux.patch
new file mode 100644
index 0000000000..f9e0d959f9
--- /dev/null
+++ b/tools/libtool/patches/001-always-install-aux.patch
@@ -0,0 +1,11 @@
+--- a/libtoolize.in
++++ b/libtoolize.in
+@@ -1066,7 +1066,7 @@ func_install_pkgaux_files ()
+ func_ltmain_update "$file" "$pkgauxdir" "$aux_dir" pkgaux_header
+ ;;
+ *)
+- test subproject = "$ltdl_mode" || continue
++ $opt_install || test subproject = "$ltdl_mode" || continue
+ func_copy "$file" "$pkgauxdir" "$aux_dir" pkgaux_header
+ ;;
+ esac
diff --git a/tools/libtool/patches/100-libdir-fixes.patch b/tools/libtool/patches/100-libdir-fixes.patch
index 2a563901a5..c663ca38e4 100644
--- a/tools/libtool/patches/100-libdir-fixes.patch
+++ b/tools/libtool/patches/100-libdir-fixes.patch
@@ -19,7 +19,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
--- a/build-aux/ltmain.in
+++ b/build-aux/ltmain.in
-@@ -6097,8 +6097,14 @@ func_mode_link ()
+@@ -6274,8 +6274,14 @@ func_mode_link ()
absdir=$abs_ladir
libdir=$abs_ladir
else
@@ -36,16 +36,16 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
fi
test yes = "$hardcode_automatic" && avoidtemprpath=yes
else
-@@ -6496,8 +6502,6 @@ func_mode_link ()
+@@ -6682,8 +6688,6 @@ func_mode_link ()
add=$libdir/$linklib
fi
else
- # We cannot seem to hardcode it, guess we'll fake it.
-- add_dir=-L$libdir
+- add_dir=-L$lt_sysroot$libdir
# Try looking first in the location we're being installed to.
if test -n "$inst_prefix_dir"; then
case $libdir in
-@@ -6652,7 +6656,17 @@ func_mode_link ()
+@@ -6836,7 +6840,17 @@ func_mode_link ()
fi
;;
*)
diff --git a/tools/libtool/patches/110-dont-use-target-dir-for-relinking.patch b/tools/libtool/patches/110-dont-use-target-dir-for-relinking.patch
index 2d2189e766..f6e7a3c605 100644
--- a/tools/libtool/patches/110-dont-use-target-dir-for-relinking.patch
+++ b/tools/libtool/patches/110-dont-use-target-dir-for-relinking.patch
@@ -10,7 +10,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
--- a/build-aux/ltmain.in
+++ b/build-aux/ltmain.in
-@@ -6482,13 +6482,13 @@ func_mode_link ()
+@@ -6668,13 +6668,13 @@ func_mode_link ()
add_dir=
add=
# Finalize command for both is simple: just hardcode it.
@@ -22,7 +22,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
- add_dir=-L$libdir
+ add_dir=-L$lt_sysroot$libdir
- add=-l$name
- elif test yes = "$hardcode_shlibpath_var"; then
+ add="-l$name"
diff --git a/tools/libtool/patches/120-strip-unsafe-dirs-for-relinking.patch b/tools/libtool/patches/120-strip-unsafe-dirs-for-relinking.patch
index 132f1c9bd6..604acb2af6 100644
--- a/tools/libtool/patches/120-strip-unsafe-dirs-for-relinking.patch
+++ b/tools/libtool/patches/120-strip-unsafe-dirs-for-relinking.patch
@@ -13,7 +13,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
--- a/build-aux/ltmain.in
+++ b/build-aux/ltmain.in
-@@ -2400,6 +2400,9 @@ func_mode_install ()
+@@ -2540,6 +2540,9 @@ func_mode_install ()
relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
fi
diff --git a/tools/libtool/patches/130-trailingslash.patch b/tools/libtool/patches/130-trailingslash.patch
deleted file mode 100644
index 78fdf0a410..0000000000
--- a/tools/libtool/patches/130-trailingslash.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 1b45c3c0d6682be7f4876b620780ee246a5acbaa Mon Sep 17 00:00:00 2001
-From: Eneas U de Queiroz <cotequeiroz@gmail.com>
-Date: Tue, 20 Jul 2021 16:56:16 -0300
-Subject: openwrt: remove trailing slash in install destdir
-
-A command like /bin/sh ../../i586-poky-linux-libtool --mode=install /usr/bin/install -c gck-roots-store-standalone.la '/media/data1/builds/poky1/tmp/work/core2-poky-linux/gnome-keyring-2.26.1-r1/image/usr/lib/gnome-keyring/standalone/' fails (e.g. gnome-keyring or pulseaudio)
-
-This is because libdir has a trailing slash which breaks the comparision.
-
-RP 2/1/10
-
-Merged a patch received from Gary Thomas <gary@mlbassoc.com>
-
-Date: 2010/07/12
-Nitin A Kamble <nitin.a.kamble@intel.com>
-
-Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
-
---- a/build-aux/ltmain.in
-+++ b/build-aux/ltmain.in
-@@ -2381,8 +2381,15 @@ func_mode_install ()
- func_append dir "$objdir"
-
- if test -n "$relink_command"; then
-+ # Strip any trailing slash from the destination.
-+ func_stripname '' '/' "$libdir"
-+ destlibdir=$func_stripname_result
-+
-+ func_stripname '' '/' "$destdir"
-+ s_destdir=$func_stripname_result
-+
- # Determine the prefix the user has applied to our future dir.
-- inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
-+ inst_prefix_dir=`$ECHO "X$s_destdir" | $Xsed -e "s%$destlibdir\$%%"`
-
- # Don't allow the user to place us outside of our expected
- # location b/c this prevents finding dependent libraries that
diff --git a/tools/libtool/patches/140-don-t-quote-SHELL-in-Makefile.am.patch b/tools/libtool/patches/140-don-t-quote-SHELL-in-Makefile.am.patch
index 3422961385..0dd0af0a5b 100644
--- a/tools/libtool/patches/140-don-t-quote-SHELL-in-Makefile.am.patch
+++ b/tools/libtool/patches/140-don-t-quote-SHELL-in-Makefile.am.patch
@@ -9,7 +9,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
--- a/Makefile.am
+++ b/Makefile.am
-@@ -46,7 +46,7 @@ EXTRA_LTLIBRARIES =
+@@ -43,7 +43,7 @@ EXTRA_LTLIBRARIES =
# Using 'cd' in backquotes may print the directory name, use this instead:
lt__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
@@ -18,7 +18,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
rebuild = rebuild=:; revision=`$(lt__cd) $(srcdir) && $(git_version_gen) | $(SED) 's|-.*$$||'`
-@@ -306,7 +306,7 @@ libtool: $(ltmain_sh) $(config_status) $
+@@ -303,7 +303,7 @@ libtool: $(ltmain_sh) $(config_status) $
if test 0 = '$(AM_DEFAULT_VERBOSITY)' && test 1 != '$(V)'; \
then echo " GEN " $@; \
else echo '$(SHELL) $(top_builddir)/config.status "$@"'; fi; \
@@ -27,7 +27,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
fi
-@@ -789,13 +789,13 @@ testsuite_deps_uninstalled = $(testsuite
+@@ -790,13 +790,13 @@ testsuite_deps_uninstalled = $(testsuite
# Hook the test suite into the check rule
check-local: $(testsuite_deps_uninstalled)
$(AM_V_at)$(CD_TESTDIR); \
@@ -43,7 +43,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
$(TESTS_ENVIRONMENT) $(INSTALLCHECK_ENVIRONMENT) $(TESTSUITEFLAGS) \
AUTOTEST_PATH='$(exec_prefix)/bin'
-@@ -807,7 +807,7 @@ check-noninteractive-old:
+@@ -808,7 +808,7 @@ check-noninteractive-old:
.PHONY: check-noninteractive-new
check-noninteractive-new: $(testsuite_deps_uninstalled)
$(AM_V_at)$(CD_TESTDIR); \
@@ -52,7 +52,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
$(TESTS_ENVIRONMENT) $(BUILDCHECK_ENVIRONMENT) \
-k '!interactive' INNER_TESTSUITEFLAGS=',!interactive' \
$(TESTSUITEFLAGS)
-@@ -816,7 +816,7 @@ check-noninteractive-new: $(testsuite_de
+@@ -817,7 +817,7 @@ check-noninteractive-new: $(testsuite_de
.PHONY: check-interactive
check-interactive: $(testsuite_deps_uninstalled)
$(AM_V_at)$(CD_TESTDIR); \
@@ -61,7 +61,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
$(TESTS_ENVIRONMENT) $(BUILDCHECK_ENVIRONMENT) \
-k interactive -k recursive INNER_TESTSUITEFLAGS=',interactive' \
$(TESTSUITEFLAGS)
-@@ -828,7 +828,7 @@ check-noninteractive: check-noninteracti
+@@ -829,7 +829,7 @@ check-noninteractive: check-noninteracti
clean-local:
-$(CD_TESTDIR); \
test -f "$$abs_srcdir/$(TESTSUITE)" && \
diff --git a/tools/libtool/patches/200-openwrt-branding.patch b/tools/libtool/patches/200-openwrt-branding.patch
index 5876f8bfac..6483768156 100644
--- a/tools/libtool/patches/200-openwrt-branding.patch
+++ b/tools/libtool/patches/200-openwrt-branding.patch
@@ -12,7 +12,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
--- a/build-aux/ltmain.in
+++ b/build-aux/ltmain.in
-@@ -82,7 +82,7 @@ func_echo ()
+@@ -105,7 +105,7 @@ func_echo ()
IFS=$nl
for _G_line in $_G_message; do
IFS=$func_echo_IFS
diff --git a/tools/llvm-bpf/Makefile b/tools/llvm-bpf/Makefile
index bb3179016c..a4e8b2dbaa 100644
--- a/tools/llvm-bpf/Makefile
+++ b/tools/llvm-bpf/Makefile
@@ -7,12 +7,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=llvm-project
-PKG_VERSION:=15.0.7
-PKG_RELEASE:=1
+PKG_VERSION:=20.1.8
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).src.tar.xz
PKG_SOURCE_URL:=https://github.com/llvm/llvm-project/releases/download/llvmorg-$(PKG_VERSION)
-PKG_HASH:=8b5fcb24b4128cf04df1b0b9410ce8b1a729cb3c544e6da885d234280dedeac6
+PKG_HASH:=6898f963c8e938981e6c4a302e83ec5beb4630147c7311183cf61069af16333d
PKG_CPE_ID:=cpe:/a:llvm:llvm
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION).src
@@ -23,21 +22,38 @@ CMAKE_SOURCE_SUBDIR := llvm
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/cmake.mk
+ifneq ($(HOST_OS),Linux)
+ HOST_CFLAGS := $(filter-out -I$(STAGING_DIR_HOST)/include,$(HOST_CFLAGS))
+ HOST_CXXFLAGS := $(filter-out -I$(STAGING_DIR_HOST)/include,$(HOST_CXXFLAGS))
+endif
+
LLVM_BPF_PREFIX = llvm-bpf-$(PKG_VERSION).$(HOST_OS)-$(HOST_ARCH)
CMAKE_HOST_INSTALL_PREFIX = $(STAGING_DIR_HOST)/$(LLVM_BPF_PREFIX)
CMAKE_HOST_OPTIONS += \
- -DLLVM_ENABLE_BINDINGS=OFF \
- -DLLVM_INCLUDE_DOCS=OFF \
- -DLLVM_INCLUDE_EXAMPLES=OFF \
- -DLLVM_INCLUDE_TESTS=OFF \
- -DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_TARGETS_TO_BUILD=BPF \
- -DCLANG_BUILD_EXAMPLES=OFF \
+ -DLLVM_DEFAULT_TARGET_TRIPLE=bpf \
+ -DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_INSTALL_TOOLCHAIN_ONLY=ON \
-DLLVM_LINK_LLVM_DYLIB=ON \
-DLLVM_TOOLCHAIN_TOOLS="llvm-objcopy;llvm-objdump;llvm-readelf;llvm-strip;llvm-ar;llvm-as;llvm-dis;llvm-link;llvm-nm;llvm-ranlib;llc;opt" \
+ -DLLVM_INCLUDE_BENCHMARKS=OFF \
+ -DLLVM_INCLUDE_DOCS=OFF \
+ -DLLVM_INCLUDE_EXAMPLES=OFF \
+ -DLLVM_INCLUDE_TESTS=OFF \
+ -DLLVM_ENABLE_BINDINGS=OFF \
+ -DLLVM_ENABLE_CURL=OFF \
+ -DLLVM_ENABLE_HTTPLIB=OFF \
+ -DLLVM_ENABLE_IDE=OFF \
+ -DLLVM_ENABLE_LIBEDIT=OFF \
+ -DLLVM_ENABLE_LIBPFM=OFF \
+ -DLLVM_ENABLE_LIBXML2=OFF \
+ -DLLVM_ENABLE_OCAMLDOC=OFF \
+ -DLLVM_ENABLE_Z3_SOLVER=OFF \
+ -DLLVM_ENABLE_ZLIB=OFF \
+ -DLLVM_ENABLE_ZSTD=OFF \
+ -DLLVM_PARALLEL_LINK_JOBS=1 \
-DCMAKE_SKIP_RPATH=OFF
define Host/Install
diff --git a/tools/lz4/Makefile b/tools/lz4/Makefile
index cf1738a52f..aea66328e3 100644
--- a/tools/lz4/Makefile
+++ b/tools/lz4/Makefile
@@ -8,11 +8,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=lz4
-PKG_VERSION:=1.9.4
+PKG_VERSION:=1.10.0
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/lz4/lz4/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=0b0e3aa07c8c063ddf40b082bdf7e37a1562bda40a0ff5272957f3e987e0e54b
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/lz4/lz4.git
+PKG_SOURCE_VERSION:=ebb370ca83af193212df4dcbadcc5d87bc0de2f0
+PKG_MIRROR_HASH:=b168683fbeee4182f6f64bc216ad23f3b94edefbca9b8792dcd99ecd0a49f20f
PKG_LICENSE:=BSD-2-Clause
PKG_LICENSE_FILES:=LICENSE lib/LICENSE
@@ -21,7 +22,7 @@ PKG_CPE_ID:=cpe:/a:lz4_project:lz4
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/meson.mk
-MESON_HOST_BUILD_DIR:=$(HOST_BUILD_DIR)/contrib/meson/openwrt-build
+MESON_HOST_BUILD_DIR:=$(HOST_BUILD_DIR)/build/meson/openwrt-build
# Always optimize for speed
HOST_CFLAGS := $(filter-out -O%,$(HOST_CFLAGS)) -O3
diff --git a/tools/lz4/patches/001-add-make-ENABLE_DOCS-configurable.patch b/tools/lz4/patches/001-add-make-ENABLE_DOCS-configurable.patch
deleted file mode 100644
index 5d6dca33f3..0000000000
--- a/tools/lz4/patches/001-add-make-ENABLE_DOCS-configurable.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-+++ a/programs/Makefile 2022-08-15 15:45:31.000000000 -0700
---- b/programs/Makefile 2022-11-28 16:34:21.315593784 -0800
-@@ -66,6 +66,7 @@
- MD2ROFF = ronn
- MD2ROFF_FLAGS = --roff --warnings --manual="User Commands" --organization="lz4 $(LZ4_VERSION)"
-
-+ENABLE_DOCS ?= 1
-
- default: lz4-release
-
-@@ -120,6 +121,7 @@
- lz4c32 : $(SRCFILES)
- $(CC) $(FLAGS) $^ -o $@$(EXT)
-
-+ifeq ($(ENABLE_DOCS),1)
- lz4.1: lz4.1.md $(LIBVER_SRC)
- cat $< | $(MD2ROFF) $(MD2ROFF_FLAGS) | $(SED) -n '/^\.\\\".*/!p' > $@
-
-@@ -130,6 +132,7 @@
-
- preview-man: clean-man man
- man ./lz4.1
-+endif
-
- clean:
- ifeq ($(WINBASED),yes)
-@@ -172,16 +175,19 @@
-
- install: lz4
- @echo Installing binaries in $(DESTDIR)$(bindir)
-- $(INSTALL_DIR) $(DESTDIR)$(bindir)/ $(DESTDIR)$(man1dir)/
-+ $(INSTALL_DIR) $(DESTDIR)$(bindir)/
- $(INSTALL_PROGRAM) lz4$(EXT) $(DESTDIR)$(bindir)/lz4$(EXT)
- $(LN_SF) lz4$(EXT) $(DESTDIR)$(bindir)/lz4c$(EXT)
- $(LN_SF) lz4$(EXT) $(DESTDIR)$(bindir)/lz4cat$(EXT)
- $(LN_SF) lz4$(EXT) $(DESTDIR)$(bindir)/unlz4$(EXT)
-+ifeq ($(ENABLE_DOCS),1)
- @echo Installing man pages in $(DESTDIR)$(man1dir)
-+ $(INSTALL_DIR) $(DESTDIR)$(man1dir)/
- $(INSTALL_DATA) lz4.1 $(DESTDIR)$(man1dir)/lz4.1
- $(LN_SF) lz4.1 $(DESTDIR)$(man1dir)/lz4c.1
- $(LN_SF) lz4.1 $(DESTDIR)$(man1dir)/lz4cat.1
- $(LN_SF) lz4.1 $(DESTDIR)$(man1dir)/unlz4.1
-+endif
- @echo lz4 installation completed
-
- uninstall:
-@@ -189,10 +195,12 @@
- $(RM) $(DESTDIR)$(bindir)/unlz4$(EXT)
- $(RM) $(DESTDIR)$(bindir)/lz4$(EXT)
- $(RM) $(DESTDIR)$(bindir)/lz4c$(EXT)
-+ifeq ($(ENABLE_DOCS),1)
- $(RM) $(DESTDIR)$(man1dir)/lz4.1
- $(RM) $(DESTDIR)$(man1dir)/lz4c.1
- $(RM) $(DESTDIR)$(man1dir)/lz4cat.1
- $(RM) $(DESTDIR)$(man1dir)/unlz4.1
-+endif
- @echo lz4 programs successfully uninstalled
-
- endif
diff --git a/tools/lz4/patches/002-makefile-install-links-from-same-dir.patch b/tools/lz4/patches/002-makefile-install-links-from-same-dir.patch
deleted file mode 100644
index 159dc67f1a..0000000000
--- a/tools/lz4/patches/002-makefile-install-links-from-same-dir.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-diff -ur a/lib/Makefile b/lib/Makefile
---- a/lib/Makefile 2022-12-04 23:49:06.336839263 -0800
-+++ b/lib/Makefile 2022-12-05 00:00:59.172307488 -0800
-@@ -195,8 +195,8 @@
- $(INSTALL_PROGRAM) dll/$(LIBLZ4_EXP) $(DESTDIR)$(libdir)
- else
- $(INSTALL_PROGRAM) liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(libdir)
-- $(LN_SF) liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT_MAJOR)
-- $(LN_SF) liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT)
-+ (cd $(DESTDIR)$(libdir) && $(LN_SF) liblz4.$(SHARED_EXT_VER) liblz4.$(SHARED_EXT_MAJOR))
-+ (cd $(DESTDIR)$(libdir) && $(LN_SF) liblz4.$(SHARED_EXT_MAJOR) liblz4.$(SHARED_EXT))
- endif
- endif
- @echo Installing headers in $(DESTDIR)$(includedir)
-diff -ur a/Makefile b/Makefile
---- a/Makefile 2022-12-04 23:49:06.336839263 -0800
-+++ b/Makefile 2022-12-04 23:42:09.693836654 -0800
-@@ -77,12 +77,12 @@
-
- .PHONY: clean
- clean:
-- $(MAKE) -C $(LZ4DIR) $@ > $(VOID)
-- $(MAKE) -C $(PRGDIR) $@ > $(VOID)
-- $(MAKE) -C $(TESTDIR) $@ > $(VOID)
-- $(MAKE) -C $(EXDIR) $@ > $(VOID)
-- $(MAKE) -C $(FUZZDIR) $@ > $(VOID)
-- $(MAKE) -C contrib/gen_manual $@ > $(VOID)
-+ $(MAKE) -C $(LZ4DIR) $@
-+ $(MAKE) -C $(PRGDIR) $@
-+ $(MAKE) -C $(TESTDIR) $@
-+ $(MAKE) -C $(EXDIR) $@
-+ $(MAKE) -C $(FUZZDIR) $@
-+ $(MAKE) -C contrib/gen_manual $@
- $(RM) lz4$(EXT)
- $(RM) -r $(CMAKE_BUILD_DIR)
- @echo Cleaning completed
-diff -ur a/programs/Makefile b/programs/Makefile
---- a/programs/Makefile 2022-12-04 23:49:06.336839263 -0800
-+++ b/programs/Makefile 2022-12-04 23:42:30.849582910 -0800
-@@ -138,7 +138,7 @@
- ifeq ($(WINBASED),yes)
- $(RM) *.rc
- endif
-- $(MAKE) -C $(LZ4DIR) $@ > $(VOID)
-+ $(MAKE) -C $(LZ4DIR) $@
- $(RM) core *.o *.test tmp* \
- lz4$(EXT) lz4c$(EXT) lz4c32$(EXT) lz4-wlib$(EXT) \
- unlz4$(EXT) lz4cat$(EXT)
-@@ -177,16 +177,16 @@
- @echo Installing binaries in $(DESTDIR)$(bindir)
- $(INSTALL_DIR) $(DESTDIR)$(bindir)/
- $(INSTALL_PROGRAM) lz4$(EXT) $(DESTDIR)$(bindir)/lz4$(EXT)
-- $(LN_SF) lz4$(EXT) $(DESTDIR)$(bindir)/lz4c$(EXT)
-- $(LN_SF) lz4$(EXT) $(DESTDIR)$(bindir)/lz4cat$(EXT)
-- $(LN_SF) lz4$(EXT) $(DESTDIR)$(bindir)/unlz4$(EXT)
-+ (cd $(DESTDIR)$(bindir) && $(LN_SF) lz4$(EXT) lz4c$(EXT))
-+ (cd $(DESTDIR)$(bindir) && $(LN_SF) lz4$(EXT) lz4cat$(EXT))
-+ (cd $(DESTDIR)$(bindir) && $(LN_SF) lz4$(EXT) unlz4$(EXT))
- ifeq ($(ENABLE_DOCS),1)
- @echo Installing man pages in $(DESTDIR)$(man1dir)
- $(INSTALL_DIR) $(DESTDIR)$(man1dir)/
- $(INSTALL_DATA) lz4.1 $(DESTDIR)$(man1dir)/lz4.1
-- $(LN_SF) lz4.1 $(DESTDIR)$(man1dir)/lz4c.1
-- $(LN_SF) lz4.1 $(DESTDIR)$(man1dir)/lz4cat.1
-- $(LN_SF) lz4.1 $(DESTDIR)$(man1dir)/unlz4.1
-+ (cd $(DESTDIR)$(man1dir) && $(LN_SF) lz4.1 lz4c.1)
-+ (cd $(DESTDIR)$(man1dir) && $(LN_SF) lz4.1 lz4cat.1)
-+ (cd $(DESTDIR)$(man1dir) && $(LN_SF) lz4.1 unlz4.1)
- endif
- @echo lz4 installation completed
-
diff --git a/tools/lzma/patches/001-large_files.patch b/tools/lzma/patches/001-large_files.patch
index b95fe9e90f..65603f4976 100644
--- a/tools/lzma/patches/001-large_files.patch
+++ b/tools/lzma/patches/001-large_files.patch
@@ -1,8 +1,6 @@
-Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
-===================================================================
---- lzma-4.65.orig/CPP/7zip/Compress/LZMA_Alone/makefile.gcc 2009-05-15 23:33:51.000000000 +0200
-+++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc 2009-06-01 22:00:54.000000000 +0200
-@@ -3,7 +3,7 @@
+--- a/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
++++ b/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
+@@ -3,7 +3,7 @@ CXX = g++ -O2 -Wall
CXX_C = gcc -O2 -Wall
LIB = -lm
RM = rm -f
diff --git a/tools/lzma/patches/002-lzmp.patch b/tools/lzma/patches/002-lzmp.patch
index 72d881cdb2..f1d45f45ff 100644
--- a/tools/lzma/patches/002-lzmp.patch
+++ b/tools/lzma/patches/002-lzmp.patch
@@ -1,7 +1,5 @@
-Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzmp.cpp
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzmp.cpp 2009-06-01 22:01:10.000000000 +0200
+--- /dev/null
++++ b/CPP/7zip/Compress/LZMA_Alone/lzmp.cpp
@@ -0,0 +1,895 @@
+/*
+ * LZMA command line tool similar to gzip to encode and decode LZMA files.
@@ -898,10 +896,8 @@ Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzmp.cpp
+ return STATUS_OK;
+}
+
-Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/Exception.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/Exception.h 2009-06-01 22:01:10.000000000 +0200
+--- /dev/null
++++ b/CPP/7zip/Compress/LZMA_Alone/Exception.h
@@ -0,0 +1,45 @@
+/* A couple of exceptions for lzmp.
+ *
@@ -948,10 +944,8 @@ Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/Exception.h
+
+#endif
+
-Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
-===================================================================
---- lzma-4.65.orig/CPP/7zip/Compress/LZMA_Alone/makefile.gcc 2009-06-01 22:00:54.000000000 +0200
-+++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc 2009-06-01 22:06:13.000000000 +0200
+--- a/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
++++ b/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
@@ -1,9 +1,10 @@
-PROG = lzma
+PROG = lzma_alone
@@ -965,7 +959,7 @@ Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
ifdef SystemDrive
IS_MINGW = 1
-@@ -45,12 +46,35 @@
+@@ -45,12 +46,35 @@ OBJS = \
Lzma86Dec.o \
Lzma86Enc.o \
@@ -1002,17 +996,15 @@ Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
LzmaAlone.o: LzmaAlone.cpp
$(CXX) $(CFLAGS) LzmaAlone.cpp
-@@ -131,5 +153,5 @@
+@@ -131,5 +155,5 @@ Lzma86Enc.o: ../../../../C/LzmaUtil/Lzma
$(CXX_C) $(CFLAGS) ../../../../C/LzmaUtil/Lzma86Enc.c
clean:
- -$(RM) $(PROG) $(OBJS)
+ -$(RM) $(PROG) $(PROG2) $(OBJS)
-Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzma_version.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzma_version.h 2009-06-01 22:01:10.000000000 +0200
+--- /dev/null
++++ b/CPP/7zip/Compress/LZMA_Alone/lzma_version.h
@@ -0,0 +1,31 @@
+#ifndef LZMA_VERSION_H
+#define LZMA_VERSION_H
@@ -1045,11 +1037,9 @@ Index: lzma-4.65/CPP/7zip/Compress/LZMA_Alone/lzma_version.h
+ "named COPYING.\n";
+
+#endif /* ifndef LZMA_VERSION_H */
-Index: lzma-4.65/CPP/Common/C_FileIO.h
-===================================================================
---- lzma-4.65.orig/CPP/Common/C_FileIO.h 2009-05-15 23:33:51.000000000 +0200
-+++ lzma-4.65/CPP/Common/C_FileIO.h 2009-06-01 22:06:56.000000000 +0200
-@@ -24,6 +24,7 @@
+--- a/CPP/Common/C_FileIO.h
++++ b/CPP/Common/C_FileIO.h
+@@ -24,6 +24,7 @@ public:
bool Close();
bool GetLength(UInt64 &length) const;
off_t Seek(off_t distanceToMove, int moveMethod) const;
diff --git a/tools/lzma/patches/003-compile_fixes.patch b/tools/lzma/patches/003-compile_fixes.patch
index 49ae66b9c4..06f7a54aef 100644
--- a/tools/lzma/patches/003-compile_fixes.patch
+++ b/tools/lzma/patches/003-compile_fixes.patch
@@ -1,7 +1,6 @@
-diff -urN lzma-4.65/CPP/7zip/Common/FileStreams.h lzma-4.65.new/CPP/7zip/Common/FileStreams.h
---- lzma-4.65/CPP/7zip/Common/FileStreams.h 2009-05-15 23:33:51.000000000 +0200
-+++ lzma-4.65.new/CPP/7zip/Common/FileStreams.h 2009-06-01 22:30:01.000000000 +0200
-@@ -72,6 +72,7 @@
+--- a/CPP/7zip/Common/FileStreams.h
++++ b/CPP/7zip/Common/FileStreams.h
+@@ -72,6 +72,7 @@ class COutFileStream:
public IOutStream,
public CMyUnknownImp
{
@@ -9,10 +8,9 @@ diff -urN lzma-4.65/CPP/7zip/Common/FileStreams.h lzma-4.65.new/CPP/7zip/Common/
#ifdef USE_WIN_FILE
NWindows::NFile::NIO::COutFile File;
#else
-diff -urN lzma-4.65/CPP/Common/MyWindows.h lzma-4.65.new/CPP/Common/MyWindows.h
---- lzma-4.65/CPP/Common/MyWindows.h 2009-05-15 23:33:51.000000000 +0200
-+++ lzma-4.65.new/CPP/Common/MyWindows.h 2009-06-01 22:29:26.000000000 +0200
-@@ -101,8 +101,11 @@
+--- a/CPP/Common/MyWindows.h
++++ b/CPP/Common/MyWindows.h
+@@ -101,8 +101,11 @@ typedef LONG SCODE;
#ifdef __cplusplus
diff --git a/tools/lzop/patches/001-add-cmake-ENABLE_DOCS-configurable.patch b/tools/lzop/patches/001-add-cmake-ENABLE_DOCS-configurable.patch
index 01ebd33a39..27af782c1c 100644
--- a/tools/lzop/patches/001-add-cmake-ENABLE_DOCS-configurable.patch
+++ b/tools/lzop/patches/001-add-cmake-ENABLE_DOCS-configurable.patch
@@ -1,6 +1,6 @@
---- a/CMakeLists.txt 2017-08-10 04:19:45.000000000 -0700
-+++ b/CMakeLists.txt 2022-11-28 17:21:03.453548350 -0800
-@@ -50,6 +50,9 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -50,6 +50,9 @@ endif()
project(lzop VERSION 1.04 LANGUAGES C)
@@ -10,7 +10,7 @@
# install directories
if(NOT CMAKE_INSTALL_PREFIX)
message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined.")
-@@ -186,9 +189,11 @@
+@@ -186,9 +189,11 @@ if(DEFINED CMAKE_INSTALL_FULL_LIBDIR)
install(TARGETS lzop DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
diff --git a/tools/lzop/patches/002-bump-minimum-cmake-version.patch b/tools/lzop/patches/002-bump-minimum-cmake-version.patch
new file mode 100644
index 0000000000..62a389e9e0
--- /dev/null
+++ b/tools/lzop/patches/002-bump-minimum-cmake-version.patch
@@ -0,0 +1,11 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -8,7 +8,7 @@
+ # All Rights Reserved.
+ #
+
+-cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
++cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+ #
+ # simple usage example (Unix):
diff --git a/tools/m4/Makefile b/tools/m4/Makefile
index ee369f3cbb..eaa46ec4f8 100644
--- a/tools/m4/Makefile
+++ b/tools/m4/Makefile
@@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=m4
PKG_CPE_ID:=cpe:/a:gnu:m4
-PKG_VERSION:=1.4.19
+PKG_VERSION:=1.4.20
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
-PKG_HASH:=3be4a26d825ffdfda52a56fc43246456989a3630093cced3fbddf4771ee58a70
+PKG_HASH:=6ac4fc31ce440debe63987c2ebbf9d7b6634e67a7c3279257dc7361de8bdb3ef
HOST_BUILD_PARALLEL:=1
diff --git a/tools/make-ext4fs/Makefile b/tools/make-ext4fs/Makefile
index b5616b1bc7..631660b044 100644
--- a/tools/make-ext4fs/Makefile
+++ b/tools/make-ext4fs/Makefile
@@ -11,9 +11,9 @@ PKG_NAME:=make-ext4fs
PKG_SOURCE_URL=$(PROJECT_GIT)/project/make_ext4fs.git
PKG_SOURCE_PROTO:=git
-PKG_SOURCE_DATE:=2020-01-05
-PKG_SOURCE_VERSION:=5c201be7d72aff735da27e17c29852e0cefe3e52
-PKG_MIRROR_HASH:=ec8304dc06f94338e14e608a807f48e10d0987bdac4d90f235650b46994dfbd7
+PKG_SOURCE_DATE:=2025-05-02
+PKG_SOURCE_VERSION:=13767a96fcdffd59fef16f1b86919f63b6dee45a
+PKG_MIRROR_HASH:=4fc8c5c2a550a3978648411d4bff83730c580b6e54194826461830299b21b680
include $(INCLUDE_DIR)/host-build.mk
diff --git a/tools/meson/Makefile b/tools/meson/Makefile
index 96974faafe..6593f41f53 100644
--- a/tools/meson/Makefile
+++ b/tools/meson/Makefile
@@ -1,11 +1,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=meson
-PKG_VERSION:=1.3.2
+PKG_VERSION:=1.6.1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/mesonbuild/meson/releases/download/$(PKG_VERSION)
-PKG_HASH:=492eb450c8b073024276f916f5adbb3c4bb7e90e9e6ec124efda064f3d9b5baa
+PKG_HASH:=1eca49eb6c26d58bbee67fd3337d8ef557c0804e30a6d16bfdf269db997464de
PKG_MAINTAINER:=Andre Heider <a.heider@gmail.com>
PKG_LICENSE:=Apache-2.0
diff --git a/tools/missing-macros/Makefile b/tools/missing-macros/Makefile
index edbcb84302..15a1cc9b97 100644
--- a/tools/missing-macros/Makefile
+++ b/tools/missing-macros/Makefile
@@ -20,9 +20,9 @@ endef
define Host/Install
$(INSTALL_DIR) $(STAGING_DIR_HOST)/share/aclocal
- $(INSTALL_DATA) ./src/m4/*.m4 $(STAGING_DIR_HOST)/share/aclocal/
+ $(INSTALL_DATA) $(HOST_BUILD_DIR)/m4/*.m4 $(STAGING_DIR_HOST)/share/aclocal/
$(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
- $(INSTALL_BIN) ./src/bin/* $(STAGING_DIR_HOST)/bin/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/bin/* $(STAGING_DIR_HOST)/bin/
$(LN) makeinfo $(STAGING_DIR_HOST)/bin/texi2any
$(LN) makeinfo $(STAGING_DIR_HOST)/bin/texi2pdf
$(LN) makeinfo $(STAGING_DIR_HOST)/bin/texi2dvi
diff --git a/tools/mkimage/Makefile b/tools/mkimage/Makefile
index ae744f9bf3..610574a7d1 100644
--- a/tools/mkimage/Makefile
+++ b/tools/mkimage/Makefile
@@ -7,14 +7,14 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mkimage
-PKG_VERSION:=2024.01
+PKG_VERSION:=2025.07
PKG_SOURCE:=u-boot-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
https://mirror.cyberbits.eu/u-boot \
https://ftp.denx.de/pub/u-boot \
ftp://ftp.denx.de/pub/u-boot
-PKG_HASH:=b99611f1ed237bf3541bdc8434b68c96a6e05967061f992443cb30aabebef5b3
+PKG_HASH:=0f933f6c5a426895bf306e93e6ac53c60870e4b54cda56d95211bec99e63bec7
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/u-boot-$(PKG_VERSION)
diff --git a/tools/mkimage/patches/030-allow-to-use-different-magic.patch b/tools/mkimage/patches/030-allow-to-use-different-magic.patch
index f2f57965f6..cdf5b16e2d 100644
--- a/tools/mkimage/patches/030-allow-to-use-different-magic.patch
+++ b/tools/mkimage/patches/030-allow-to-use-different-magic.patch
@@ -24,7 +24,7 @@ This patch makes it possible to set a custom image magic.
" -a ==> set load address to 'addr' (hex)\n"
" -e ==> set entry point to 'ep' (hex)\n"
" -n ==> set image name to 'name'\n"
-@@ -159,7 +161,7 @@ static int add_content(int type, const c
+@@ -160,7 +162,7 @@ static int add_content(int type, const c
}
static const char optstring[] =
@@ -33,7 +33,7 @@ This patch makes it possible to set a custom image magic.
static const struct option longopts[] = {
{ "load-address", required_argument, NULL, 'a' },
-@@ -302,6 +304,14 @@ static void process_args(int argc, char
+@@ -304,6 +306,14 @@ static void process_args(int argc, char
case 'l':
params.lflag = 1;
break;
diff --git a/tools/mkimage/patches/095-tools-disable-TOOLS_FIT_FULL_CHECK.patch b/tools/mkimage/patches/095-tools-disable-TOOLS_FIT_FULL_CHECK.patch
index f2e3b9b053..89dd6337b1 100644
--- a/tools/mkimage/patches/095-tools-disable-TOOLS_FIT_FULL_CHECK.patch
+++ b/tools/mkimage/patches/095-tools-disable-TOOLS_FIT_FULL_CHECK.patch
@@ -14,7 +14,7 @@ https://github.com/u-boot/u-boot/commit/3f04db891a353f4b127ed57279279f851c6b4917
--- a/tools/Kconfig
+++ b/tools/Kconfig
-@@ -31,7 +31,7 @@ config TOOLS_FIT
+@@ -46,7 +46,7 @@ config TOOLS_FIT
Enable FIT support in the tools builds.
config TOOLS_FIT_FULL_CHECK
diff --git a/tools/mold/Makefile b/tools/mold/Makefile
index b2a3231e67..8c3e33f38f 100644
--- a/tools/mold/Makefile
+++ b/tools/mold/Makefile
@@ -3,19 +3,19 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mold
-PKG_VERSION:=2.30.0
+PKG_VERSION:=2.40.4
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL_FILE:=v$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/rui314/mold/archive/refs/tags
-PKG_HASH:=6e5178ccafe828fdb4ba0dd841d083ff6004d3cb41e56485143eb64c716345fd
+PKG_HASH:=69414c702ec1084e1fa8ca16da24f167f549e5e11e9ecd5d70a8dcda6f08c249
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/cmake.mk
CMAKE_HOST_OPTIONS += \
-DMOLD_LTO=ON \
- -DMOLD_MOSTLY_STATIC=ON \
-DMOLD_USE_SYSTEM_MIMALLOC=OFF \
-DMOLD_USE_SYSTEM_TBB=OFF
diff --git a/tools/mpfr/Makefile b/tools/mpfr/Makefile
index bfbbf399d2..9e9a0ae879 100644
--- a/tools/mpfr/Makefile
+++ b/tools/mpfr/Makefile
@@ -7,12 +7,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mpfr
-PKG_VERSION:=4.2.1
+PKG_VERSION:=4.2.2
PKG_CPE_ID:=cpe:/a:mpfr:gnu_mpfr
PKG_SOURCE_URL:=@GNU/mpfr http://www.mpfr.org/mpfr-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_HASH:=116715552bd966c85b417c424db1bbdf639f53836eb361549d1f8d6ded5cb4c6
+PKG_HASH:=826cbb24610bd193f36fde172233fb8c009f3f5c2ad99f644d0dea2e16a20e42
HOST_BUILD_PARALLEL:=1
HOST_FIXUP:=autoreconf
diff --git a/tools/mpfr/patches/001-only_src.patch b/tools/mpfr/patches/001-only_src.patch
index bd9e38aefb..70226745a2 100644
--- a/tools/mpfr/patches/001-only_src.patch
+++ b/tools/mpfr/patches/001-only_src.patch
@@ -11,7 +11,7 @@
pkgconfig_DATA = mpfr.pc
--- a/Makefile.in
+++ b/Makefile.in
-@@ -401,7 +401,7 @@ AUTOMAKE_OPTIONS = gnu
+@@ -406,7 +406,7 @@ AUTOMAKE_OPTIONS = gnu
# libtoolize and in case some developer needs to switch back to an
# old Automake version.
ACLOCAL_AMFLAGS = -I m4
diff --git a/tools/mpfr/patches/100-freebsd-compat.patch b/tools/mpfr/patches/100-freebsd-compat.patch
index 8a7c6b098e..17e31691b7 100644
--- a/tools/mpfr/patches/100-freebsd-compat.patch
+++ b/tools/mpfr/patches/100-freebsd-compat.patch
@@ -1,6 +1,6 @@
--- a/src/vasprintf.c
+++ b/src/vasprintf.c
-@@ -72,6 +72,7 @@ https://www.gnu.org/licenses/ or write t
+@@ -71,6 +71,7 @@ If not, see <https://www.gnu.org/license
#endif /* HAVE_VA_COPY */
#ifdef HAVE_WCHAR_H
diff --git a/tools/mtd-utils/Makefile b/tools/mtd-utils/Makefile
index 59b1716072..cf7081fb5a 100644
--- a/tools/mtd-utils/Makefile
+++ b/tools/mtd-utils/Makefile
@@ -7,12 +7,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mtd-utils
-PKG_VERSION:=2.1.6
+PKG_VERSION:=2.2.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://infraroot.at/pub/mtd/
-PKG_HASH:=c1d853bc4adf83bcabd2792fc95af33bdd8643c97e8f7b3f0180af36af76f0e5
+PKG_HASH:=f7ae20b2eb79ee83441468f0b99d897024cd96ff853eea59106fb1952065c803
PKG_CPE_ID:=cpe:/a:mtd-utils_project:mtd-utils
PKG_FIXUP:=autoreconf
@@ -29,15 +29,13 @@ ifneq ($(HOST_OS),Linux)
-include fls.h
endif
-HOST_CONFIGURE_VARS+= \
- UUID_CFLAGS="-I$(STAGING_DIR_HOST)/include/e2fsprogs/uuid"
-
HOST_CONFIGURE_ARGS+= \
- --disable-tests \
+ --without-tests \
--without-crypto \
--without-xattr \
--without-zstd \
- --without-lzo
+ --without-lzo \
+ --with-lzma
HOST_MAKE_FLAGS += \
PROGRAMS="mkfs.jffs2 ubinize mkfs.ubifs"
diff --git a/tools/mtd-utils/patches/110-portability.patch b/tools/mtd-utils/patches/110-portability.patch
index e25fd82bb3..cf5f0c8d8e 100644
--- a/tools/mtd-utils/patches/110-portability.patch
+++ b/tools/mtd-utils/patches/110-portability.patch
@@ -1,9 +1,9 @@
--- a/jffsX-utils/compr_lzo.c
+++ b/jffsX-utils/compr_lzo.c
-@@ -26,7 +26,6 @@
+@@ -24,7 +24,6 @@
+ #include <stdint.h>
+ #include <stdio.h>
#include <string.h>
-
- #ifndef WITHOUT_LZO
-#include <asm/types.h>
#include <linux/jffs2.h>
#include <lzo/lzo1x.h>
@@ -18,8 +18,8 @@
#include <linux/jffs2.h>
#include "common.h"
#include "compr.h"
---- a/jffsX-utils/rbtree.h
-+++ b/jffsX-utils/rbtree.h
+--- a/include/rbtree.h
++++ b/include/rbtree.h
@@ -94,8 +94,7 @@ static inline struct page * rb_insert_pa
#ifndef _LINUX_RBTREE_H
#define _LINUX_RBTREE_H
@@ -70,7 +70,7 @@
#include <sys/types.h>
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
-@@ -1542,6 +1542,7 @@ static int add_inode(struct stat *st, in
+@@ -1568,6 +1568,7 @@ static int add_inode(struct stat *st, in
if (c->default_compr != UBIFS_COMPR_NONE)
use_flags |= UBIFS_COMPR_FL;
@@ -78,7 +78,7 @@
if (flags & FS_COMPR_FL)
use_flags |= UBIFS_COMPR_FL;
if (flags & FS_SYNC_FL)
-@@ -1554,6 +1555,7 @@ static int add_inode(struct stat *st, in
+@@ -1580,6 +1581,7 @@ static int add_inode(struct stat *st, in
use_flags |= UBIFS_DIRSYNC_FL;
if (fctx)
use_flags |= UBIFS_CRYPT_FL;
@@ -86,7 +86,7 @@
memset(ino, 0, UBIFS_INO_NODE_SZ);
ino_key_init(&key, inum);
-@@ -1639,7 +1641,9 @@ static int add_dir_inode(const char *pat
+@@ -1665,7 +1667,9 @@ static int add_dir_inode(const char *pat
fd = dirfd(dir);
if (fd == -1)
return sys_err_msg("dirfd failed");
@@ -96,23 +96,23 @@
flags = 0;
}
-@@ -1850,6 +1854,7 @@ static int add_file(const char *path_nam
+@@ -1878,6 +1882,7 @@ static int add_file(const char *path_nam
dn->ch.node_type = UBIFS_DATA_NODE;
key_write(&key, &dn->key);
out_len = NODE_BUFFER_SIZE - UBIFS_DATA_NODE_SZ;
+#ifndef NO_NATIVE_SUPPORT
if (c->default_compr == UBIFS_COMPR_NONE &&
!c->encrypted && (flags & FS_COMPR_FL))
- #ifdef WITHOUT_LZO
-@@ -1858,6 +1863,7 @@ static int add_file(const char *path_nam
- use_compr = UBIFS_COMPR_LZO;
+ #ifdef WITH_LZO
+@@ -1888,6 +1893,7 @@ static int add_file(const char *path_nam
+ use_compr = UBIFS_COMPR_NONE;
#endif
else
+#endif
use_compr = c->default_compr;
compr_type = compress_data(buf, bytes_read, &dn->data,
&out_len, use_compr);
-@@ -1917,7 +1923,9 @@ static int add_non_dir(const char *path_
+@@ -1947,7 +1953,9 @@ static int add_non_dir(const char *path_
if (fd == -1)
return sys_err_msg("failed to open file '%s'",
path_name);
diff --git a/tools/mtd-utils/patches/130-lzma_jffs2.patch b/tools/mtd-utils/patches/130-lzma_jffs2.patch
index db683063d5..b03265a380 100644
--- a/tools/mtd-utils/patches/130-lzma_jffs2.patch
+++ b/tools/mtd-utils/patches/130-lzma_jffs2.patch
@@ -1,25 +1,9 @@
--- a/jffsX-utils/Makemodule.am
+++ b/jffsX-utils/Makemodule.am
-@@ -4,7 +4,10 @@ mkfs_jffs2_SOURCES = \
- jffsX-utils/compr_zlib.c \
- jffsX-utils/compr.h \
- jffsX-utils/rbtree.c \
-- jffsX-utils/compr_lzo.c \
-+ jffsX-utils/compr_lzma.c \
-+ jffsX-utils/lzma/LzFind.c \
-+ jffsX-utils/lzma/LzmaEnc.c \
-+ jffsX-utils/lzma/LzmaDec.c \
- jffsX-utils/compr.c \
- jffsX-utils/compr_rtime.c \
- jffsX-utils/compr.h \
-@@ -12,8 +15,13 @@ mkfs_jffs2_SOURCES = \
- jffsX-utils/summary.h \
- include/linux/jffs2.h \
- include/mtd/jffs2-user.h
-+
-+if !WITHOUT_LZO
-+mkfs_jffs2_SOURCES += jffsX-utils/compr_lzo.c
-+endif
+@@ -9,8 +9,9 @@ mkfs_jffs2_SOURCES = \
+ include/mtd/jffs2-user.h \
+ include/list.h \
+ include/rbtree.h
+
mkfs_jffs2_LDADD = libmtd.a $(ZLIB_LIBS) $(LZO_LIBS)
-mkfs_jffs2_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) $(LZO_CFLAGS)
@@ -27,36 +11,45 @@
jffs2reader_SOURCES = jffsX-utils/jffs2reader.c include/mtd/jffs2-user.h
jffs2reader_LDADD = libmtd.a $(ZLIB_LIBS) $(LZO_LIBS)
+@@ -32,6 +33,14 @@ if WITH_ZLIB
+ mkfs_jffs2_SOURCES += jffsX-utils/compr_zlib.c
+ endif
+
++if WITH_LZMA
++mkfs_jffs2_SOURCES += \
++ jffsX-utils/compr_lzma.c \
++ jffsX-utils/lzma/LzFind.c \
++ jffsX-utils/lzma/LzmaEnc.c \
++ jffsX-utils/lzma/LzmaDec.c
++endif
++
+ EXTRA_DIST += jffsX-utils/device_table.txt jffsX-utils/mkfs.jffs2.1
+
+ dist_man1_MANS += jffsX-utils/mkfs.jffs2.1
--- a/jffsX-utils/compr.c
+++ b/jffsX-utils/compr.c
-@@ -520,6 +520,9 @@ int jffs2_compressors_init(void)
- #ifdef CONFIG_JFFS2_LZO
+@@ -471,6 +471,9 @@ int jffs2_compressors_init(void)
+ #ifdef WITH_LZO
jffs2_lzo_init();
#endif
-+#ifdef CONFIG_JFFS2_LZMA
++#ifdef WITH_LZMA
+ jffs2_lzma_init();
+#endif
return 0;
}
-@@ -534,5 +537,8 @@ int jffs2_compressors_exit(void)
- #ifdef CONFIG_JFFS2_LZO
+@@ -485,5 +488,8 @@ int jffs2_compressors_exit(void)
+ #ifdef WITH_LZO
jffs2_lzo_exit();
#endif
-+#ifdef CONFIG_JFFS2_LZMA
++#ifdef WITH_LZMA
+ jffs2_lzma_exit();
+#endif
return 0;
}
--- a/jffsX-utils/compr.h
+++ b/jffsX-utils/compr.h
-@@ -18,13 +18,14 @@
-
- #define CONFIG_JFFS2_ZLIB
- #define CONFIG_JFFS2_RTIME
--#define CONFIG_JFFS2_LZO
-+#define CONFIG_JFFS2_LZMA
-
+@@ -22,8 +22,9 @@
#define JFFS2_RUBINMIPS_PRIORITY 10
#define JFFS2_DYNRUBIN_PRIORITY 20
#define JFFS2_RTIME_PRIORITY 50
@@ -68,11 +61,11 @@
#define JFFS2_COMPR_MODE_NONE 0
#define JFFS2_COMPR_MODE_PRIORITY 1
-@@ -115,5 +116,10 @@ void jffs2_rtime_exit(void);
+@@ -110,5 +111,10 @@ void jffs2_rtime_exit(void);
int jffs2_lzo_init(void);
void jffs2_lzo_exit(void);
#endif
-+#ifdef CONFIG_JFFS2_LZMA
++#ifdef WITH_LZMA
+int jffs2_lzma_init(void);
+void jffs2_lzma_exit(void);
+#endif
@@ -5036,3 +5029,45 @@
}
break;
}
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -19,6 +19,10 @@ if WITH_ZSTD
+ AM_CPPFLAGS += -DWITH_ZSTD
+ endif
+
++if WITH_LZMA
++AM_CPPFLAGS += -DWITH_LZMA
++endif
++
+ if WITH_SELINUX
+ AM_CPPFLAGS += -DWITH_SELINUX
+ endif
+--- a/configure.ac
++++ b/configure.ac
+@@ -96,6 +96,10 @@ AC_ARG_WITH([zstd],
+ [AS_HELP_STRING([--with-zstd], [Support for ZSTD compression])],
+ [], [with_zstd="check"])
+
++AC_ARG_WITH([lzma],
++ [AS_HELP_STRING([--with-lzma], [Support for LZMA compression])],
++ [], [with_lzma="check"])
++
+ AC_ARG_WITH([selinux],
+ [AS_HELP_STRING([--with-selinux],
+ [Support for selinux extended attributes])],
+@@ -269,6 +273,7 @@ fi
+ AM_CONDITIONAL([WITH_LZO], [test "x$with_lzo" = "xyes"])
+ AM_CONDITIONAL([WITH_ZLIB], [test "x$with_zlib" = "xyes"])
+ AM_CONDITIONAL([WITH_ZSTD], [test "x$with_zstd" = "xyes"])
++AM_CONDITIONAL([WITH_LZMA], [test "x$with_lzma" = "xyes"])
+ AM_CONDITIONAL([WITH_XATTR], [test "x$with_xattr" = "xyes"])
+ AM_CONDITIONAL([WITH_SELINUX], [test "x$with_selinux" = "xyes"])
+ AM_CONDITIONAL([WITH_CRYPTO], [test "x$with_crypto" = "xyes"])
+@@ -313,6 +318,7 @@ AC_MSG_RESULT([
+ lzo support: ${with_lzo}
+ zlib support: ${with_zlib}
+ zstd support: ${with_zstd}
++ lzma support: ${with_lzma}
+ xattr/acl support: ${with_xattr}
+ SELinux support: ${with_selinux}
+ fscrypt support: ${with_crypto}
diff --git a/tools/mtools/Makefile b/tools/mtools/Makefile
index b810918b98..8d4a54a698 100644
--- a/tools/mtools/Makefile
+++ b/tools/mtools/Makefile
@@ -7,11 +7,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mtools
-PKG_VERSION:=4.0.43
+PKG_VERSION:=4.0.49
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
-PKG_HASH:=541e179665dc4e272b9602f2074243591a157da89cc47064da8c5829dbd2b339
+PKG_HASH:=6fe5193583d6e7c59da75e63d7234f76c0b07caf33b103894f46f66a871ffc9f
HOST_BUILD_PARALLEL:=1
diff --git a/tools/ninja/Makefile b/tools/ninja/Makefile
index 4763e759d8..d79f3c5d5d 100644
--- a/tools/ninja/Makefile
+++ b/tools/ninja/Makefile
@@ -1,38 +1,35 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ninja
-PKG_VERSION:=1.11.1
+PKG_VERSION:=1.12.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/ninja-build/ninja/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=31747ae633213f1eda3842686f83c2aa1412e0f5691d1c14dbbcc67fe7400cea
+PKG_HASH:=821bdff48a3f683bc4bb3b6f0b5fe7b2d647cf65d52aeb63328c91a6c6df285a
include $(INCLUDE_DIR)/host-build.mk
-CONFIGURE_ARGS:=
-ifneq ($(findstring c,$(OPENWRT_VERBOSE)),)
- CONFIGURE_ARGS+=--verbose
-endif
-
define Host/Configure
+ cd $(HOST_BUILD_DIR) && \
+ $(HOST_MAKE_VARS) \
+ CXX="$(HOSTCXX_NOCACHE)" \
+ $(STAGING_DIR_HOST)/bin/$(PYTHON) configure.py \
+ $(if $(shell $(STAGING_DIR_HOST)/bin/ninja --version),,--bootstrap) \
+ --no-rebuild \
+ --verbose
+ -$(Host/Install)
endef
define Host/Compile
- cd $(HOST_BUILD_DIR) && \
- CXX="$(HOSTCXX_NOCACHE)" \
- CXXFLAGS="$(HOST_CXXFLAGS) $(HOST_CPPFLAGS)" \
- LDFLAGS="$(HOST_LDFLAGS)" \
- $(STAGING_DIR_HOST)/bin/$(PYTHON) configure.py --bootstrap $(CONFIGURE_ARGS)
+ +$(NINJA) -C $(HOST_BUILD_DIR)
endef
define Host/Install
- $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
$(INSTALL_BIN) $(HOST_BUILD_DIR)/ninja $(STAGING_DIR_HOST)/bin/
endef
define Host/Clean
- $(call Host/Clean/Default)
rm -f $(STAGING_DIR_HOST)/bin/ninja
endef
diff --git a/tools/ninja/patches/001-backport-gtest.patch b/tools/ninja/patches/001-backport-gtest.patch
new file mode 100644
index 0000000000..1440f29ef0
--- /dev/null
+++ b/tools/ninja/patches/001-backport-gtest.patch
@@ -0,0 +1,153 @@
+From afcd4a146fb82843f6ff695f89504ce4ca65ddfd Mon Sep 17 00:00:00 2001
+From: David 'Digit' Turner <digit+github@google.com>
+Date: Sun, 12 May 2024 23:45:28 +0200
+Subject: [PATCH] configure.py: Support --gtest-source-dir to build tests.
+
+Allow the Ninja build plan generated by configure.py to
+build `ninja_test` by compiling GoogleTest from source if
+the path to the library if passed through the new option
+`--gtest-source-dir` or the GTEST_SOURCE_DIR environment
+variable.
+
+For simplicity, probing for an installed version of the
+library, and linking to it, is not supported (use the
+CMake build for this).
+
+This also removes the obsolete `--gtest-dir` option.
+
++ Update README.md
+
+Fixes #2447
+---
+ README.md | 13 ++++++++
+ configure.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 95 insertions(+), 1 deletion(-)
+
+--- a/README.md
++++ b/README.md
+@@ -34,6 +34,19 @@ via CMake. For more details see
+ This will generate the `ninja` binary and a `build.ninja` file you can now use
+ to build Ninja with itself.
+
++If you have a GoogleTest source directory, you can build the tests
++by passing its path with `--gtest-source-dir=PATH` option, or the
++`GTEST_SOURCE_DIR` environment variable, e.g.:
++
++```
++./configure.py --bootstrap --gtest-source-dir=/path/to/googletest
++./ninja all # build ninja_test and other auxiliary binaries
++./ninja_test` # run the unit-test suite.
++```
++
++Use the CMake build below if you want to use a preinstalled binary
++version of the library.
++
+ ### CMake
+
+ ```
+--- a/configure.py
++++ b/configure.py
+@@ -213,7 +213,10 @@ parser.add_option('--debug', action='sto
+ parser.add_option('--profile', metavar='TYPE',
+ choices=profilers,
+ help='enable profiling (' + '/'.join(profilers) + ')',)
+-parser.add_option('--with-gtest', metavar='PATH', help='ignored')
++parser.add_option('--gtest-source-dir', metavar='PATH',
++ help='Path to GoogleTest source directory. If not provided ' +
++ 'GTEST_SOURCE_DIR will be probed in the environment. ' +
++ 'Tests will not be built without a value.')
+ parser.add_option('--with-python', metavar='EXE',
+ help='use EXE as the Python interpreter',
+ default=os.path.basename(sys.executable))
+@@ -425,6 +428,7 @@ n.variable('cflags', ' '.join(shell_esca
+ if 'LDFLAGS' in configure_env:
+ ldflags.append(configure_env['LDFLAGS'])
+ n.variable('ldflags', ' '.join(shell_escape(flag) for flag in ldflags))
++
+ n.newline()
+
+ if platform.is_msvc():
+@@ -582,6 +586,83 @@ if options.bootstrap:
+ # build.ninja file.
+ n = ninja_writer
+
++# Build the ninja_test executable only if the GTest source directory
++# is provided explicitly. Either from the environment with GTEST_SOURCE_DIR
++# or with the --gtest-source-dir command-line option.
++#
++# Do not try to look for an installed binary version, and link against it
++# because doing so properly is platform-specific (use the CMake build for
++# this).
++if options.gtest_source_dir:
++ gtest_src_dir = options.gtest_source_dir
++else:
++ gtest_src_dir = os.environ.get('GTEST_SOURCE_DIR')
++
++if gtest_src_dir:
++ # Verify GoogleTest source directory, and add its include directory
++ # to the global include search path (even for non-test sources) to
++ # keep the build plan generation simple.
++ gtest_all_cc = os.path.join(gtest_src_dir, 'googletest', 'src', 'gtest-all.cc')
++ if not os.path.exists(gtest_all_cc):
++ print('ERROR: Missing GoogleTest source file: %s' % gtest_all_cc)
++ sys.exit(1)
++
++ n.comment('Tests all build into ninja_test executable.')
++
++ # Test-specific version of cflags, must include the GoogleTest
++ # include directory. Also GoogleTest can only build with a C++14 compiler.
++ test_cflags = [f.replace('std=c++11', 'std=c++14') for f in cflags]
++ test_cflags.append('-I' + os.path.join(gtest_src_dir, 'googletest', 'include'))
++
++ test_variables = [('cflags', test_cflags)]
++ if platform.is_msvc():
++ test_variables += [('pdb', 'ninja_test.pdb')]
++
++ test_names = [
++ 'build_log_test',
++ 'build_test',
++ 'clean_test',
++ 'clparser_test',
++ 'depfile_parser_test',
++ 'deps_log_test',
++ 'disk_interface_test',
++ 'dyndep_parser_test',
++ 'edit_distance_test',
++ 'graph_test',
++ 'json_test',
++ 'lexer_test',
++ 'manifest_parser_test',
++ 'ninja_test',
++ 'state_test',
++ 'string_piece_util_test',
++ 'subprocess_test',
++ 'test',
++ 'util_test',
++ ]
++ if platform.is_windows():
++ test_names += [
++ 'includes_normalize_test',
++ 'msvc_helper_test',
++ ]
++
++ objs = []
++ for name in test_names:
++ objs += cxx(name, variables=test_variables)
++
++ # Build GTest as a monolithic source file.
++ # This requires one extra include search path, so replace the
++ # value of 'cflags' in our list.
++ gtest_all_variables = test_variables[1:] + [
++ ('cflags', test_cflags + ['-I' + os.path.join(gtest_src_dir, 'googletest') ]),
++ ]
++ # Do not use cxx() directly to ensure the object file is under $builddir.
++ objs += n.build(built('gtest_all' + objext), 'cxx', gtest_all_cc, variables=gtest_all_variables)
++
++ ninja_test = n.build(binary('ninja_test'), 'link', objs, implicit=ninja_lib,
++ variables=[('libs', libs)])
++ n.newline()
++ all_targets += ninja_test
++
+ n.comment('Ancillary executables.')
+
+ if platform.is_aix() and '-maix64' not in ldflags:
diff --git a/tools/ninja/patches/010-bootstrap-configure-only.patch b/tools/ninja/patches/010-bootstrap-configure-only.patch
new file mode 100644
index 0000000000..4785ac654e
--- /dev/null
+++ b/tools/ninja/patches/010-bootstrap-configure-only.patch
@@ -0,0 +1,24 @@
+--- a/configure.py
++++ b/configure.py
+@@ -198,6 +198,8 @@ parser = OptionParser()
+ profilers = ['gmon', 'pprof']
+ parser.add_option('--bootstrap', action='store_true',
+ help='bootstrap a ninja binary from nothing')
++parser.add_option('--no-rebuild', action='store_true',
++ help='let user execute ninja after build.ninja generation')
+ parser.add_option('--verbose', action='store_true',
+ help='enable verbose build')
+ parser.add_option('--platform',
+@@ -756,7 +758,11 @@ n.build('all', 'phony', all_targets)
+ n.close()
+ print('wrote %s.' % BUILD_FILENAME)
+
+-if options.bootstrap:
++if options.bootstrap and options.no_rebuild:
++ print('bootstrap complete. execute ninja in this directory...')
++ print(os.getcwd())
++
++elif options.bootstrap:
+ print('bootstrap complete. rebuilding...')
+
+ rebuild_args = []
diff --git a/tools/ninja/patches/100-make_jobserver_support.patch b/tools/ninja/patches/100-make_jobserver_support.patch
index 34d2b6c431..82ecf0222e 100644
--- a/tools/ninja/patches/100-make_jobserver_support.patch
+++ b/tools/ninja/patches/100-make_jobserver_support.patch
@@ -18,22 +18,9 @@ Documentation for GNU make jobserver
http://make.mad-scientist.net/papers/jobserver-implementation/
-Fixes https://github.com/ninja-build/ninja/issues/1139
----
- configure.py | 2 +
- src/build.cc | 63 ++++++++----
- src/build.h | 3 +
- src/tokenpool-gnu-make.cc | 211 ++++++++++++++++++++++++++++++++++++++
- src/tokenpool-none.cc | 27 +++++
- src/tokenpool.h | 26 +++++
- 6 files changed, 310 insertions(+), 22 deletions(-)
- create mode 100644 src/tokenpool-gnu-make.cc
- create mode 100644 src/tokenpool-none.cc
- create mode 100644 src/tokenpool.h
-
--- a/configure.py
+++ b/configure.py
-@@ -517,11 +517,13 @@ for name in ['build',
+@@ -543,11 +543,13 @@ for name in ['build',
'state',
'status',
'string_piece_util',
@@ -47,7 +34,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
'includes_normalize-win32',
'msvc_helper-win32',
'msvc_helper_main-win32']:
-@@ -530,7 +532,9 @@ if platform.is_windows():
+@@ -556,7 +558,9 @@ if platform.is_windows():
objs += cxx('minidump-win32', variables=cxxvariables)
objs += cc('getopt')
else:
@@ -58,17 +45,17 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
if platform.is_aix():
objs += cc('getopt')
if platform.is_msvc():
-@@ -588,6 +592,7 @@ for name in ['build_log_test',
- 'string_piece_util_test',
- 'subprocess_test',
- 'test',
-+ 'tokenpool_test',
- 'util_test']:
- objs += cxx(name, variables=cxxvariables)
- if platform.is_windows():
+@@ -639,6 +643,7 @@ if gtest_src_dir:
+ 'string_piece_util_test',
+ 'subprocess_test',
+ 'test',
++ 'tokenpool_test',
+ 'util_test',
+ ]
+ if platform.is_windows():
--- a/src/build.cc
+++ b/src/build.cc
-@@ -35,6 +35,7 @@
+@@ -39,6 +39,7 @@
#include "state.h"
#include "status.h"
#include "subprocess.h"
@@ -76,10 +63,12 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
#include "util.h"
using namespace std;
-@@ -47,8 +48,9 @@ struct DryRunCommandRunner : public Comm
+@@ -50,24 +51,29 @@ struct DryRunCommandRunner : public Comm
+ virtual ~DryRunCommandRunner() {}
// Overridden from CommandRunner:
- virtual bool CanRunMore() const;
+- virtual size_t CanRunMore() const;
++ virtual size_t CanRunMore();
+ virtual bool AcquireToken();
virtual bool StartCommand(Edge* edge);
- virtual bool WaitForCommand(Result* result);
@@ -87,8 +76,11 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
private:
queue<Edge*> finished_;
-@@ -58,12 +60,16 @@ bool DryRunCommandRunner::CanRunMore() c
- return true;
+ };
+
+-size_t DryRunCommandRunner::CanRunMore() const {
++size_t DryRunCommandRunner::CanRunMore() {
+ return SIZE_MAX;
}
+bool DryRunCommandRunner::AcquireToken() {
@@ -105,24 +97,25 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
if (finished_.empty())
return false;
-@@ -149,7 +155,7 @@ void Plan::EdgeWanted(const Edge* edge)
+@@ -160,7 +166,7 @@ void Plan::EdgeWanted(const Edge* edge)
}
Edge* Plan::FindWork() {
- if (ready_.empty())
+ if (!more_ready())
return NULL;
- EdgeSet::iterator e = ready_.begin();
- Edge* edge = *e;
-@@ -448,19 +454,39 @@ void Plan::Dump() const {
+
+ Edge* work = ready_.top();
+@@ -595,19 +601,39 @@ void Plan::Dump() const {
}
struct RealCommandRunner : public CommandRunner {
- explicit RealCommandRunner(const BuildConfig& config) : config_(config) {}
- virtual ~RealCommandRunner() {}
+- virtual size_t CanRunMore() const;
+ explicit RealCommandRunner(const BuildConfig& config);
+ virtual ~RealCommandRunner();
- virtual bool CanRunMore() const;
++ virtual size_t CanRunMore();
+ virtual bool AcquireToken();
virtual bool StartCommand(Edge* edge);
- virtual bool WaitForCommand(Result* result);
@@ -157,7 +150,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
vector<Edge*> RealCommandRunner::GetActiveEdges() {
vector<Edge*> edges;
for (map<const Subprocess*, Edge*>::iterator e = subproc_to_edge_.begin();
-@@ -471,14 +497,23 @@ vector<Edge*> RealCommandRunner::GetActi
+@@ -618,9 +644,11 @@ vector<Edge*> RealCommandRunner::GetActi
void RealCommandRunner::Abort() {
subprocs_.Clear();
@@ -165,28 +158,35 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+ tokens_->Clear();
}
- bool RealCommandRunner::CanRunMore() const {
-- size_t subproc_number =
-- subprocs_.running_.size() + subprocs_.finished_.size();
-- return (int)subproc_number < config_.parallelism
-- && ((subprocs_.running_.empty() || config_.max_load_average <= 0.0f)
-- || GetLoadAverage() < config_.max_load_average);
-+ bool parallelism_limit_not_reached =
-+ tokens_ || // ignore config_.parallelism
-+ ((int) (subprocs_.running_.size() +
-+ subprocs_.finished_.size()) < config_.parallelism);
-+ return parallelism_limit_not_reached
-+ && (subprocs_.running_.empty() ||
-+ (max_load_average_ <= 0.0f ||
-+ GetLoadAverage() < max_load_average_));
-+}
+-size_t RealCommandRunner::CanRunMore() const {
++size_t RealCommandRunner::CanRunMore() {
+ size_t subproc_number =
+ subprocs_.running_.size() + subprocs_.finished_.size();
+
+@@ -635,6 +663,13 @@ size_t RealCommandRunner::CanRunMore() c
+ if (capacity < 0)
+ capacity = 0;
+
++ if (tokens_) {
++ if (AcquireToken())
++ return SIZE_MAX;
++ else
++ capacity = 0;
++ }
+
-+bool RealCommandRunner::AcquireToken() {
-+ return (!tokens_ || tokens_->Acquire());
+ if (capacity == 0 && subprocs_.running_.empty())
+ // Ensure that we make progress.
+ capacity = 1;
+@@ -642,24 +677,42 @@ size_t RealCommandRunner::CanRunMore() c
+ return capacity;
}
++bool RealCommandRunner::AcquireToken() {
++ return (!tokens_ || tokens_->Acquire());
++}
++
bool RealCommandRunner::StartCommand(Edge* edge) {
-@@ -486,19 +521,33 @@ bool RealCommandRunner::StartCommand(Edg
+ string command = edge->EvaluateCommand();
Subprocess* subproc = subprocs_.Add(command, edge->use_console());
if (!subproc)
return false;
@@ -223,61 +223,17 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
result->status = subproc->Finish();
result->output = subproc->GetOutput();
-@@ -620,38 +669,43 @@ bool Builder::Build(string* err) {
- // command runner.
+@@ -790,7 +843,8 @@ bool Builder::Build(string* err) {
// Second, we attempt to wait for / reap the next finished command.
while (plan_.more_to_do()) {
-- // See if we can start any more commands.
-- if (failures_allowed && command_runner_->CanRunMore()) {
-- if (Edge* edge = plan_.FindWork()) {
-- if (edge->GetBindingBool("generator")) {
-+ // See if we can start any more commands...
-+ bool can_run_more =
-+ failures_allowed &&
-+ plan_.more_ready() &&
-+ command_runner_->CanRunMore();
-+
-+ // ... but we also need a token to do that.
-+ if (can_run_more && command_runner_->AcquireToken()) {
-+ Edge* edge = plan_.FindWork();
-+ if (edge->GetBindingBool("generator")) {
- scan_.build_log()->Close();
- }
-
-- if (!StartEdge(edge, err)) {
-+ if (!StartEdge(edge, err)) {
-+ Cleanup();
-+ status_->BuildFinished();
-+ return false;
-+ }
-+
-+ if (edge->is_phony()) {
-+ if (!plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, err)) {
- Cleanup();
- status_->BuildFinished();
- return false;
- }
--
-- if (edge->is_phony()) {
-- if (!plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, err)) {
-- Cleanup();
-- status_->BuildFinished();
-- return false;
-- }
-- } else {
-- ++pending_commands;
-- }
--
-- // We made some progress; go back to the main loop.
-- continue;
-+ } else {
-+ ++pending_commands;
- }
-+
-+ // We made some progress; go back to the main loop.
-+ continue;
- }
-
+ // See if we can start any more commands.
+- if (failures_allowed) {
++ bool can_run_more = failures_allowed && plan_.more_ready();
++ if (can_run_more) {
+ size_t capacity = command_runner_->CanRunMore();
+ while (capacity > 0) {
+ Edge* edge = plan_.FindWork();
+@@ -833,7 +887,7 @@ bool Builder::Build(string* err) {
// See if we can reap any finished commands.
if (pending_commands) {
CommandRunner::Result result;
@@ -286,7 +242,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
result.status == ExitInterrupted) {
Cleanup();
status_->BuildFinished();
-@@ -659,6 +713,10 @@ bool Builder::Build(string* err) {
+@@ -841,6 +895,10 @@ bool Builder::Build(string* err) {
return false;
}
@@ -299,7 +255,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
Cleanup();
--- a/src/build.h
+++ b/src/build.h
-@@ -52,6 +52,9 @@ struct Plan {
+@@ -51,6 +51,9 @@ struct Plan {
/// Returns true if there's more work to be done.
bool more_to_do() const { return wanted_edges_ > 0 && command_edges_ > 0; }
@@ -309,15 +265,17 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
/// Dumps the current state of the plan.
void Dump() const;
-@@ -136,6 +139,7 @@ private:
+@@ -145,7 +148,8 @@ private:
+ /// RealCommandRunner is an implementation that actually runs commands.
struct CommandRunner {
virtual ~CommandRunner() {}
- virtual bool CanRunMore() const = 0;
+- virtual size_t CanRunMore() const = 0;
++ virtual size_t CanRunMore() = 0;
+ virtual bool AcquireToken() = 0;
virtual bool StartCommand(Edge* edge) = 0;
/// The result of waiting for a command.
-@@ -147,7 +151,9 @@ struct CommandRunner {
+@@ -157,7 +161,9 @@ struct CommandRunner {
bool success() const { return status == ExitSuccess; }
};
/// Wait for a command to complete, or return false if interrupted.
@@ -328,7 +286,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
virtual std::vector<Edge*> GetActiveEdges() { return std::vector<Edge*>(); }
virtual void Abort() {}
-@@ -155,7 +161,8 @@ struct CommandRunner {
+@@ -165,7 +171,8 @@ struct CommandRunner {
/// Options (e.g. verbosity, parallelism) passed to a build.
struct BuildConfig {
@@ -338,7 +296,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
failures_allowed(1), max_load_average(-0.0f) {}
enum Verbosity {
-@@ -167,6 +174,7 @@ struct BuildConfig {
+@@ -177,6 +184,7 @@ struct BuildConfig {
Verbosity verbosity;
bool dry_run;
int parallelism;
@@ -509,13 +467,15 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
#include <assert.h>
+#include <stdarg.h>
+ #include <climits>
+ #include <stdint.h>
- #include "build_log.h"
- #include "deps_log.h"
-@@ -474,8 +475,9 @@ struct FakeCommandRunner : public Comman
+@@ -521,9 +522,10 @@ struct FakeCommandRunner : public Comman
+ max_active_edges_(1), fs_(fs) {}
// CommandRunner impl
- virtual bool CanRunMore() const;
+- virtual size_t CanRunMore() const;
++ virtual size_t CanRunMore();
+ virtual bool AcquireToken();
virtual bool StartCommand(Edge* edge);
- virtual bool WaitForCommand(Result* result);
@@ -523,8 +483,16 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
virtual vector<Edge*> GetActiveEdges();
virtual void Abort();
-@@ -578,6 +580,10 @@ bool FakeCommandRunner::CanRunMore() con
- return active_edges_.size() < max_active_edges_;
+@@ -622,13 +624,17 @@ void BuildTest::RebuildTarget(const stri
+ builder.command_runner_.release();
+ }
+
+-size_t FakeCommandRunner::CanRunMore() const {
++size_t FakeCommandRunner::CanRunMore() {
+ if (active_edges_.size() < max_active_edges_)
+ return SIZE_MAX;
+
+ return 0;
}
+bool FakeCommandRunner::AcquireToken() {
@@ -534,7 +502,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
bool FakeCommandRunner::StartCommand(Edge* edge) {
assert(active_edges_.size() < max_active_edges_);
assert(find(active_edges_.begin(), active_edges_.end(), edge)
-@@ -649,7 +655,7 @@ bool FakeCommandRunner::StartCommand(Edg
+@@ -720,7 +726,7 @@ bool FakeCommandRunner::StartCommand(Edg
return true;
}
@@ -543,7 +511,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
if (active_edges_.empty())
return false;
-@@ -3985,3 +3991,356 @@ TEST_F(BuildTest, ValidationWithCircular
+@@ -4380,3 +4386,355 @@ TEST_F(BuildTest, ValidationWithCircular
EXPECT_FALSE(builder_.AddTarget("out", &err));
EXPECT_EQ("dependency cycle: validate -> validate_in -> validate", err);
}
@@ -557,7 +525,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+ explicit FakeTokenCommandRunner() {}
+
+ // CommandRunner impl
-+ virtual bool CanRunMore() const;
++ virtual bool CanRunMore();
+ virtual bool AcquireToken();
+ virtual bool StartCommand(Edge* edge);
+ virtual bool WaitForCommand(Result* result, bool more_ready);
@@ -572,7 +540,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+ vector<bool> wait_for_command_;
+};
+
-+bool FakeTokenCommandRunner::CanRunMore() const {
++bool FakeTokenCommandRunner::CanRunMore() {
+ if (can_run_more_.size() == 0) {
+ EXPECT_FALSE("unexpected call to CommandRunner::CanRunMore()");
+ return false;
@@ -580,9 +548,8 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+
+ bool result = can_run_more_[0];
+
-+ // Unfortunately CanRunMore() isn't "const" for tests
-+ const_cast<FakeTokenCommandRunner*>(this)->can_run_more_.erase(
-+ const_cast<FakeTokenCommandRunner*>(this)->can_run_more_.begin()
++ can_run_more_.erase(
++ can_run_more_.begin()
+ );
+
+ return result;
@@ -1345,7 +1312,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+}
--- a/src/ninja.cc
+++ b/src/ninja.cc
-@@ -1447,6 +1447,7 @@ int ReadFlags(int* argc, char*** argv,
+@@ -1466,6 +1466,7 @@ int ReadFlags(int* argc, char*** argv,
// We want to run N jobs in parallel. For N = 0, INT_MAX
// is close enough to infinite for most sane builds.
config->parallelism = value > 0 ? value : INT_MAX;
@@ -2139,7 +2106,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+};
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -112,6 +112,7 @@ add_library(libninja OBJECT
+@@ -142,6 +142,7 @@ add_library(libninja OBJECT
src/state.cc
src/status.cc
src/string_piece_util.cc
@@ -2147,22 +2114,26 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
src/util.cc
src/version.cc
)
-@@ -123,9 +124,14 @@ if(WIN32)
+@@ -153,13 +154,17 @@ if(WIN32)
src/msvc_helper_main-win32.cc
src/getopt.c
src/minidump-win32.cc
+ src/tokenpool-gnu-make-win32.cc
)
+ # Build getopt.c, which can be compiled as either C or C++, as C++
+ # so that build environments which lack a C compiler, but have a C++
+ # compiler may build ninja.
+ set_source_files_properties(src/getopt.c PROPERTIES LANGUAGE CXX)
else()
- target_sources(libninja PRIVATE src/subprocess-posix.cc)
+- target_sources(libninja PRIVATE src/subprocess-posix.cc)
+ target_sources(libninja PRIVATE
+ src/subprocess-posix.cc
+ src/tokenpool-gnu-make-posix.cc
+ )
if(CMAKE_SYSTEM_NAME STREQUAL "OS400" OR CMAKE_SYSTEM_NAME STREQUAL "AIX")
target_sources(libninja PRIVATE src/getopt.c)
- endif()
-@@ -204,6 +210,7 @@ if(BUILD_TESTING)
+ # Build getopt.c, which can be compiled as either C or C++, as C++
+@@ -286,6 +291,7 @@ if(BUILD_TESTING)
src/string_piece_util_test.cc
src/subprocess_test.cc
src/test.cc
diff --git a/tools/padjffs2/Makefile b/tools/padjffs2/Makefile
index 422d14db30..b893fadce5 100644
--- a/tools/padjffs2/Makefile
+++ b/tools/padjffs2/Makefile
@@ -13,8 +13,7 @@ PKG_RELEASE:=1
include $(INCLUDE_DIR)/host-build.mk
define Host/Prepare
- mkdir -p $(HOST_BUILD_DIR)
- $(CP) ./src/* $(HOST_BUILD_DIR)/
+ $(call Host/Prepare/Default)
find $(HOST_BUILD_DIR) -name .svn | $(XARGS) rm -rf
endef
diff --git a/tools/patch-image/src/patch-cmdline.c b/tools/patch-image/src/patch-cmdline.c
index 9eaa648ec0..7a54f81b72 100644
--- a/tools/patch-image/src/patch-cmdline.c
+++ b/tools/patch-image/src/patch-cmdline.c
@@ -51,13 +51,13 @@ int main(int argc, char **argv)
fprintf(stderr, "Command line string too long\n");
goto err1;
}
-
+
if (((fd = open(argv[1], O_RDWR)) < 0) ||
(ptr = (char *) mmap(0, search_space + CMDLINE_MAX, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == (void *) (-1)) {
fprintf(stderr, "Could not open kernel image");
goto err2;
}
-
+
for (p = ptr; p < (ptr + search_space); p += 4) {
if (memcmp(p, "CMDLINE:", 8) == 0) {
found = 1;
diff --git a/tools/patch/Makefile b/tools/patch/Makefile
index f4cf588622..785793685c 100644
--- a/tools/patch/Makefile
+++ b/tools/patch/Makefile
@@ -7,13 +7,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=patch
-PKG_VERSION:=2.7.6
-PKG_RELEASE:=7
+PKG_VERSION:=2.8
+PKG_RELEASE:=1
PKG_CPE_ID:=cpe:/a:gnu:patch
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/patch
-PKG_HASH:=8cf86e00ad3aaa6d26aca30640e86b0e3e1f395ed99f189b06d4c9f74bc58a4e
+PKG_HASH:=308a4983ff324521b9b21310bfc2398ca861798f02307c79eb99bb0e0d2bf980
HOST_BUILD_PARALLEL := 1
diff --git a/tools/patch/patches/010-CVE-2018-6951.patch b/tools/patch/patches/010-CVE-2018-6951.patch
deleted file mode 100644
index 10dc568099..0000000000
--- a/tools/patch/patches/010-CVE-2018-6951.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 1f7853c05f9949d81da9be7a02b90cc64284d1f8 Mon Sep 17 00:00:00 2001
-From: Andreas Gruenbacher <agruen@gnu.org>
-Date: Mon, 12 Feb 2018 16:48:24 +0100
-Subject: [PATCH] Fix segfault with mangled rename patch
-
-http://savannah.gnu.org/bugs/?53132
-* src/pch.c (intuit_diff_type): Ensure that two filenames are specified
-for renames and copies (fix the existing check).
----
- src/pch.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/src/pch.c
-+++ b/src/pch.c
-@@ -974,7 +974,8 @@ intuit_diff_type (bool need_header, mode
- if ((pch_rename () || pch_copy ())
- && ! inname
- && ! ((i == OLD || i == NEW) &&
-- p_name[! reverse] &&
-+ p_name[reverse] && p_name[! reverse] &&
-+ name_is_valid (p_name[reverse]) &&
- name_is_valid (p_name[! reverse])))
- {
- say ("Cannot %s file without two valid file names\n", pch_rename () ? "rename" : "copy");
diff --git a/tools/patch/patches/020-CVE-2018-1000156.patch b/tools/patch/patches/020-CVE-2018-1000156.patch
deleted file mode 100644
index 99dfe54075..0000000000
--- a/tools/patch/patches/020-CVE-2018-1000156.patch
+++ /dev/null
@@ -1,142 +0,0 @@
-From b3a0ca3deed00334f9feece43f76776b6a168e47 Mon Sep 17 00:00:00 2001
-From: Andreas Gruenbacher <agruen@gnu.org>
-Date: Fri, 6 Apr 2018 12:14:49 +0200
-Subject: [PATCH] Fix arbitrary command execution in ed-style patches
- (CVE-2018-1000156)
-
-* src/pch.c (do_ed_script): Write ed script to a temporary file instead
-of piping it to ed: this will cause ed to abort on invalid commands
-instead of rejecting them and carrying on.
-* tests/ed-style: New test case.
-* tests/Makefile.am (TESTS): Add test case.
----
- src/pch.c | 89 +++++++++++++++++++++++++++++++++++++++++--------------
- 1 file changed, 66 insertions(+), 23 deletions(-)
-
---- a/src/pch.c
-+++ b/src/pch.c
-@@ -33,6 +33,7 @@
- # include <io.h>
- #endif
- #include <safe.h>
-+#include <sys/wait.h>
-
- #define INITHUNKMAX 125 /* initial dynamic allocation size */
-
-@@ -2389,22 +2390,28 @@ do_ed_script (char const *inname, char c
- static char const editor_program[] = EDITOR_PROGRAM;
-
- file_offset beginning_of_this_line;
-- FILE *pipefp = 0;
- size_t chars_read;
-+ FILE *tmpfp = 0;
-+ char const *tmpname;
-+ int tmpfd;
-+ pid_t pid;
-+
-+ if (! dry_run && ! skip_rest_of_patch)
-+ {
-+ /* Write ed script to a temporary file. This causes ed to abort on
-+ invalid commands such as when line numbers or ranges exceed the
-+ number of available lines. When ed reads from a pipe, it rejects
-+ invalid commands and treats the next line as a new command, which
-+ can lead to arbitrary command execution. */
-+
-+ tmpfd = make_tempfile (&tmpname, 'e', NULL, O_RDWR | O_BINARY, 0);
-+ if (tmpfd == -1)
-+ pfatal ("Can't create temporary file %s", quotearg (tmpname));
-+ tmpfp = fdopen (tmpfd, "w+b");
-+ if (! tmpfp)
-+ pfatal ("Can't open stream for file %s", quotearg (tmpname));
-+ }
-
-- if (! dry_run && ! skip_rest_of_patch) {
-- int exclusive = *outname_needs_removal ? 0 : O_EXCL;
-- assert (! inerrno);
-- *outname_needs_removal = true;
-- copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
-- sprintf (buf, "%s %s%s", editor_program,
-- verbosity == VERBOSE ? "" : "- ",
-- outname);
-- fflush (stdout);
-- pipefp = popen(buf, binary_transput ? "wb" : "w");
-- if (!pipefp)
-- pfatal ("Can't open pipe to %s", quotearg (buf));
-- }
- for (;;) {
- char ed_command_letter;
- beginning_of_this_line = file_tell (pfp);
-@@ -2415,14 +2422,14 @@ do_ed_script (char const *inname, char c
- }
- ed_command_letter = get_ed_command_letter (buf);
- if (ed_command_letter) {
-- if (pipefp)
-- if (! fwrite (buf, sizeof *buf, chars_read, pipefp))
-+ if (tmpfp)
-+ if (! fwrite (buf, sizeof *buf, chars_read, tmpfp))
- write_fatal ();
- if (ed_command_letter != 'd' && ed_command_letter != 's') {
- p_pass_comments_through = true;
- while ((chars_read = get_line ()) != 0) {
-- if (pipefp)
-- if (! fwrite (buf, sizeof *buf, chars_read, pipefp))
-+ if (tmpfp)
-+ if (! fwrite (buf, sizeof *buf, chars_read, tmpfp))
- write_fatal ();
- if (chars_read == 2 && strEQ (buf, ".\n"))
- break;
-@@ -2435,13 +2442,49 @@ do_ed_script (char const *inname, char c
- break;
- }
- }
-- if (!pipefp)
-+ if (!tmpfp)
- return;
-- if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, pipefp) == 0
-- || fflush (pipefp) != 0)
-+ if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, tmpfp) == 0
-+ || fflush (tmpfp) != 0)
- write_fatal ();
-- if (pclose (pipefp) != 0)
-- fatal ("%s FAILED", editor_program);
-+
-+ if (lseek (tmpfd, 0, SEEK_SET) == -1)
-+ pfatal ("Can't rewind to the beginning of file %s", quotearg (tmpname));
-+
-+ if (! dry_run && ! skip_rest_of_patch) {
-+ int exclusive = *outname_needs_removal ? 0 : O_EXCL;
-+ *outname_needs_removal = true;
-+ if (inerrno != ENOENT)
-+ {
-+ *outname_needs_removal = true;
-+ copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
-+ }
-+ sprintf (buf, "%s %s%s", editor_program,
-+ verbosity == VERBOSE ? "" : "- ",
-+ outname);
-+ fflush (stdout);
-+
-+ pid = fork();
-+ if (pid == -1)
-+ pfatal ("Can't fork");
-+ else if (pid == 0)
-+ {
-+ dup2 (tmpfd, 0);
-+ execl ("/bin/sh", "sh", "-c", buf, (char *) 0);
-+ _exit (2);
-+ }
-+ else
-+ {
-+ int wstatus;
-+ if (waitpid (pid, &wstatus, 0) == -1
-+ || ! WIFEXITED (wstatus)
-+ || WEXITSTATUS (wstatus) != 0)
-+ fatal ("%s FAILED", editor_program);
-+ }
-+ }
-+
-+ fclose (tmpfp);
-+ safe_unlink (tmpname);
-
- if (ofp)
- {
diff --git a/tools/patch/patches/030-CVE-2018-6952.patch b/tools/patch/patches/030-CVE-2018-6952.patch
deleted file mode 100644
index 36b58c79dd..0000000000
--- a/tools/patch/patches/030-CVE-2018-6952.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From df40f2ea17254de269a3624319a12a93a4e395ff Mon Sep 17 00:00:00 2001
-From: Andreas Gruenbacher <agruen@gnu.org>
-Date: Fri, 17 Aug 2018 13:35:40 +0200
-Subject: [PATCH] Fix swapping fake lines in pch_swap
-
-* src/pch.c (pch_swap): Fix swapping p_bfake and p_efake when there is a
-blank line in the middle of a context-diff hunk: that empty line stays
-in the middle of the hunk and isn't swapped.
-
-Fixes: https://savannah.gnu.org/bugs/index.php?53133
----
- src/pch.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/src/pch.c
-+++ b/src/pch.c
-@@ -2115,7 +2115,7 @@ pch_swap (void)
- }
- if (p_efake >= 0) { /* fix non-freeable ptr range */
- if (p_efake <= i)
-- n = p_end - i + 1;
-+ n = p_end - p_ptrn_lines;
- else
- n = -i;
- p_efake += n;
diff --git a/tools/patch/patches/040-Fix-error-handling-with-git-style-patches.patch b/tools/patch/patches/040-Fix-error-handling-with-git-style-patches.patch
deleted file mode 100644
index 5cc958e746..0000000000
--- a/tools/patch/patches/040-Fix-error-handling-with-git-style-patches.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 424da221cec76ea200cff1fa9b08a6f3d94c28a7 Mon Sep 17 00:00:00 2001
-From: Lubomir Rintel <lkundrak@v3.sk>
-Date: Wed, 31 Oct 2018 16:39:13 -0700
-Subject: [PATCH] Fix error handling with git-style patches
-
-When an error is encountered in output_files(), the subsequent call to
-cleanup() calls back into output_files() resulting in an infinte recursion.
-This is trivially reproduced with a git-style patch (which utilizes
-output_file_later()) that tries to patch a nonexistent or unreadable
-file (see attached test case).
-
-* src/patch.c: (output_files) clear the files_to_output list before
-iterating it, so that recursive calls won't iterate the same files.
----
- src/patch.c | 12 ++++++++----
- 1 file changed, 8 insertions(+), 4 deletions(-)
-
---- a/src/patch.c
-+++ b/src/patch.c
-@@ -1938,8 +1938,12 @@ output_files (struct stat const *st)
- {
- gl_list_iterator_t iter;
- const void *elt;
-+ gl_list_t files;
-
-- iter = gl_list_iterator (files_to_output);
-+ files = files_to_output;
-+ init_files_to_output ();
-+
-+ iter = gl_list_iterator (files);
- while (gl_list_iterator_next (&iter, &elt, NULL))
- {
- const struct file_to_output *file_to_output = elt;
-@@ -1957,8 +1961,8 @@ output_files (struct stat const *st)
- /* Free the list up to here. */
- for (;;)
- {
-- const void *elt2 = gl_list_get_at (files_to_output, 0);
-- gl_list_remove_at (files_to_output, 0);
-+ const void *elt2 = gl_list_get_at (files, 0);
-+ gl_list_remove_at (files, 0);
- if (elt == elt2)
- break;
- }
-@@ -1967,7 +1971,7 @@ output_files (struct stat const *st)
- }
- }
- gl_list_iterator_free (&iter);
-- gl_list_clear (files_to_output);
-+ gl_list_clear (files);
- }
-
- /* Fatal exit with cleanup. */
diff --git a/tools/patch/patches/050-CVE-2019-13636.patch b/tools/patch/patches/050-CVE-2019-13636.patch
deleted file mode 100644
index e62c3d4175..0000000000
--- a/tools/patch/patches/050-CVE-2019-13636.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From dce4683cbbe107a95f1f0d45fabc304acfb5d71a Mon Sep 17 00:00:00 2001
-From: Andreas Gruenbacher <agruen@gnu.org>
-Date: Mon, 15 Jul 2019 16:21:48 +0200
-Subject: Don't follow symlinks unless --follow-symlinks is given
-
-* src/inp.c (plan_a, plan_b), src/util.c (copy_to_fd, copy_file,
-append_to_file): Unless the --follow-symlinks option is given, open files with
-the O_NOFOLLOW flag to avoid following symlinks. So far, we were only doing
-that consistently for input files.
-* src/util.c (create_backup): When creating empty backup files, (re)create them
-with O_CREAT | O_EXCL to avoid following symlinks in that case as well.
----
- src/inp.c | 12 ++++++++++--
- src/util.c | 14 +++++++++++---
- 2 files changed, 21 insertions(+), 5 deletions(-)
-
-diff --git a/src/inp.c b/src/inp.c
-index 32d0919..22d7473 100644
---- a/src/inp.c
-+++ b/src/inp.c
-@@ -238,8 +238,13 @@ plan_a (char const *filename)
- {
- if (S_ISREG (instat.st_mode))
- {
-- int ifd = safe_open (filename, O_RDONLY|binary_transput, 0);
-+ int flags = O_RDONLY | binary_transput;
- size_t buffered = 0, n;
-+ int ifd;
-+
-+ if (! follow_symlinks)
-+ flags |= O_NOFOLLOW;
-+ ifd = safe_open (filename, flags, 0);
- if (ifd < 0)
- pfatal ("can't open file %s", quotearg (filename));
-
-@@ -340,6 +345,7 @@ plan_a (char const *filename)
- static void
- plan_b (char const *filename)
- {
-+ int flags = O_RDONLY | binary_transput;
- int ifd;
- FILE *ifp;
- int c;
-@@ -353,7 +359,9 @@ plan_b (char const *filename)
-
- if (instat.st_size == 0)
- filename = NULL_DEVICE;
-- if ((ifd = safe_open (filename, O_RDONLY | binary_transput, 0)) < 0
-+ if (! follow_symlinks)
-+ flags |= O_NOFOLLOW;
-+ if ((ifd = safe_open (filename, flags, 0)) < 0
- || ! (ifp = fdopen (ifd, binary_transput ? "rb" : "r")))
- pfatal ("Can't open file %s", quotearg (filename));
- if (TMPINNAME_needs_removal)
-diff --git a/src/util.c b/src/util.c
-index 1cc08ba..fb38307 100644
---- a/src/util.c
-+++ b/src/util.c
-@@ -388,7 +388,7 @@ create_backup (char const *to, const struct stat *to_st, bool leave_original)
-
- try_makedirs_errno = ENOENT;
- safe_unlink (bakname);
-- while ((fd = safe_open (bakname, O_CREAT | O_WRONLY | O_TRUNC, 0666)) < 0)
-+ while ((fd = safe_open (bakname, O_CREAT | O_EXCL | O_WRONLY | O_TRUNC, 0666)) < 0)
- {
- if (errno != try_makedirs_errno)
- pfatal ("Can't create file %s", quotearg (bakname));
-@@ -579,10 +579,13 @@ create_file (char const *file, int open_flags, mode_t mode,
- static void
- copy_to_fd (const char *from, int tofd)
- {
-+ int from_flags = O_RDONLY | O_BINARY;
- int fromfd;
- ssize_t i;
-
-- if ((fromfd = safe_open (from, O_RDONLY | O_BINARY, 0)) < 0)
-+ if (! follow_symlinks)
-+ from_flags |= O_NOFOLLOW;
-+ if ((fromfd = safe_open (from, from_flags, 0)) < 0)
- pfatal ("Can't reopen file %s", quotearg (from));
- while ((i = read (fromfd, buf, bufsize)) != 0)
- {
-@@ -625,6 +628,8 @@ copy_file (char const *from, char const *to, struct stat *tost,
- else
- {
- assert (S_ISREG (mode));
-+ if (! follow_symlinks)
-+ to_flags |= O_NOFOLLOW;
- tofd = create_file (to, O_WRONLY | O_BINARY | to_flags, mode,
- to_dir_known_to_exist);
- copy_to_fd (from, tofd);
-@@ -640,9 +645,12 @@ copy_file (char const *from, char const *to, struct stat *tost,
- void
- append_to_file (char const *from, char const *to)
- {
-+ int to_flags = O_WRONLY | O_APPEND | O_BINARY;
- int tofd;
-
-- if ((tofd = safe_open (to, O_WRONLY | O_BINARY | O_APPEND, 0)) < 0)
-+ if (! follow_symlinks)
-+ to_flags |= O_NOFOLLOW;
-+ if ((tofd = safe_open (to, to_flags, 0)) < 0)
- pfatal ("Can't reopen file %s", quotearg (to));
- copy_to_fd (from, tofd);
- if (close (tofd) != 0)
---
-cgit v1.0-41-gc330
-
diff --git a/tools/patch/patches/060-CVE-2019-13638.patch b/tools/patch/patches/060-CVE-2019-13638.patch
deleted file mode 100644
index 38caff628a..0000000000
--- a/tools/patch/patches/060-CVE-2019-13638.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 3fcd042d26d70856e826a42b5f93dc4854d80bf0 Mon Sep 17 00:00:00 2001
-From: Andreas Gruenbacher <agruen@gnu.org>
-Date: Fri, 6 Apr 2018 19:36:15 +0200
-Subject: Invoke ed directly instead of using the shell
-
-* src/pch.c (do_ed_script): Invoke ed directly instead of using a shell
-command to avoid quoting vulnerabilities.
----
- src/pch.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
-diff --git a/src/pch.c b/src/pch.c
-index 4fd5a05..16e001a 100644
---- a/src/pch.c
-+++ b/src/pch.c
-@@ -2459,9 +2459,6 @@ do_ed_script (char const *inname, char const *outname,
- *outname_needs_removal = true;
- copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
- }
-- sprintf (buf, "%s %s%s", editor_program,
-- verbosity == VERBOSE ? "" : "- ",
-- outname);
- fflush (stdout);
-
- pid = fork();
-@@ -2470,7 +2467,8 @@ do_ed_script (char const *inname, char const *outname,
- else if (pid == 0)
- {
- dup2 (tmpfd, 0);
-- execl ("/bin/sh", "sh", "-c", buf, (char *) 0);
-+ assert (outname[0] != '!' && outname[0] != '-');
-+ execlp (editor_program, editor_program, "-", outname, (char *) NULL);
- _exit (2);
- }
- else
---
-cgit v1.0-41-gc330
-
diff --git a/tools/patch/patches/070-don-t-fail-hard-on-EACCES-when-copying-xattrs.patch b/tools/patch/patches/070-don-t-fail-hard-on-EACCES-when-copying-xattrs.patch
deleted file mode 100644
index e19a9c0845..0000000000
--- a/tools/patch/patches/070-don-t-fail-hard-on-EACCES-when-copying-xattrs.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From f42cbe1a91a3a6f79d1eec594ce7c72aec79179b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <thomas@t-8ch.de>
-Date: Wed, 9 Nov 2022 05:08:22 +0100
-Subject: [PATCH] don't fail hard on EACCES when copying xattrs
-
-On btrfs the xattr "btrfs.compressed" requires privileges to set,
-otherwise EACCES is returned.
-When patch tries to do copy this attribute it receives the error and
-aborts.
----
- src/util.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/src/util.c
-+++ b/src/util.c
-@@ -182,7 +182,7 @@ copy_attr_error (struct error_context *c
- int err = errno;
- va_list ap;
-
-- if (err != ENOSYS && err != ENOTSUP && err != EPERM)
-+ if (err != ENOSYS && err != ENOTSUP && err != EPERM && err != EACCES)
- {
- /* use verror module to print error message */
- va_start (ap, fmt);
-@@ -284,7 +284,7 @@ set_file_attributes (char const *to, enu
- }
- if (attr & FA_XATTRS)
- if (copy_attr (from, to) != 0
-- && errno != ENOSYS && errno != ENOTSUP && errno != EPERM)
-+ && errno != ENOSYS && errno != ENOTSUP && errno != EPERM && errno != EACCES)
- fatal_exit (0);
- if (attr & FA_MODE)
- {
diff --git a/tools/pkgconf/Makefile b/tools/pkgconf/Makefile
index 517b8d847b..7cb81f9f02 100644
--- a/tools/pkgconf/Makefile
+++ b/tools/pkgconf/Makefile
@@ -7,11 +7,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=pkgconf
-PKG_VERSION:=2.1.1
+PKG_VERSION:=2.5.1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://distfiles.dereferenced.org/pkgconf
-PKG_HASH:=1a00b7fa08c7b506a24c40f7cc8d9e0e59be748d731af8f7aa0b4d722bd8ccbe
+PKG_HASH:=ab89d59810d9cad5dfcd508f25efab8ea0b1c8e7bad91c2b6351f13e6a5940d8
PKG_CPE_ID:=cpe:/a:pkgconf:pkgconf
diff --git a/tools/quilt/Makefile b/tools/quilt/Makefile
index c16f989b5d..8fe69ca1e8 100644
--- a/tools/quilt/Makefile
+++ b/tools/quilt/Makefile
@@ -7,11 +7,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=quilt
-PKG_VERSION:=0.67
+PKG_VERSION:=0.69
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SAVANNAH/quilt
-PKG_HASH:=3be3be0987e72a6c364678bb827e3e1fcc10322b56bc5f02b576698f55013cc2
+PKG_HASH:=555ddffde22da3c86d1caf5a9c1fb8a152ac2b84730437bd39cc08849c9f4852
include $(INCLUDE_DIR)/host-build.mk
diff --git a/tools/quilt/patches/001-fix_compile.patch b/tools/quilt/patches/001-fix_compile.patch
index ef6f8ff608..c9a236e1b6 100644
--- a/tools/quilt/patches/001-fix_compile.patch
+++ b/tools/quilt/patches/001-fix_compile.patch
@@ -1,6 +1,6 @@
--- a/Makefile.in
+++ b/Makefile.in
-@@ -276,13 +276,10 @@ $(patsubst %.in,%,$(wildcard bin/*.in qu
+@@ -279,13 +279,10 @@ $(patsubst %.in,%,$(wildcard bin/*.in qu
@$(if $(filter $@,$(NON_EXEC_IN)),,chmod +x $@)
configure : configure.ac aclocal.m4
diff --git a/tools/sparse/Makefile b/tools/sparse/Makefile
index 74d25bfbde..a46e495678 100644
--- a/tools/sparse/Makefile
+++ b/tools/sparse/Makefile
@@ -8,7 +8,6 @@ PKG_NAME:=sparse
PKG_VERSION:=0.6.4
PKG_HASH:=8b907c007459a66db110496f0a02fcff1c3c8b67ddff37b959fb102a28424209
-PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@KERNEL/software/devel/sparse/dist/
diff --git a/tools/sparse/patches/010-llvm15.patch b/tools/sparse/patches/010-llvm15.patch
new file mode 100644
index 0000000000..54fddc7a90
--- /dev/null
+++ b/tools/sparse/patches/010-llvm15.patch
@@ -0,0 +1,128 @@
+From 0544c547682b878758eea731ef4b8e64e5ec91fb Mon Sep 17 00:00:00 2001
+From: Luc Van Oostenryck <lucvoo@kernel.org>
+Date: Sat, 20 Jan 2024 01:24:12 +0100
+Subject: llvm: fix LLVM 15 deprecation warnings
+
+LLVM 15 switched to opaque pointers by default and no longer supports typed pointers.
+Remove deprecated LLVM calls and update test.
+
+Original-patch-by: Vladimir Petko <vladimir.petko@canonical.com>
+Signed-off-by: Luc Van Oostenryck <lucvoo@kernel.org>
+---
+ sparse-llvm.c | 35 ++++++++++++++++++++++++++++++++++-
+ validation/backend/call-variadic.c | 16 ++++------------
+ 2 files changed, 38 insertions(+), 13 deletions(-)
+
+--- a/sparse-llvm.c
++++ b/sparse-llvm.c
+@@ -32,6 +32,20 @@ static LLVMTypeRef func_return_type(stru
+ return symbol_type(sym->ctype.base_type);
+ }
+
++#if LLVM_VERSION_MAJOR > 14
++// A call can be done either with a SYM_FN or a SYM_PTR (pointing to a SYM_FN).
++// Return the type corresponding to the SYM_FN.
++static LLVMTypeRef func_full_type(struct symbol *type)
++{
++ if (type->type == SYM_NODE) {
++ struct symbol *btype = type->ctype.base_type;
++ if (btype->type == SYM_PTR)
++ type = btype->ctype.base_type;
++ }
++ return symbol_type(type);
++}
++#endif
++
+ static LLVMTypeRef sym_func_type(struct symbol *sym)
+ {
+ int n_arg = symbol_list_size(sym->arguments);
+@@ -302,7 +316,11 @@ static LLVMValueRef get_sym_value(LLVMMo
+ LLVMSetGlobalConstant(data, 1);
+ LLVMSetInitializer(data, LLVMConstString(strdup(s), strlen(s) + 1, true));
+
++#if LLVM_VERSION_MAJOR > 14
++ result = LLVMConstGEP2(LLVMTypeOf(data), data, indices, ARRAY_SIZE(indices));
++#else
+ result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices));
++#endif
+ return result;
+ }
+ default:
+@@ -485,7 +503,11 @@ static LLVMValueRef calc_gep(LLVMBuilder
+ /* convert base to char* type */
+ base = LLVMBuildPointerCast(builder, base, bytep, name);
+ /* addr = base + off */
++#if LLVM_VERSION_MAJOR > 14
++ addr = LLVMBuildInBoundsGEP2(builder, LLVMTypeOf(base), base, &off, 1, name);
++#else
+ addr = LLVMBuildInBoundsGEP(builder, base, &off, 1, name);
++#endif
+ /* convert back to the actual pointer type */
+ addr = LLVMBuildPointerCast(builder, addr, type, name);
+ return addr;
+@@ -711,7 +733,11 @@ static void output_op_load(struct functi
+
+ /* perform load */
+ pseudo_name(insn->target, name);
++#if LLVM_VERSION_MAJOR > 14
++ target = LLVMBuildLoad2(fn->builder, symbol_type(insn->type), addr, name);
++#else
+ target = LLVMBuildLoad(fn->builder, addr, name);
++#endif
+
+ insn->target->priv = target;
+ }
+@@ -797,6 +823,7 @@ static void output_op_switch(struct func
+ static void output_op_call(struct function *fn, struct instruction *insn)
+ {
+ LLVMValueRef target, func;
++ struct symbol *fntype;
+ struct symbol *ctype;
+ int n_arg = 0, i;
+ struct pseudo *arg;
+@@ -812,14 +839,20 @@ static void output_op_call(struct functi
+ else
+ func = pseudo_to_value(fn, ctype, insn->func);
+ i = 0;
++ fntype = ctype; // first symbol in the list is the function 'true' type
+ FOR_EACH_PTR(insn->arguments, arg) {
+- NEXT_PTR_LIST(ctype);
++ NEXT_PTR_LIST(ctype); // the remaining ones are the arguments' type
+ args[i++] = pseudo_to_rvalue(fn, ctype, arg);
+ } END_FOR_EACH_PTR(arg);
+ FINISH_PTR_LIST(ctype);
+
+ pseudo_name(insn->target, name);
++#if LLVM_VERSION_MAJOR > 14
++ target = LLVMBuildCall2(fn->builder, func_full_type(fntype), func, args, n_arg, name);
++#else
++ (void) fntype;
+ target = LLVMBuildCall(fn->builder, func, args, n_arg, name);
++#endif
+
+ insn->target->priv = target;
+ }
+--- a/validation/backend/call-variadic.c
++++ b/validation/backend/call-variadic.c
+@@ -11,17 +11,9 @@ int foo(const char *fmt, int a, long l,
+ /*
+ * check-name: call-variadic
+ * check-command: sparse-llvm-dis -m64 $file
++ * check-output-ignore
++ * check-output-contains: , ...) @print(\\(i8\\*\\|ptr\\) %ARG1., i32 120, i32 %ARG2., i32 8, i64 %ARG3., i64 0, \\(i32\\*\\|ptr\\) %ARG4., \\(i8\\*\\|ptr\\) null)
++ * check-output-contains: define i32 @foo(
++ * check-output-contains: declare i32 @print(
+ *
+- * check-output-start
+-; ModuleID = '<stdin>'
+-source_filename = "sparse"
+-
+-define i32 @foo(i8* %ARG1., i32 %ARG2., i64 %ARG3., i32* %ARG4.) {
+-L0:
+- %R5. = call i32 (i8*, ...) @print(i8* %ARG1., i32 120, i32 %ARG2., i32 8, i64 %ARG3., i64 0, i32* %ARG4., i8* null)
+- ret i32 %R5.
+-}
+-
+-declare i32 @print(i8*, ...)
+- * check-output-end
+ */
diff --git a/tools/squashfs3-lzma/patches/160-gcc15.patch b/tools/squashfs3-lzma/patches/160-gcc15.patch
new file mode 100644
index 0000000000..542fa52202
--- /dev/null
+++ b/tools/squashfs3-lzma/patches/160-gcc15.patch
@@ -0,0 +1,20 @@
+--- a/squashfs-tools/mksquashfs.c
++++ b/squashfs-tools/mksquashfs.c
+@@ -290,7 +290,7 @@ void restorefs()
+ }
+
+
+-void sighandler()
++void sighandler(int i)
+ {
+ if(interrupted == 1)
+ restorefs();
+@@ -302,7 +302,7 @@ void sighandler()
+ }
+
+
+-void sighandler2()
++void sighandler2(int i)
+ {
+ EXIT_MKSQUASHFS();
+ }
diff --git a/tools/squashfs4/Makefile b/tools/squashfs4/Makefile
index 38c3e5233f..94679bd79d 100644
--- a/tools/squashfs4/Makefile
+++ b/tools/squashfs4/Makefile
@@ -8,14 +8,14 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=squashfs4
PKG_CPE_ID:=cpe:/a:phillip_lougher:squashfs
-PKG_VERSION:=4.6.1
-PKG_RELEASE=3
+PKG_VERSION:=4.7.2
+PKG_RELEASE=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/plougher/squashfs-tools
-PKG_SOURCE_DATE:=2023-03-26
-PKG_SOURCE_VERSION:=d8cb82d9840330f9344ec37b992595b5d7b44184
-PKG_MIRROR_HASH:=e84026de1ab187f3f76d1b781a29259d818f887e1651225f850a62d6f90b1b9e
+PKG_SOURCE_DATE:=2025-08-19
+PKG_SOURCE_VERSION:=99d23a31b471433c51e9c145aeba2ab1536e34df
+PKG_MIRROR_HASH:=229a1b8f465fa0f576b5ace1753a8e9d28a2c4254ec2b019668baa676094f6c3
HOST_BUILD_PARALLEL:=1
@@ -24,6 +24,10 @@ include $(INCLUDE_DIR)/host-build.mk
define Host/Compile
+$(HOST_MAKE_VARS) \
$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR)/squashfs-tools \
+ LZ4_SUPPORT=0 \
+ LZO_SUPPORT=0 \
+ ZSTD_SUPPORT=0 \
+ GZIP_SUPPORT=1 \
XZ_SUPPORT=1 \
LZMA_XZ_SUPPORT=1 \
XZ_EXTENDED_OPTIONS=1 \
diff --git a/tools/squashfs4/patches/001-xz_wrapper-support-multiple-lzma-configuration-optio.patch b/tools/squashfs4/patches/001-xz_wrapper-support-multiple-lzma-configuration-optio.patch
deleted file mode 100644
index bcc962a9de..0000000000
--- a/tools/squashfs4/patches/001-xz_wrapper-support-multiple-lzma-configuration-optio.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From dcb976fe4ee40e4bac8ae0dcc836629c625a6fd4 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 14 Oct 2022 15:59:16 +0200
-Subject: [PATCH] xz_wrapper: support multiple lzma configuration options
-
-Add option to configure preset, lc, lp and pb lzma parameters.
--Xpreset can be used to set the compression level.
--Xe can be used to set the 'EXTREME' flag to use the lzma compression
-options tweaking additional settings on top of the compression level set.
-
-New option added:
- -Xpreset
- -Xe
- -Xlc
- -Xlp
- -Xpb
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- squashfs-tools/xz_wrapper.c | 119 ++++++++++++++++++++++++++++++++++--
- 1 file changed, 115 insertions(+), 4 deletions(-)
-
---- a/squashfs-tools/xz_wrapper.c
-+++ b/squashfs-tools/xz_wrapper.c
-@@ -44,7 +44,10 @@ static struct bcj bcj[] = {
- static int filter_count = 1;
- static int dictionary_size = 0;
- static float dictionary_percent = 0;
--
-+static int preset = LZMA_PRESET_DEFAULT;
-+static int lc = -1;
-+static int lp = -1;
-+static int pb = -1;
-
- /*
- * This function is called by the options parsing code in mksquashfs.c
-@@ -53,6 +56,11 @@ static float dictionary_percent = 0;
- * Two specific options are supported:
- * -Xbcj
- * -Xdict-size
-+ * -Xpreset
-+ * -Xe
-+ * -Xlc
-+ * -Xlp
-+ * -Xpb
- *
- * This function returns:
- * >=0 (number of additional args parsed) on success
-@@ -141,6 +149,85 @@ static int xz_options(char *argv[], int
- }
-
- return 1;
-+ } else if(strcmp(argv[0], "-Xpreset") == 0) {
-+ char *b;
-+ long val;
-+
-+ if(argc < 2) {
-+ fprintf(stderr, "xz: -Xpreset missing preset-level "
-+ "(valid value 0-9)\n");
-+ goto failed;
-+ }
-+
-+ val = strtol(argv[1], &b, 10);
-+ if (*b != '\0' || (int) val < 0 || (int) val & ~LZMA_PRESET_LEVEL_MASK) {
-+ fprintf(stderr, "xz: -Xpreset can't be "
-+ "negative or more than the max preset\n");
-+ goto failed;
-+ }
-+
-+ preset &= ~LZMA_PRESET_LEVEL_MASK;
-+ preset |= (int) val;
-+
-+ return 1;
-+ } else if(strcmp(argv[0], "-Xe") == 0) {
-+ preset |= LZMA_PRESET_EXTREME;
-+
-+ return 0;
-+ } else if(strcmp(argv[0], "-Xlc") == 0) {
-+ char *b;
-+ long val;
-+
-+ if(argc < 2) {
-+ fprintf(stderr, "xz: -Xlc missing value\n");
-+ goto failed;
-+ }
-+
-+ val = strtol(argv[1], &b, 10);
-+ if (*b != '\0' || (int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) {
-+ fprintf(stderr, "xz: -Xlc invalid value\n");
-+ goto failed;
-+ }
-+
-+ lc = (int) val;
-+
-+ return 1;
-+ } else if(strcmp(argv[0], "-Xlp") == 0) {
-+ char *b;
-+ long val;
-+
-+ if(argc < 2) {
-+ fprintf(stderr, "xz: -Xlp missing value\n");
-+ goto failed;
-+ }
-+
-+ val = strtol(argv[1], &b, 10);
-+ if (*b != '\0' || (int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) {
-+ fprintf(stderr, "xz: -Xlp invalid value\n");
-+ goto failed;
-+ }
-+
-+ lp = (int) val;
-+
-+ return 1;
-+ } else if(strcmp(argv[0], "-Xpb") == 0) {
-+ char *b;
-+ long val;
-+
-+ if(argc < 2) {
-+ fprintf(stderr, "xz: -Xpb missing value\n");
-+ goto failed;
-+ }
-+
-+ val = strtol(argv[1], &b, 10);
-+ if (*b != '\0' || (int) val < LZMA_PB_MIN || (int) val > LZMA_PB_MAX) {
-+ fprintf(stderr, "xz: -Xpb invalid value\n");
-+ goto failed;
-+ }
-+
-+ pb = (int) val;
-+
-+ return 1;
- }
-
- return -1;
-@@ -446,11 +533,20 @@ static int xz_compress(void *strm, void
- for(i = 0; i < stream->filters; i++) {
- struct filter *filter = &stream->filter[i];
-
-- if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT))
-- goto failed;
-+ if(lzma_lzma_preset(&stream->opt, preset))
-+ goto failed;
-
- stream->opt.dict_size = stream->dictionary_size;
-
-+ if (lc >= 0)
-+ stream->opt.lc = lc;
-+
-+ if (lp >= 0)
-+ stream->opt.lp = lp;
-+
-+ if (pb >= 0)
-+ stream->opt.pb = pb;
-+
- filter->length = 0;
- res = lzma_stream_buffer_encode(filter->filter,
- LZMA_CHECK_CRC32, NULL, src, size, filter->buffer,
-@@ -521,13 +617,28 @@ static void xz_usage(FILE *stream)
- fprintf(stream, " header as either 2^n or as 2^n+2^(n+1).\n\t\t");
- fprintf(stream, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or");
- fprintf(stream, " 32K, 16K, 8K\n\t\tetc.\n");
-+ fprintf(stream, "\t -Xpreset <preset-level>\n");
-+ fprintf(stream, "\t\tUse <preset-value> as the custom preset to use");
-+ fprintf(stream, " on compress.\n\t\t<preset-level> should be 0 .. 9");
-+ fprintf(stream, " (default 6)\n");
-+ fprintf(stream, "\t -Xe\n");
-+ fprintf(stream, "\t\tEnable additional compression settings by passing");
-+ fprintf(stream, " the EXTREME\n\t\tflag to the compression flags.\n");
-+ fprintf(stream, "\t -Xlc <value>\n");
-+ fprintf(stream, "\t -Xlp <value>\n");
-+ fprintf(stream, "\t -Xpb <value>\n");
- }
-
-
- static int option_args(char *option)
- {
- if(strcmp(option, "-Xbcj") == 0 ||
-- strcmp(option, "-Xdict-size") == 0)
-+ strcmp(option, "-Xdict-size") == 0 ||
-+ strcmp(option, "-Xpreset") == 0 ||
-+ strcmp(option, "-Xe") == 0 ||
-+ strcmp(option, "-Xlc") == 0 ||
-+ strcmp(option, "-Xlp") == 0 ||
-+ strcmp(option, "-Xpb") == 0)
- return 1;
-
- return 0;
diff --git a/tools/squashfs4/patches/002-xz_wrapper-make-new-OpenWrt-extended-options-non-def.patch b/tools/squashfs4/patches/002-xz_wrapper-make-new-OpenWrt-extended-options-non-def.patch
deleted file mode 100644
index 92b6a1aa91..0000000000
--- a/tools/squashfs4/patches/002-xz_wrapper-make-new-OpenWrt-extended-options-non-def.patch
+++ /dev/null
@@ -1,898 +0,0 @@
-From 5fb9fdfb8757fc9afb6318a3dcf9dce0a97de352 Mon Sep 17 00:00:00 2001
-From: Phillip Lougher <phillip@squashfs.org.uk>
-Date: Wed, 19 Apr 2023 18:35:53 +0100
-Subject: [PATCH] xz_wrapper: make new OpenWrt extended options non-default
-
-The reason why these options are being made non-default are
-described here:
-
-https://github.com/plougher/squashfs-tools/pull/218#issuecomment-1515197256
-
-The new options can be enabled by editing the Makefile or by defining
-XZ_EXTENDED_OPTIONS on the Make command line, e.g.
-
-% CONFIG=1 XZ_SUPPORT=1 XZ_EXTENDED_OPTIONS=1 make
-
-Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
----
- squashfs-tools/Makefile | 12 +
- squashfs-tools/xz_wrapper.c | 117 +----
- squashfs-tools/xz_wrapper_extended.c | 664 +++++++++++++++++++++++++++
- 3 files changed, 679 insertions(+), 114 deletions(-)
- create mode 100644 squashfs-tools/xz_wrapper_extended.c
-
---- a/squashfs-tools/Makefile
-+++ b/squashfs-tools/Makefile
-@@ -39,6 +39,10 @@ GZIP_SUPPORT = 1
- #
- #XZ_SUPPORT = 1
-
-+# Enable support for OpenWrt extended compression options by uncommenting
-+# next line. Do not do this unless you understand the implications.
-+#XZ_EXTENDED_OPTIONS = 1
-+
-
- ############ Building LZO support ##############
- #
-@@ -197,6 +201,7 @@ INSTALL_MANPAGES_DIR ?= $(INSTALL_PREFIX
- LZMA_XZ_SUPPORT ?= 0
- LZMA_SUPPORT ?= 0
- LZMA_DIR ?= ../../../../LZMA/lzma465
-+XZ_EXTENDED_OPTIONS ?= 0
- endif
-
-
-@@ -248,8 +253,13 @@ endif
-
- ifeq ($(XZ_SUPPORT),1)
- CFLAGS += -DXZ_SUPPORT
-+ifeq ($(XZ_EXTENDED_OPTIONS),1)
-+MKSQUASHFS_OBJS += xz_wrapper_extended.o
-+UNSQUASHFS_OBJS += xz_wrapper_extended.o
-+else
- MKSQUASHFS_OBJS += xz_wrapper.o
- UNSQUASHFS_OBJS += xz_wrapper.o
-+endif
- LIBS += -llzma
- COMPRESSORS += xz
- endif
-@@ -428,6 +438,8 @@ lz4_wrapper.o: lz4_wrapper.c squashfs_fs
-
- xz_wrapper.o: xz_wrapper.c squashfs_fs.h xz_wrapper.h compressor.h
-
-+xz_wrapper_extended.o: xz_wrapper_extended.c squashfs_fs.h xz_wrapper.h compressor.h
-+
- unsquashfs: $(UNSQUASHFS_OBJS)
- $(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) $(UNSQUASHFS_OBJS) $(LIBS) -o $@
- ln -sf unsquashfs sqfscat
---- a/squashfs-tools/xz_wrapper.c
-+++ b/squashfs-tools/xz_wrapper.c
-@@ -44,10 +44,7 @@ static struct bcj bcj[] = {
- static int filter_count = 1;
- static int dictionary_size = 0;
- static float dictionary_percent = 0;
--static int preset = LZMA_PRESET_DEFAULT;
--static int lc = -1;
--static int lp = -1;
--static int pb = -1;
-+
-
- /*
- * This function is called by the options parsing code in mksquashfs.c
-@@ -56,11 +53,6 @@ static int pb = -1;
- * Two specific options are supported:
- * -Xbcj
- * -Xdict-size
-- * -Xpreset
-- * -Xe
-- * -Xlc
-- * -Xlp
-- * -Xpb
- *
- * This function returns:
- * >=0 (number of additional args parsed) on success
-@@ -149,85 +141,6 @@ static int xz_options(char *argv[], int
- }
-
- return 1;
-- } else if(strcmp(argv[0], "-Xpreset") == 0) {
-- char *b;
-- long val;
--
-- if(argc < 2) {
-- fprintf(stderr, "xz: -Xpreset missing preset-level "
-- "(valid value 0-9)\n");
-- goto failed;
-- }
--
-- val = strtol(argv[1], &b, 10);
-- if (*b != '\0' || (int) val < 0 || (int) val & ~LZMA_PRESET_LEVEL_MASK) {
-- fprintf(stderr, "xz: -Xpreset can't be "
-- "negative or more than the max preset\n");
-- goto failed;
-- }
--
-- preset &= ~LZMA_PRESET_LEVEL_MASK;
-- preset |= (int) val;
--
-- return 1;
-- } else if(strcmp(argv[0], "-Xe") == 0) {
-- preset |= LZMA_PRESET_EXTREME;
--
-- return 0;
-- } else if(strcmp(argv[0], "-Xlc") == 0) {
-- char *b;
-- long val;
--
-- if(argc < 2) {
-- fprintf(stderr, "xz: -Xlc missing value\n");
-- goto failed;
-- }
--
-- val = strtol(argv[1], &b, 10);
-- if (*b != '\0' || (int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) {
-- fprintf(stderr, "xz: -Xlc invalid value\n");
-- goto failed;
-- }
--
-- lc = (int) val;
--
-- return 1;
-- } else if(strcmp(argv[0], "-Xlp") == 0) {
-- char *b;
-- long val;
--
-- if(argc < 2) {
-- fprintf(stderr, "xz: -Xlp missing value\n");
-- goto failed;
-- }
--
-- val = strtol(argv[1], &b, 10);
-- if (*b != '\0' || (int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) {
-- fprintf(stderr, "xz: -Xlp invalid value\n");
-- goto failed;
-- }
--
-- lp = (int) val;
--
-- return 1;
-- } else if(strcmp(argv[0], "-Xpb") == 0) {
-- char *b;
-- long val;
--
-- if(argc < 2) {
-- fprintf(stderr, "xz: -Xpb missing value\n");
-- goto failed;
-- }
--
-- val = strtol(argv[1], &b, 10);
-- if (*b != '\0' || (int) val < LZMA_PB_MIN || (int) val > LZMA_PB_MAX) {
-- fprintf(stderr, "xz: -Xpb invalid value\n");
-- goto failed;
-- }
--
-- pb = (int) val;
--
-- return 1;
- }
-
- return -1;
-@@ -533,20 +446,11 @@ static int xz_compress(void *strm, void
- for(i = 0; i < stream->filters; i++) {
- struct filter *filter = &stream->filter[i];
-
-- if(lzma_lzma_preset(&stream->opt, preset))
-+ if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT))
- goto failed;
-
- stream->opt.dict_size = stream->dictionary_size;
-
-- if (lc >= 0)
-- stream->opt.lc = lc;
--
-- if (lp >= 0)
-- stream->opt.lp = lp;
--
-- if (pb >= 0)
-- stream->opt.pb = pb;
--
- filter->length = 0;
- res = lzma_stream_buffer_encode(filter->filter,
- LZMA_CHECK_CRC32, NULL, src, size, filter->buffer,
-@@ -617,28 +521,13 @@ static void xz_usage(FILE *stream)
- fprintf(stream, " header as either 2^n or as 2^n+2^(n+1).\n\t\t");
- fprintf(stream, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or");
- fprintf(stream, " 32K, 16K, 8K\n\t\tetc.\n");
-- fprintf(stream, "\t -Xpreset <preset-level>\n");
-- fprintf(stream, "\t\tUse <preset-value> as the custom preset to use");
-- fprintf(stream, " on compress.\n\t\t<preset-level> should be 0 .. 9");
-- fprintf(stream, " (default 6)\n");
-- fprintf(stream, "\t -Xe\n");
-- fprintf(stream, "\t\tEnable additional compression settings by passing");
-- fprintf(stream, " the EXTREME\n\t\tflag to the compression flags.\n");
-- fprintf(stream, "\t -Xlc <value>\n");
-- fprintf(stream, "\t -Xlp <value>\n");
-- fprintf(stream, "\t -Xpb <value>\n");
- }
-
-
- static int option_args(char *option)
- {
- if(strcmp(option, "-Xbcj") == 0 ||
-- strcmp(option, "-Xdict-size") == 0 ||
-- strcmp(option, "-Xpreset") == 0 ||
-- strcmp(option, "-Xe") == 0 ||
-- strcmp(option, "-Xlc") == 0 ||
-- strcmp(option, "-Xlp") == 0 ||
-- strcmp(option, "-Xpb") == 0)
-+ strcmp(option, "-Xdict-size") == 0)
- return 1;
-
- return 0;
---- /dev/null
-+++ b/squashfs-tools/xz_wrapper_extended.c
-@@ -0,0 +1,664 @@
-+/*
-+ * Copyright (c) 2010, 2011, 2012, 2013, 2021, 2022
-+ * Phillip Lougher <phillip@squashfs.org.uk>
-+ *
-+ * This program 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 2,
-+ * or (at your option) any later version.
-+ *
-+ * This program 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 this program; if not, write to the Free Software
-+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * xz_wrapper_extended.c
-+ *
-+ * Support for XZ (LZMA2) compression using XZ Utils liblzma
-+ * http://tukaani.org/xz/
-+ *
-+ * This file supports OpenWrt extended XZ compression options.
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <lzma.h>
-+
-+#include "squashfs_fs.h"
-+#include "xz_wrapper.h"
-+#include "compressor.h"
-+
-+static struct bcj bcj[] = {
-+ { "x86", LZMA_FILTER_X86, 0 },
-+ { "powerpc", LZMA_FILTER_POWERPC, 0 },
-+ { "ia64", LZMA_FILTER_IA64, 0 },
-+ { "arm", LZMA_FILTER_ARM, 0 },
-+ { "armthumb", LZMA_FILTER_ARMTHUMB, 0 },
-+ { "sparc", LZMA_FILTER_SPARC, 0 },
-+ { NULL, LZMA_VLI_UNKNOWN, 0 }
-+};
-+
-+static int filter_count = 1;
-+static int dictionary_size = 0;
-+static float dictionary_percent = 0;
-+static int preset = LZMA_PRESET_DEFAULT;
-+static int lc = -1;
-+static int lp = -1;
-+static int pb = -1;
-+
-+/*
-+ * This function is called by the options parsing code in mksquashfs.c
-+ * to parse any -X compressor option.
-+ *
-+ * Two specific options are supported:
-+ * -Xbcj
-+ * -Xdict-size
-+ * -Xpreset
-+ * -Xe
-+ * -Xlc
-+ * -Xlp
-+ * -Xpb
-+ *
-+ * This function returns:
-+ * >=0 (number of additional args parsed) on success
-+ * -1 if the option was unrecognised, or
-+ * -2 if the option was recognised, but otherwise bad in
-+ * some way (e.g. invalid parameter)
-+ *
-+ * Note: this function sets internal compressor state, but does not
-+ * pass back the results of the parsing other than success/failure.
-+ * The xz_dump_options() function is called later to get the options in
-+ * a format suitable for writing to the filesystem.
-+ */
-+static int xz_options(char *argv[], int argc)
-+{
-+ int i;
-+ char *name;
-+
-+ if(strcmp(argv[0], "-Xbcj") == 0) {
-+ if(argc < 2) {
-+ fprintf(stderr, "xz: -Xbcj missing filter\n");
-+ goto failed;
-+ }
-+
-+ name = argv[1];
-+ while(name[0] != '\0') {
-+ for(i = 0; bcj[i].name; i++) {
-+ int n = strlen(bcj[i].name);
-+ if((strncmp(name, bcj[i].name, n) == 0) &&
-+ (name[n] == '\0' ||
-+ name[n] == ',')) {
-+ if(bcj[i].selected == 0) {
-+ bcj[i].selected = 1;
-+ filter_count++;
-+ }
-+ name += name[n] == ',' ? n + 1 : n;
-+ break;
-+ }
-+ }
-+ if(bcj[i].name == NULL) {
-+ fprintf(stderr, "xz: -Xbcj unrecognised "
-+ "filter\n");
-+ goto failed;
-+ }
-+ }
-+
-+ return 1;
-+ } else if(strcmp(argv[0], "-Xdict-size") == 0) {
-+ char *b;
-+ float size;
-+
-+ if(argc < 2) {
-+ fprintf(stderr, "xz: -Xdict-size missing dict-size\n");
-+ goto failed;
-+ }
-+
-+ size = strtof(argv[1], &b);
-+ if(*b == '%') {
-+ if(size <= 0 || size > 100) {
-+ fprintf(stderr, "xz: -Xdict-size percentage "
-+ "should be 0 < dict-size <= 100\n");
-+ goto failed;
-+ }
-+
-+ dictionary_percent = size;
-+ dictionary_size = 0;
-+ } else {
-+ if((float) ((int) size) != size) {
-+ fprintf(stderr, "xz: -Xdict-size can't be "
-+ "fractional unless a percentage of the"
-+ " block size\n");
-+ goto failed;
-+ }
-+
-+ dictionary_percent = 0;
-+ dictionary_size = (int) size;
-+
-+ if(*b == 'k' || *b == 'K')
-+ dictionary_size *= 1024;
-+ else if(*b == 'm' || *b == 'M')
-+ dictionary_size *= 1024 * 1024;
-+ else if(*b != '\0') {
-+ fprintf(stderr, "xz: -Xdict-size invalid "
-+ "dict-size\n");
-+ goto failed;
-+ }
-+ }
-+
-+ return 1;
-+ } else if(strcmp(argv[0], "-Xpreset") == 0) {
-+ char *b;
-+ long val;
-+
-+ if(argc < 2) {
-+ fprintf(stderr, "xz: -Xpreset missing preset-level "
-+ "(valid value 0-9)\n");
-+ goto failed;
-+ }
-+
-+ val = strtol(argv[1], &b, 10);
-+ if (*b != '\0' || (int) val < 0 || (int) val & ~LZMA_PRESET_LEVEL_MASK) {
-+ fprintf(stderr, "xz: -Xpreset can't be "
-+ "negative or more than the max preset\n");
-+ goto failed;
-+ }
-+
-+ preset &= ~LZMA_PRESET_LEVEL_MASK;
-+ preset |= (int) val;
-+
-+ return 1;
-+ } else if(strcmp(argv[0], "-Xe") == 0) {
-+ preset |= LZMA_PRESET_EXTREME;
-+
-+ return 0;
-+ } else if(strcmp(argv[0], "-Xlc") == 0) {
-+ char *b;
-+ long val;
-+
-+ if(argc < 2) {
-+ fprintf(stderr, "xz: -Xlc missing value\n");
-+ goto failed;
-+ }
-+
-+ val = strtol(argv[1], &b, 10);
-+ if (*b != '\0' || (int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) {
-+ fprintf(stderr, "xz: -Xlc invalid value\n");
-+ goto failed;
-+ }
-+
-+ lc = (int) val;
-+
-+ return 1;
-+ } else if(strcmp(argv[0], "-Xlp") == 0) {
-+ char *b;
-+ long val;
-+
-+ if(argc < 2) {
-+ fprintf(stderr, "xz: -Xlp missing value\n");
-+ goto failed;
-+ }
-+
-+ val = strtol(argv[1], &b, 10);
-+ if (*b != '\0' || (int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) {
-+ fprintf(stderr, "xz: -Xlp invalid value\n");
-+ goto failed;
-+ }
-+
-+ lp = (int) val;
-+
-+ return 1;
-+ } else if(strcmp(argv[0], "-Xpb") == 0) {
-+ char *b;
-+ long val;
-+
-+ if(argc < 2) {
-+ fprintf(stderr, "xz: -Xpb missing value\n");
-+ goto failed;
-+ }
-+
-+ val = strtol(argv[1], &b, 10);
-+ if (*b != '\0' || (int) val < LZMA_PB_MIN || (int) val > LZMA_PB_MAX) {
-+ fprintf(stderr, "xz: -Xpb invalid value\n");
-+ goto failed;
-+ }
-+
-+ pb = (int) val;
-+
-+ return 1;
-+ }
-+
-+ return -1;
-+
-+failed:
-+ return -2;
-+}
-+
-+
-+/*
-+ * This function is called after all options have been parsed.
-+ * It is used to do post-processing on the compressor options using
-+ * values that were not expected to be known at option parse time.
-+ *
-+ * In this case block_size may not be known until after -Xdict-size has
-+ * been processed (in the case where -b is specified after -Xdict-size)
-+ *
-+ * This function returns 0 on successful post processing, or
-+ * -1 on error
-+ */
-+static int xz_options_post(int block_size)
-+{
-+ /*
-+ * if -Xdict-size has been specified use this to compute the datablock
-+ * dictionary size
-+ */
-+ if(dictionary_size || dictionary_percent) {
-+ int n;
-+
-+ if(dictionary_size) {
-+ if(dictionary_size > block_size) {
-+ fprintf(stderr, "xz: -Xdict-size is larger than"
-+ " block_size\n");
-+ goto failed;
-+ }
-+ } else
-+ dictionary_size = block_size * dictionary_percent / 100;
-+
-+ if(dictionary_size < 8192) {
-+ fprintf(stderr, "xz: -Xdict-size should be 8192 bytes "
-+ "or larger\n");
-+ goto failed;
-+ }
-+
-+ /*
-+ * dictionary_size must be storable in xz header as either
-+ * 2^n or as 2^n+2^(n+1)
-+ */
-+ n = ffs(dictionary_size) - 1;
-+ if(dictionary_size != (1 << n) &&
-+ dictionary_size != ((1 << n) + (1 << (n + 1)))) {
-+ fprintf(stderr, "xz: -Xdict-size is an unsupported "
-+ "value, dict-size must be storable in xz "
-+ "header\n");
-+ fprintf(stderr, "as either 2^n or as 2^n+2^(n+1). "
-+ "Example dict-sizes are 75%%, 50%%, 37.5%%, "
-+ "25%%,\n");
-+ fprintf(stderr, "or 32K, 16K, 8K etc.\n");
-+ goto failed;
-+ }
-+
-+ } else
-+ /* No -Xdict-size specified, use defaults */
-+ dictionary_size = block_size;
-+
-+ return 0;
-+
-+failed:
-+ return -1;
-+}
-+
-+
-+/*
-+ * This function is called by mksquashfs to dump the parsed
-+ * compressor options in a format suitable for writing to the
-+ * compressor options field in the filesystem (stored immediately
-+ * after the superblock).
-+ *
-+ * This function returns a pointer to the compression options structure
-+ * to be stored (and the size), or NULL if there are no compression
-+ * options
-+ */
-+static void *xz_dump_options(int block_size, int *size)
-+{
-+ static struct comp_opts comp_opts;
-+ int flags = 0, i;
-+
-+ /*
-+ * don't store compressor specific options in file system if the
-+ * default options are being used - no compressor options in the
-+ * file system means the default options are always assumed
-+ *
-+ * Defaults are:
-+ * metadata dictionary size: SQUASHFS_METADATA_SIZE
-+ * datablock dictionary size: block_size
-+ * 1 filter
-+ */
-+ if(dictionary_size == block_size && filter_count == 1)
-+ return NULL;
-+
-+ for(i = 0; bcj[i].name; i++)
-+ flags |= bcj[i].selected << i;
-+
-+ comp_opts.dictionary_size = dictionary_size;
-+ comp_opts.flags = flags;
-+
-+ SQUASHFS_INSWAP_COMP_OPTS(&comp_opts);
-+
-+ *size = sizeof(comp_opts);
-+ return &comp_opts;
-+}
-+
-+
-+/*
-+ * This function is a helper specifically for the append mode of
-+ * mksquashfs. Its purpose is to set the internal compressor state
-+ * to the stored compressor options in the passed compressor options
-+ * structure.
-+ *
-+ * In effect this function sets up the compressor options
-+ * to the same state they were when the filesystem was originally
-+ * generated, this is to ensure on appending, the compressor uses
-+ * the same compression options that were used to generate the
-+ * original filesystem.
-+ *
-+ * Note, even if there are no compressor options, this function is still
-+ * called with an empty compressor structure (size == 0), to explicitly
-+ * set the default options, this is to ensure any user supplied
-+ * -X options on the appending mksquashfs command line are over-ridden
-+ *
-+ * This function returns 0 on sucessful extraction of options, and
-+ * -1 on error
-+ */
-+static int xz_extract_options(int block_size, void *buffer, int size)
-+{
-+ struct comp_opts *comp_opts = buffer;
-+ int flags, i, n;
-+
-+ if(size == 0) {
-+ /* set defaults */
-+ dictionary_size = block_size;
-+ flags = 0;
-+ } else {
-+ /* check passed comp opts struct is of the correct length */
-+ if(size != sizeof(struct comp_opts))
-+ goto failed;
-+
-+ SQUASHFS_INSWAP_COMP_OPTS(comp_opts);
-+
-+ dictionary_size = comp_opts->dictionary_size;
-+ flags = comp_opts->flags;
-+
-+ /*
-+ * check that the dictionary size seems correct - the dictionary
-+ * size should 2^n or 2^n+2^(n+1)
-+ */
-+ n = ffs(dictionary_size) - 1;
-+ if(dictionary_size != (1 << n) &&
-+ dictionary_size != ((1 << n) + (1 << (n + 1))))
-+ goto failed;
-+ }
-+
-+ filter_count = 1;
-+ for(i = 0; bcj[i].name; i++) {
-+ if((flags >> i) & 1) {
-+ bcj[i].selected = 1;
-+ filter_count ++;
-+ } else
-+ bcj[i].selected = 0;
-+ }
-+
-+ return 0;
-+
-+failed:
-+ fprintf(stderr, "xz: error reading stored compressor options from "
-+ "filesystem!\n");
-+
-+ return -1;
-+}
-+
-+
-+static void xz_display_options(void *buffer, int size)
-+{
-+ struct comp_opts *comp_opts = buffer;
-+ int dictionary_size, flags, printed;
-+ int i, n;
-+
-+ /* check passed comp opts struct is of the correct length */
-+ if(size != sizeof(struct comp_opts))
-+ goto failed;
-+
-+ SQUASHFS_INSWAP_COMP_OPTS(comp_opts);
-+
-+ dictionary_size = comp_opts->dictionary_size;
-+ flags = comp_opts->flags;
-+
-+ /*
-+ * check that the dictionary size seems correct - the dictionary
-+ * size should 2^n or 2^n+2^(n+1)
-+ */
-+ n = ffs(dictionary_size) - 1;
-+ if(dictionary_size != (1 << n) &&
-+ dictionary_size != ((1 << n) + (1 << (n + 1))))
-+ goto failed;
-+
-+ printf("\tDictionary size %d\n", dictionary_size);
-+
-+ printed = 0;
-+ for(i = 0; bcj[i].name; i++) {
-+ if((flags >> i) & 1) {
-+ if(printed)
-+ printf(", ");
-+ else
-+ printf("\tFilters selected: ");
-+ printf("%s", bcj[i].name);
-+ printed = 1;
-+ }
-+ }
-+
-+ if(!printed)
-+ printf("\tNo filters specified\n");
-+ else
-+ printf("\n");
-+
-+ return;
-+
-+failed:
-+ fprintf(stderr, "xz: error reading stored compressor options from "
-+ "filesystem!\n");
-+}
-+
-+
-+/*
-+ * This function is called by mksquashfs to initialise the
-+ * compressor, before compress() is called.
-+ *
-+ * This function returns 0 on success, and
-+ * -1 on error
-+ */
-+static int xz_init(void **strm, int block_size, int datablock)
-+{
-+ int i, j, filters = datablock ? filter_count : 1;
-+ struct filter *filter = malloc(filters * sizeof(struct filter));
-+ struct xz_stream *stream;
-+
-+ if(filter == NULL)
-+ goto failed;
-+
-+ stream = *strm = malloc(sizeof(struct xz_stream));
-+ if(stream == NULL)
-+ goto failed2;
-+
-+ stream->filter = filter;
-+ stream->filters = filters;
-+
-+ memset(filter, 0, filters * sizeof(struct filter));
-+
-+ stream->dictionary_size = datablock ? dictionary_size :
-+ SQUASHFS_METADATA_SIZE;
-+
-+ filter[0].filter[0].id = LZMA_FILTER_LZMA2;
-+ filter[0].filter[0].options = &stream->opt;
-+ filter[0].filter[1].id = LZMA_VLI_UNKNOWN;
-+
-+ for(i = 0, j = 1; datablock && bcj[i].name; i++) {
-+ if(bcj[i].selected) {
-+ filter[j].buffer = malloc(block_size);
-+ if(filter[j].buffer == NULL)
-+ goto failed3;
-+ filter[j].filter[0].id = bcj[i].id;
-+ filter[j].filter[1].id = LZMA_FILTER_LZMA2;
-+ filter[j].filter[1].options = &stream->opt;
-+ filter[j].filter[2].id = LZMA_VLI_UNKNOWN;
-+ j++;
-+ }
-+ }
-+
-+ return 0;
-+
-+failed3:
-+ for(i = 1; i < filters; i++)
-+ free(filter[i].buffer);
-+ free(stream);
-+
-+failed2:
-+ free(filter);
-+
-+failed:
-+ return -1;
-+}
-+
-+
-+static int xz_compress(void *strm, void *dest, void *src, int size,
-+ int block_size, int *error)
-+{
-+ int i;
-+ lzma_ret res = 0;
-+ struct xz_stream *stream = strm;
-+ struct filter *selected = NULL;
-+
-+ stream->filter[0].buffer = dest;
-+
-+ for(i = 0; i < stream->filters; i++) {
-+ struct filter *filter = &stream->filter[i];
-+
-+ if(lzma_lzma_preset(&stream->opt, preset))
-+ goto failed;
-+
-+ stream->opt.dict_size = stream->dictionary_size;
-+
-+ if (lc >= 0)
-+ stream->opt.lc = lc;
-+
-+ if (lp >= 0)
-+ stream->opt.lp = lp;
-+
-+ if (pb >= 0)
-+ stream->opt.pb = pb;
-+
-+ filter->length = 0;
-+ res = lzma_stream_buffer_encode(filter->filter,
-+ LZMA_CHECK_CRC32, NULL, src, size, filter->buffer,
-+ &filter->length, block_size);
-+
-+ if(res == LZMA_OK) {
-+ if(!selected || selected->length > filter->length)
-+ selected = filter;
-+ } else if(res != LZMA_BUF_ERROR)
-+ goto failed;
-+ }
-+
-+ if(!selected)
-+ /*
-+ * Output buffer overflow. Return out of buffer space
-+ */
-+ return 0;
-+
-+ if(selected->buffer != dest)
-+ memcpy(dest, selected->buffer, selected->length);
-+
-+ return (int) selected->length;
-+
-+failed:
-+ /*
-+ * All other errors return failure, with the compressor
-+ * specific error code in *error
-+ */
-+ *error = res;
-+ return -1;
-+}
-+
-+
-+static int xz_uncompress(void *dest, void *src, int size, int outsize,
-+ int *error)
-+{
-+ size_t src_pos = 0;
-+ size_t dest_pos = 0;
-+ uint64_t memlimit = MEMLIMIT;
-+
-+ lzma_ret res = lzma_stream_buffer_decode(&memlimit, 0, NULL,
-+ src, &src_pos, size, dest, &dest_pos, outsize);
-+
-+ if(res == LZMA_OK && size == (int) src_pos)
-+ return (int) dest_pos;
-+ else {
-+ *error = res;
-+ return -1;
-+ }
-+}
-+
-+
-+static void xz_usage(FILE *stream)
-+{
-+ fprintf(stream, "\t -Xbcj filter1,filter2,...,filterN\n");
-+ fprintf(stream, "\t\tCompress using filter1,filter2,...,filterN in");
-+ fprintf(stream, " turn\n\t\t(in addition to no filter), and choose");
-+ fprintf(stream, " the best compression.\n");
-+ fprintf(stream, "\t\tAvailable filters: x86, arm, armthumb,");
-+ fprintf(stream, " powerpc, sparc, ia64\n");
-+ fprintf(stream, "\t -Xdict-size <dict-size>\n");
-+ fprintf(stream, "\t\tUse <dict-size> as the XZ dictionary size. The");
-+ fprintf(stream, " dictionary size\n\t\tcan be specified as a");
-+ fprintf(stream, " percentage of the block size, or as an\n\t\t");
-+ fprintf(stream, "absolute value. The dictionary size must be less");
-+ fprintf(stream, " than or equal\n\t\tto the block size and 8192 bytes");
-+ fprintf(stream, " or larger. It must also be\n\t\tstorable in the xz");
-+ fprintf(stream, " header as either 2^n or as 2^n+2^(n+1).\n\t\t");
-+ fprintf(stream, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or");
-+ fprintf(stream, " 32K, 16K, 8K\n\t\tetc.\n");
-+ fprintf(stream, "\t -Xpreset <preset-level>\n");
-+ fprintf(stream, "\t\tUse <preset-value> as the custom preset to use");
-+ fprintf(stream, " on compress.\n\t\t<preset-level> should be 0 .. 9");
-+ fprintf(stream, " (default 6)\n");
-+ fprintf(stream, "\t -Xe\n");
-+ fprintf(stream, "\t\tEnable additional compression settings by passing");
-+ fprintf(stream, " the EXTREME\n\t\tflag to the compression flags.\n");
-+ fprintf(stream, "\t -Xlc <value>\n");
-+ fprintf(stream, "\t -Xlp <value>\n");
-+ fprintf(stream, "\t -Xpb <value>\n");
-+}
-+
-+
-+static int option_args(char *option)
-+{
-+ if(strcmp(option, "-Xbcj") == 0 ||
-+ strcmp(option, "-Xdict-size") == 0 ||
-+ strcmp(option, "-Xpreset") == 0 ||
-+ strcmp(option, "-Xe") == 0 ||
-+ strcmp(option, "-Xlc") == 0 ||
-+ strcmp(option, "-Xlp") == 0 ||
-+ strcmp(option, "-Xpb") == 0)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+
-+struct compressor xz_comp_ops = {
-+ .init = xz_init,
-+ .compress = xz_compress,
-+ .uncompress = xz_uncompress,
-+ .options = xz_options,
-+ .options_post = xz_options_post,
-+ .dump_options = xz_dump_options,
-+ .extract_options = xz_extract_options,
-+ .display_options = xz_display_options,
-+ .usage = xz_usage,
-+ .option_args = option_args,
-+ .id = XZ_COMPRESSION,
-+ .name = "xz",
-+ .supported = 1
-+};
diff --git a/tools/tar/Makefile b/tools/tar/Makefile
index a05ffc4381..8bedb8eb13 100644
--- a/tools/tar/Makefile
+++ b/tools/tar/Makefile
@@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=tar
PKG_CPE_ID:=cpe:/a:gnu:tar
-PKG_VERSION:=1.34
+PKG_VERSION:=1.35
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/tar
-PKG_HASH:=03d908cf5768cfe6b7ad588c921c6ed21acabfb2b79b788d1330453507647aed
+PKG_HASH:=14d55e32063ea9526e057fbf35fcabd53378e769787eff7919c3755b02d2b57e
HOST_BUILD_PARALLEL:=1
diff --git a/tools/tar/patches/0001-Fix-savannah-bug-64441.patch b/tools/tar/patches/0001-Fix-savannah-bug-64441.patch
new file mode 100644
index 0000000000..1c10e5452c
--- /dev/null
+++ b/tools/tar/patches/0001-Fix-savannah-bug-64441.patch
@@ -0,0 +1,35 @@
+From 6bec1e7e7fe0ae5bbeb66fc9f32b0b1dd156957d Mon Sep 17 00:00:00 2001
+From: Sergey Poznyakoff <gray@gnu.org>
+Date: Tue, 18 Jun 2024 14:31:17 +0200
+Subject: [PATCH] Fix savannah bug #64441
+
+* src/Makefile.am (tar_LDADD): Add libiconv libraries.
+
+Adapted upstream commit 8632df398b2f548465ebe68b8f494c0d6f8d913d to patch
+the pregenerated Makefile.in instead of Makefile.am to avoid invoking
+automake which requires m4.
+
+This is required for macOS, as otherwise it will fail with:
+Undefined symbols for architecture arm64:
+ "_iconv", referenced from:
+ _utf8_convert in utf8.o
+ "_iconv_open", referenced from:
+ _utf8_convert in utf8.o
+ld: symbol(s) not found for architecture arm64
+clang: error: linker command failed with exit code 1 (use -v to see invocation)
+---
+ src/Makefile.in | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/src/Makefile.in
++++ b/src/Makefile.in
+@@ -1793,7 +1793,8 @@ AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLA
+ tar_LDADD = $(LIBS) ../lib/libtar.a ../gnu/libgnu.a\
+ $(LIB_ACL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS)\
+ $(LIB_GETRANDOM) $(LIB_HARD_LOCALE) $(FILE_HAS_ACL_LIB) $(LIB_MBRTOWC)\
+- $(LIB_SELINUX) $(LIB_SETLOCALE_NULL)
++ $(LIB_SELINUX) $(LIB_SETLOCALE_NULL) \
++ $(LIBINTL) $(LIBICONV)
+
+ all: all-am
+
diff --git a/tools/tar/patches/100-symlink-force-root-name.patch b/tools/tar/patches/100-symlink-force-root-name.patch
index 8a8ebc0c4c..93f889761b 100644
--- a/tools/tar/patches/100-symlink-force-root-name.patch
+++ b/tools/tar/patches/100-symlink-force-root-name.patch
@@ -5,7 +5,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/src/create.c
+++ b/src/create.c
-@@ -543,17 +543,8 @@ write_gnu_long_link (struct tar_stat_inf
+@@ -544,17 +544,8 @@ write_gnu_long_link (struct tar_stat_inf
union block *header;
header = start_private_header ("././@LongLink", size, 0);
diff --git a/tools/tar/patches/110-symlink-force-permissions.patch b/tools/tar/patches/110-symlink-force-permissions.patch
index 4a80de6ef0..ec64afe7f4 100644
--- a/tools/tar/patches/110-symlink-force-permissions.patch
+++ b/tools/tar/patches/110-symlink-force-permissions.patch
@@ -1,6 +1,6 @@
--- a/src/create.c
+++ b/src/create.c
-@@ -1844,6 +1844,7 @@ dump_file0 (struct tar_stat_info *st, ch
+@@ -1855,6 +1855,7 @@ dump_file0 (struct tar_stat_info *st, ch
#ifdef HAVE_READLINK
else if (S_ISLNK (st->stat.st_mode))
{
diff --git a/tools/util-linux/Makefile b/tools/util-linux/Makefile
index 846005ebe9..c9a4bbc34f 100644
--- a/tools/util-linux/Makefile
+++ b/tools/util-linux/Makefile
@@ -7,126 +7,22 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=util-linux
-PKG_VERSION:=2.39.3
+PKG_VERSION:=2.41.1
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=@KERNEL/linux/utils/$(PKG_NAME)/v2.39
-PKG_HASH:=40ea07584d56c310455471afa92c119ec259776a561af7159cc802344c2c370d
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@KERNEL/linux/utils/$(PKG_NAME)/v2.41
+PKG_HASH:=be9ad9a276f4305ab7dd2f5225c8be1ff54352f565ff4dede9628c1aaa7dec57
PKG_CPE_ID:=cpe:/a:kernel:util-linux
-HOST_BUILD_PARALLEL:=1
-
include $(INCLUDE_DIR)/host-build.mk
-
-HOST_CONFIGURE_ARGS += \
- --disable-poman \
- --disable-nls \
- --disable-asciidoc \
- --disable-poman \
- --disable-libuuid \
- --disable-libblkid \
- --disable-libmount \
- --disable-libsmartcols \
- --disable-libfdisk \
- --disable-fdisks \
- --disable-mount \
- --disable-losetup \
- --disable-zramctl \
- --disable-fsck \
- --disable-partx \
- --disable-uuidd \
- --disable-uuidgen \
- --disable-blkid \
- --disable-wipefs \
- --disable-mountpoint \
- --disable-fallocate \
- --disable-unshare \
- --disable-nsenter \
- --disable-setpriv \
- --disable-hardlink \
- --disable-eject \
- --disable-agetty \
- --disable-cramfs \
- --disable-bfs \
- --disable-minix \
- --disable-hwclock \
- --disable-mkfs \
- --disable-fstrim \
- --disable-swapon \
- --disable-lscpu \
- --disable-lsfd \
- --disable-lslogins \
- --disable-wdctl \
- --disable-cal \
- --disable-logger \
- --disable-whereis \
- --disable-pipesz \
- --disable-waitpid \
- --disable-switch_root \
- --disable-pivot_root \
- --disable-lsmem \
- --disable-chmem \
- --disable-ipcmk \
- --disable-ipcrm \
- --disable-ipcs \
- --disable-irqtop \
- --disable-lsirq \
- --disable-lsns \
- --disable-rfkill \
- --disable-scriptutils \
- --disable-tunelp \
- --disable-kill \
- --disable-last \
- --disable-utmpdump \
- --disable-line \
- --disable-mesg \
- --disable-raw \
- --disable-rename \
- --disable-vipw \
- --disable-newgrp \
- --disable-chfn-chsh \
- --disable-login \
- --disable-nologin \
- --disable-sulogin \
- --disable-su \
- --disable-runuser \
- --disable-ul \
- --disable-more \
- --disable-pg \
- --disable-setterm \
- --disable-schedutils \
- --disable-wall \
- --disable-write \
- --disable-bash-completion \
- --disable-pylibmount \
- --disable-pg-bell \
- --without-util \
- --without-selinux \
- --without-audit \
- --without-udev \
- --without-ncursesw \
- --without-ncurses \
- --without-slang \
- --without-tinfo \
- --without-readline \
- --without-utempter \
- --without-cap-ng \
- --without-libz \
- --without-libmagic \
- --without-user \
- --without-btrfs \
- --without-systemd \
- --without-smack \
- --without-econf \
- --without-python \
- --without-cryptsetup
-
-define Host/Install
- $(INSTALL_BIN) $(HOST_BUILD_DIR)/hexdump $(STAGING_DIR_HOST)/bin/
-endef
-
-define Host/Uninstall
- rm -f $(STAGING_DIR_HOST)/bin/hexdump
-endef
+include $(INCLUDE_DIR)/meson.mk
+
+MESON_HOST_ARGS += \
+ $(if $(findstring y,$(YEAR_2038)),,-Dallow-32bit-time=true) \
+ -Dauto_features=disabled \
+ -Dbuild-hexdump=enabled \
+ -Dbuild-libuuid=enabled \
+ -Dncurses=enabled \
+ -Dprogram-tests=false
$(eval $(call HostBuild))
diff --git a/tools/util-linux/patches/010-meson-curses.patch b/tools/util-linux/patches/010-meson-curses.patch
new file mode 100644
index 0000000000..80c28eedbd
--- /dev/null
+++ b/tools/util-linux/patches/010-meson-curses.patch
@@ -0,0 +1,24 @@
+From c1ca5ec4a5c6a0e4acbdcc6ff4e4fa2109c1ec24 Mon Sep 17 00:00:00 2001
+From: Rosen Penev <rosenp@gmail.com>
+Date: Wed, 30 Jul 2025 14:13:07 -0700
+Subject: [PATCH] meson: use curses for the non wide version
+
+The curses dependency in meson in special in that it uses a combination
+of pkg-config, config-tool, and various system lookups to find it.
+
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+---
+ meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/meson.build
++++ b/meson.build
+@@ -289,7 +289,7 @@ if lib_ncursesw.found()
+ lib_ncurses = disabler()
+ else
+ lib_ncurses = dependency(
+- 'ncurses',
++ 'curses',
+ disabler : true,
+ required : get_option('ncurses'))
+ headers += ['ncurses.h',
diff --git a/tools/util-linux/patches/100-fix_include_order.patch b/tools/util-linux/patches/100-fix_include_order.patch
new file mode 100644
index 0000000000..c7e4311fc1
--- /dev/null
+++ b/tools/util-linux/patches/100-fix_include_order.patch
@@ -0,0 +1,12 @@
+--- a/libuuid/src/gen_uuid.c
++++ b/libuuid/src/gen_uuid.c
+@@ -86,8 +86,8 @@
+
+ #include <signal.h>
+
+-#include "all-io.h"
+ #include "uuidP.h"
++#include "all-io.h"
+ #include "uuidd.h"
+ #include "randutils.h"
+ #include "strutils.h"
diff --git a/tools/util-linux/patches/102-macos-uuid-next.patch b/tools/util-linux/patches/102-macos-uuid-next.patch
new file mode 100644
index 0000000000..36346fd522
--- /dev/null
+++ b/tools/util-linux/patches/102-macos-uuid-next.patch
@@ -0,0 +1,13 @@
+--- a/libuuid/src/uuid.h
++++ b/libuuid/src/uuid.h
+@@ -35,6 +35,10 @@
+ #ifndef _UL_LIBUUID_UUID_H
+ #define _UL_LIBUUID_UUID_H
+
++#if defined(__clang__) && defined(__APPLE__)
++#include_next <uuid/uuid.h>
++#endif
++
+ #include <sys/types.h>
+ #ifndef _WIN32
+ #include <sys/time.h>
diff --git a/tools/util-linux/patches/110-meson-fix-a-bug-in-posixipc_libs-configuration.patch b/tools/util-linux/patches/110-meson-fix-a-bug-in-posixipc_libs-configuration.patch
new file mode 100644
index 0000000000..a6ec1b83d0
--- /dev/null
+++ b/tools/util-linux/patches/110-meson-fix-a-bug-in-posixipc_libs-configuration.patch
@@ -0,0 +1,23 @@
+From 946c0b9c6f6481ed9370b8bd0f54a622a0c4a574 Mon Sep 17 00:00:00 2001
+From: Martin Valgur <martin.valgur@gmail.com>
+Date: Tue, 15 Apr 2025 16:19:21 +0300
+Subject: [PATCH] meson: fix a bug in posixipc_libs configuration
+
+Should append instead of assigning. Otherwise fails with
+
+meson.build:1482:22: ERROR: Object <[ExternalLibraryHolder] holds [ExternalLibrary]: <ExternalLibrary rt: True>> of type ExternalLibrary does not support the `+` operator.
+---
+ meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/meson.build
++++ b/meson.build
+@@ -1473,7 +1473,7 @@ has_seminfo_type = cc.has_type('struct s
+
+ posixipc_libs = []
+ if not cc.has_function('shm_open') and conf.get('HAVE_SYS_MMAN_H').to_string() == '1'
+- posixipc_libs = cc.find_library('rt', required : true)
++ posixipc_libs += cc.find_library('rt', required : true)
+ endif
+
+ if not cc.has_function('sem_close') and conf.get('HAVE_SEMAPHORE_H').to_string() == '1'
diff --git a/tools/xxhash/Makefile b/tools/xxhash/Makefile
new file mode 100644
index 0000000000..5d5754d63a
--- /dev/null
+++ b/tools/xxhash/Makefile
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=xxHash
+PKG_VERSION:=0.8.3
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=https://github.com/Cyan4973/xxHash
+PKG_SOURCE_VERSION:=e626a72bc2321cd320e953a0ccf1584cad60f363
+PKG_MIRROR_HASH:=234cfc24004c1b97d3ec9c48e976347b31a513a68de40f57a765667eb89dbbb0
+
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_C_COMPILER_LAUNCHER :=
+CMAKE_CXX_COMPILER_LAUNCHER :=
+
+CMAKE_BINARY_SUBDIR := build
+CMAKE_SOURCE_SUBDIR := cmake_unofficial
+
+$(eval $(call HostBuild))
diff --git a/tools/xz/Makefile b/tools/xz/Makefile
index a90cec86bf..a370408ca0 100644
--- a/tools/xz/Makefile
+++ b/tools/xz/Makefile
@@ -7,12 +7,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=xz
-PKG_VERSION:=5.4.6
+PKG_VERSION:=5.8.1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=@SF/lzmautils \
+PKG_SOURCE_URL:=https://github.com/tukaani-project/xz/releases/download/v$(PKG_VERSION) \
+ @SF/lzmautils \
http://tukaani.org/xz
-PKG_HASH:=913851b274e8e1d31781ec949f1c23e8dbcf0ecf6e73a2436dc21769dd3e6f49
+PKG_HASH:=5965c692c4c8800cd4b33ce6d0f6ac9ac9d6ab227b17c512b6561bce4f08d47e
PKG_CPE_ID:=cpe:/a:tukaani:xz
HOST_BUILD_PARALLEL:=1
diff --git a/tools/yafut/Makefile b/tools/yafut/Makefile
new file mode 100644
index 0000000000..e463d38c65
--- /dev/null
+++ b/tools/yafut/Makefile
@@ -0,0 +1,20 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=yafut
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=https://github.com/kempniu/yafut.git
+PKG_MIRROR_HASH:=f5c76edc81477d2b68a7b032487d10fa361c8eaeecfc36908fde2ae828b7e822
+PKG_SOURCE_DATE:=2025-02-18
+PKG_SOURCE_VERSION:=e342c93981dc255bba58c17925b5c8983d7dacf8
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_INSTALL:=1
+
+$(eval $(call HostBuild))
diff --git a/tools/zlib/Makefile b/tools/zlib/Makefile
index b1307ef2af..09c0aa6f71 100644
--- a/tools/zlib/Makefile
+++ b/tools/zlib/Makefile
@@ -11,12 +11,13 @@ PKG_NAME:=zlib
PKG_VERSION:=1.3.1
PKG_RELEASE:=1
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://github.com/madler/zlib/releases/download/v$(PKG_VERSION)
-PKG_HASH:=9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/madler/zlib
+PKG_SOURCE_VERSION:=51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf
+PKG_MIRROR_HASH:=6558577038f4839057fad93afb295bf32e84dc9bd2c33512d40a5eab6d4889ef
PKG_LICENSE:=Zlib
-PKG_LICENSE_FILES:=README
+PKG_LICENSE_FILES:=LICENSE
PKG_CPE_ID:=cpe:/a:zlib:zlib
HOST_BUILD_PARALLEL:=1
diff --git a/tools/zstd/Makefile b/tools/zstd/Makefile
index e1d36c59cf..88a961f323 100644
--- a/tools/zstd/Makefile
+++ b/tools/zstd/Makefile
@@ -1,11 +1,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=zstd
-PKG_VERSION:=1.5.6
+PKG_VERSION:=1.5.7
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/facebook/zstd/releases/download/v$(PKG_VERSION)
-PKG_HASH:=8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1
+PKG_HASH:=eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
diff --git a/tools/zstd/patches/001-Provide-variant-pkg-config-file-for-multi-threaded-s.patch b/tools/zstd/patches/001-Provide-variant-pkg-config-file-for-multi-threaded-s.patch
deleted file mode 100644
index 1bbcaf4c8a..0000000000
--- a/tools/zstd/patches/001-Provide-variant-pkg-config-file-for-multi-threaded-s.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From f1f1ae369a4cefd3474b3528e8d1847b18750605 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 6 Apr 2024 14:41:54 +0200
-Subject: [PATCH] Provide variant pkg-config file for multi-threaded static lib
-
-Multi-threaded static library require -pthread to correctly link and works.
-The pkg-config we provide tho only works with dynamic multi-threaded library
-and won't provide the correct libs and cflags values if lib-mt is used.
-
-To handle this, introduce an env variable MT to permit advanced user to
-install and generate a correct pkg-config file for lib-mt or detect if
-lib-mt target is called.
-
-With MT env set on calling make install-pc, libzstd.pc.in is a
-pkg-config file for a multi-threaded static library.
-
-On calling make lib-mt, a libzstd.pc is generated for a multi-threaded
-static library as it's what asked by the user by forcing it.
-
-libzstd.pc is changed to PHONY to force regeneration of it on calling
-lib targets or install-pc to handle case where the same directory is
-used for mixed compilation.
-
-This was notice while migrating from meson to make build system where
-meson generates a correct .pc file while make doesn't.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- lib/Makefile | 20 +++++++++++++++++++-
- lib/README.md | 4 ++++
- lib/libzstd.pc.in | 4 ++--
- 3 files changed, 25 insertions(+), 3 deletions(-)
-
---- a/lib/Makefile
-+++ b/lib/Makefile
-@@ -63,6 +63,8 @@ CPPFLAGS_DYNLIB += -DZSTD_MULTITHREAD #
- LDFLAGS_DYNLIB += -pthread
- CPPFLAGS_STATICLIB += # static library build defaults to single-threaded
-
-+# pkg-config Libs.private points to LDFLAGS_DYNLIB
-+PCLIB := $(LDFLAGS_DYNLIB)
-
- ifeq ($(findstring GCC,$(CCVER)),GCC)
- decompress/zstd_decompress_block.o : CFLAGS+=-fno-tree-vectorize
-@@ -186,12 +188,15 @@ lib : libzstd.a libzstd
- %-mt : CPPFLAGS_DYNLIB := -DZSTD_MULTITHREAD
- %-mt : CPPFLAGS_STATICLIB := -DZSTD_MULTITHREAD
- %-mt : LDFLAGS_DYNLIB := -pthread
-+%-mt : PCLIB :=
-+%-mt : PCMTLIB := $(LDFLAGS_DYNLIB)
- %-mt : %
- @echo multi-threaded build completed
-
- %-nomt : CPPFLAGS_DYNLIB :=
- %-nomt : LDFLAGS_DYNLIB :=
- %-nomt : CPPFLAGS_STATICLIB :=
-+%-nomt : PCLIB :=
- %-nomt : %
- @echo single-threaded build completed
-
-@@ -292,6 +297,14 @@ PCLIBPREFIX := $(if $(findstring $(LIBDI
- # to PREFIX, rather than as a resolved value.
- PCEXEC_PREFIX := $(if $(HAS_EXPLICIT_EXEC_PREFIX),$(EXEC_PREFIX),$${prefix})
-
-+
-+ifneq ($(MT),)
-+ PCLIB :=
-+ PCMTLIB := $(LDFLAGS_DYNLIB)
-+else
-+ PCLIB := $(LDFLAGS_DYNLIB)
-+endif
-+
- ifneq (,$(filter $(UNAME),FreeBSD NetBSD DragonFly))
- PKGCONFIGDIR ?= $(PREFIX)/libdata/pkgconfig
- else
-@@ -308,6 +321,10 @@ INSTALL_PROGRAM ?= $(INSTALL)
- INSTALL_DATA ?= $(INSTALL) -m 644
-
-
-+# pkg-config library define.
-+# For static single-threaded library declare -pthread in Libs.private
-+# For static multi-threaded library declare -pthread in Libs and Cflags
-+.PHONY: libzstd.pc
- libzstd.pc: libzstd.pc.in
- @echo creating pkgconfig
- @sed \
-@@ -316,7 +333,8 @@ libzstd.pc: libzstd.pc.in
- -e 's|@INCLUDEDIR@|$(PCINCPREFIX)$(PCINCDIR)|' \
- -e 's|@LIBDIR@|$(PCLIBPREFIX)$(PCLIBDIR)|' \
- -e 's|@VERSION@|$(VERSION)|' \
-- -e 's|@LIBS_PRIVATE@|$(LDFLAGS_DYNLIB)|' \
-+ -e 's|@LIBS_MT@|$(PCMTLIB)|' \
-+ -e 's|@LIBS_PRIVATE@|$(PCLIB)|' \
- $< >$@
-
- .PHONY: install
---- a/lib/README.md
-+++ b/lib/README.md
-@@ -27,12 +27,16 @@ Enabling multithreading requires 2 condi
-
- For convenience, we provide a build target to generate multi and single threaded libraries:
- - Force enable multithreading on both dynamic and static libraries by appending `-mt` to the target, e.g. `make lib-mt`.
-+ Note that the `.pc` generated on calling `make lib-mt` will already include the require Libs and Cflags.
- - Force disable multithreading on both dynamic and static libraries by appending `-nomt` to the target, e.g. `make lib-nomt`.
- - By default, as mentioned before, dynamic library is multithreaded, and static library is single-threaded, e.g. `make lib`.
-
- When linking a POSIX program with a multithreaded version of `libzstd`,
- note that it's necessary to invoke the `-pthread` flag during link stage.
-
-+The `.pc` generated from `make install` or `make install-pc` always assume a single-threaded static library
-+is compiled. To correctly generate a `.pc` for the multi-threaded static library, set `MT=1` as ENV variable.
-+
- Multithreading capabilities are exposed
- via the [advanced API defined in `lib/zstd.h`](https://github.com/facebook/zstd/blob/v1.4.3/lib/zstd.h#L351).
-
---- a/lib/libzstd.pc.in
-+++ b/lib/libzstd.pc.in
-@@ -11,6 +11,6 @@ Name: zstd
- Description: fast lossless compression algorithm library
- URL: https://facebook.github.io/zstd/
- Version: @VERSION@
--Libs: -L${libdir} -lzstd
-+Libs: -L${libdir} -lzstd @LIBS_MT@
- Libs.private: @LIBS_PRIVATE@
--Cflags: -I${includedir}
-+Cflags: -I${includedir} @LIBS_MT@