Subject: bug#77476: [PATCH] Rename various hash functions to avoid clashing with GnuTLS.

From: "Greg A. Woods" <[email-masked]>
Date: Thu, 03 Apr 2025 13:00:57 -0700

At Thu, 03 Apr 2025 08:25:15 +0300, Eli Zaretskii <[email-masked]> wrote:
Subject: Re: bug#77476: [PATCH] Rename various hash functions to avoid clashing with GnuTLS.
>
> > Date: Wed, 02 Apr 2025 20:46:03 -0700
> > From: "Greg A. Woods" <[email-masked]>
> >
> > Rename various hash functions in src/fns.c to facilitate static-linking
> > with GnuTLS which includes clashing hash functions from its "gl"
> > subdirectory.
> >
> > * src/fns.c: et al (hash_string, hash_lookup, hash_lookup_get_hash,
> >   hash_put, hash_remove_from_table): Rename with a leading "lisp_" prefix.
>
> Sorry, can you tell more about the rationale?  Why do these clash?

What do you mean by "Wny do these clash?"???  There are identical
symbols in the GnuTLS library to some defined in Emacs, yet the
implementations in each are entirely different and incompatible, and so
they can't be static-linked into the same program.  I.e. they "clash".

The problematic symbols are actually from "imported" gnulib functions
that are included in separate .o's in libgnutls.a, but since they are
needed by other functions in libgnutls then they have to be loaded, but
of course this is C and there are no namespaces (at least not without
fudging it with global structures containing function pointers, or using
the preprocessor and avoiding separate compilation, but GnuTLS clearly
doesn't do either) to prevent them from clashing with already loaded
functions from the application itself and the linker rightfully gives up
and fails.

There are only two (hash_lookup() and hash_string()) that actually
clash, but it seems best to rename all the related global functions.

Static linking really should be mandated for all C programs, at least as
a primary test, to be sure you always get what you think you're looking
for and so that you really know the full extent of absolutely everything
you're depending on.  If you can't static-link a C program then there's
probably something fundamentally wrong with it's relationship to its
dependencies.  C programmers need to remember they are writing C, not
Oberon-2 or Java or Go or some such other language with modules and
namespaces and such.

> Is this perhaps a matter of correct function visibility in a library?

There's no such thing as "function visibility" in a plain old static C
library.  All global symbols are visible all the time, and depending on
internal dependencies of the object files you load, well you get what
you get from the rest of the library with no choice in how "visible" it
is to the rest of your binary.  It's all "visible".

> And why does Emacs, and not GnuTLS, need to rename its functions?

The GnuTLS library is indeed somewhat of a mess in terms of the APIs it
presents, but since it's the "third party" here the choice is either to
kick it out, or to change the local definitions that clash.

I don't know if this problem can affect dynamic-linked versions of Emacs
or not, but presumably not or bugs would have shown up by now.  I dunno
-- the runtime dynamic linker is too much of a mysterious force to know
for sure what it has done without dissecting exactly the result after
the fact, and that's much harder to do as none of the implementations I
know of have an option to produce a link map.

In any case I think fixing the problems in GnuTLS is a far more
extensive and complex job, and it's not even a tiny bit interesting to
me as I have no vested interest in directly working on GnuTLS.  My
interest is far higher in Emacs!  I would guess the whole method of
importing gnulib functions would have to be changed in order to give
those "private" (i.e. less-likely-to-ever-clash) names.

I'm happy to use GnuTLS in Emacs if that's what Emacs developers would
like to use, but I've also been relatively happy with using the tls
package to access an external implementation as well (though it is
tricky to maintain with constant changes in the command-lines and output
formats).

> Also, how come this comes up only now?

I've been avoiding linking GnuTLS for quite some time, but with the tls
package being deprecated for a while now (my primary production Emacs is
now 27.2, tls.el moved to obsolete in 27.1) that's becoming a precarious
position to take.

> In any case, the prefix "lisp_" doesn't sound right to me.  Maybe
> "emacs_" or something similar, like just "e".

Meh -- potato po-ta-toe.  I.e. I've no strong feelings about the
particular choice of prefix.  You can choose whichever you like.  I just
thought that since these functions are for accessing the "lisp hash
table", well they might best be named for it.

--
					Greg A. Woods <[email-masked]>

Kelowna, BC     +1 250 762-7675           RoboHack <[email-masked]>
Planix, Inc. <[email-masked]>     Avoncote Farms <[email-masked]>