commit: 58828a694155b06dd9d8c97fcd563e7e1d6a9fb4 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Wed Jun 12 03:20:24 2024 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Wed Jun 12 03:20:24 2024 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=58828a69
dev-util/ctags: backport alignment fix Closes: https://bugs.gentoo.org/920066 Bug: https://bugs.gentoo.org/919480 Signed-off-by: Sam James <sam <AT> gentoo.org> dev-util/ctags/ctags-20230423.0-r1.ebuild | 98 ++++++++++++++++++++++ .../ctags/files/ctags-20230423.0-alignment.patch | 88 +++++++++++++++++++ 2 files changed, 186 insertions(+) diff --git a/dev-util/ctags/ctags-20230423.0-r1.ebuild b/dev-util/ctags/ctags-20230423.0-r1.ebuild new file mode 100644 index 000000000000..b74769c09a50 --- /dev/null +++ b/dev-util/ctags/ctags-20230423.0-r1.ebuild @@ -0,0 +1,98 @@ +# Copyright 1999-2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +PYTHON_COMPAT=( python3_{10..13} ) +inherit autotools python-any-r1 + +DESCRIPTION="Exuberant Ctags creates tags files for code browsing in editors" +HOMEPAGE="https://ctags.io/ https://github.com/universal-ctags/ctags" + +if [[ ${PV} == *99999999* ]] ; then + EGIT_REPO_URI="https://github.com/universal-ctags/ctags" + inherit git-r3 +else + SRC_URI="https://github.com/universal-ctags/ctags/archive/refs/tags/p6.0.${PV}.tar.gz -> ${P}.tar.gz" + S="${WORKDIR}"/${PN}-p6.0.${PV} + + KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86 ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x64-solaris" +fi + +LICENSE="GPL-2+" +SLOT="0" +IUSE="json pcre seccomp test xml yaml" +RESTRICT="!test? ( test )" + +DEPEND=" + json? ( dev-libs/jansson:= ) + pcre? ( dev-libs/libpcre2 ) + seccomp? ( sys-libs/libseccomp ) + xml? ( dev-libs/libxml2:2 ) + yaml? ( dev-libs/libyaml ) +" +RDEPEND="${DEPEND}" +BDEPEND=" + dev-python/docutils + virtual/pkgconfig + test? ( ${PYTHON_DEPS} ) +" +IDEPEND="app-eselect/eselect-ctags" + +QA_CONFIG_IMPL_DECL_SKIP=( + # manual check for function in a library that doesn't exist, passes -liconv + # which either fails to link anyway (glibc) or passes this check (musl) + libiconv_open +) + +PATCHES=( + "${FILESDIR}"/${PN}-20230423.0-alignment.patch +) + +pkg_setup() { + use test && python-any-r1_pkg_setup +} + +src_prepare() { + # Ignore check-genfile test (calls git which errors out) + sed -i 's/man-test check-genfile/man-test/' makefiles/testing.mak || die + + default + + #./misc/dist-test-cases > makefiles/test-cases.mak || die + + eautoreconf +} + +src_configure() { + econf \ + $(use_enable json) \ + $(use_enable pcre pcre2) \ + $(use_enable seccomp) \ + $(use_enable xml) \ + $(use_enable yaml) \ + --disable-etags \ + --enable-tmpdir="${EPREFIX}"/tmp +} + +src_install() { + emake prefix="${ED}"/usr mandir="${ED}"/usr/share/man install + + # Namepace collision with X/Emacs-provided /usr/bin/ctags -- we + # rename ctags to exuberant-ctags (Mandrake does this also). + mv "${ED}"/usr/bin/{ctags,exuberant-ctags} || die + mv "${ED}"/usr/share/man/man1/{ctags,exuberant-ctags}.1 || die +} + +pkg_postinst() { + eselect ctags update + + if [[ -z "${REPLACING_VERSIONS}" ]]; then + elog "You can set the version to be started by ${EROOT}/usr/bin/ctags through" + elog "the ctags eselect module. \"man ctags.eselect\" for details." + fi +} + +pkg_postrm() { + eselect ctags update +} diff --git a/dev-util/ctags/files/ctags-20230423.0-alignment.patch b/dev-util/ctags/files/ctags-20230423.0-alignment.patch new file mode 100644 index 000000000000..89544cb516bf --- /dev/null +++ b/dev-util/ctags/files/ctags-20230423.0-alignment.patch @@ -0,0 +1,88 @@ +https://bugs.gentoo.org/920066 +https://github.com/universal-ctags/ctags/issues/3881 +https://github.com/universal-ctags/ctags/pull/3883 + +From e6bc697502fcf582ea52e7098becf01ca0b00fc8 Mon Sep 17 00:00:00 2001 +From: Colomban Wendling <[email protected]> +Date: Sat, 16 Dec 2023 19:20:32 +0100 +Subject: [PATCH] nestlevel: Fix user data alignment + +We need to align the user data properly not to trigger undefined +behavior, which even apparently crashes on SPARC. + +As `NestingLevels::levels` is actually a single allocation for all +levels and their user data mapped as `[NL0|UD0|NL1|UD1|...]` (where NL +is a NestingLevel, and UD a user data), we need to align twice, as we +need every `NL*` and every `UD*` to align properly. + +Here we align everything to `2*sizeof(size_t)`, which is a logic +borrowed from GLib, which seems to have borrowed the value from glibc. +This is pretty conservative in our case, because actually `NL*`s only +need aligning to `int`'s requirements currently, which on some +architectures is 4, not 16; but it's trickier to implement (and +actually impossible with the current API) as we'd need to compute the +actual alignment for each level taking into account it's position in +the overall memory region to still align `UD*`s to a conservative +value. +Also, having all NL+UD group at the same size makes things a bit +simpler for debugging, I guess. + +We make sure to only add alignment padding manually for cases where +there's actually some user data, not to waste memory needlessly for the +common case where `sizeof(UD)` is 0, and thus where we can merely +align to `sizeof(NL)` -- which C does for us already. + +Note that currently only the Ruby parser is affected, as it's the only +current consumer of nesting level user data. + +Fixes #3881. +--- a/main/nestlevel.c ++++ b/main/nestlevel.c +@@ -20,8 +20,16 @@ + + #include <string.h> + +-/* TODO: Alignment */ +-#define NL_SIZE(nls) (sizeof(NestingLevel) + (nls)->userDataSize) ++/* struct alignment trick, copied from GObject's gtype.c, which borrows ++ * 2*szieof(size_t) from glibc */ ++#define STRUCT_ALIGNMENT (2 * sizeof (size_t)) ++#define ALIGN_STRUCT(offset) ((offset + (STRUCT_ALIGNMENT - 1)) & -STRUCT_ALIGNMENT) ++ ++/* account for the user data alignment if we have user data, otherwise allocate ++ * exactly what's needed not to waste memory for unneeded alignment */ ++#define NL_SIZE(nls) ((nls)->userDataSize ? (ALIGN_STRUCT (sizeof (NestingLevel)) + ALIGN_STRUCT ((nls)->userDataSize)) : sizeof (NestingLevel)) ++#define NL_USER_DATA(nl) ((void *)(((char *) nl) + ALIGN_STRUCT (sizeof (NestingLevel)))) ++ + #define NL_NTH(nls,n) (NestingLevel *)(((char *)((nls)->levels)) + ((n) * NL_SIZE (nls))) + + /* +@@ -73,7 +81,7 @@ extern NestingLevel * nestingLevelsPush(NestingLevels *nls, int corkIndex) + + nl->corkIndex = corkIndex; + if (nls->userDataSize > 0) +- memset (nl->userData, 0, nls->userDataSize); ++ memset (NL_USER_DATA (nl), 0, ALIGN_STRUCT (nls->userDataSize)); + + return nl; + } +@@ -117,5 +125,5 @@ extern NestingLevel *nestingLevelsGetNthParent (const NestingLevels *nls, int n) + + extern void *nestingLevelGetUserData (const NestingLevel *nl) + { +- return (void *)nl->userData; ++ return NL_USER_DATA (nl); + } +--- a/main/nestlevel.h ++++ b/main/nestlevel.h +@@ -26,7 +26,8 @@ typedef struct NestingLevels NestingLevels; + struct NestingLevel + { + int corkIndex; +- char userData []; ++ /* user data is allocated at the end of this struct (possibly with some ++ * offset for alignment), get it with nestingLevelGetUserData() */ + }; + + struct NestingLevels +
