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
+

Reply via email to