Re: Should /usr/include/fts.h adding fts_dirfd and __fts_reserved[3] to FTSENT (a.k.a. struct _ftsent) require a change from libc.so.7 to .8 because of some resulting binary incompatibilities?
- Reply: Konstantin Belousov : "Re: Should /usr/include/fts.h adding fts_dirfd and __fts_reserved[3] to FTSENT (a.k.a. struct _ftsent) require a change from libc.so.7 to .8 because of some resulting binary incompatibilities?"
- In reply to: Konstantin Belousov : "Re: Should /usr/include/fts.h adding fts_dirfd and __fts_reserved[3] to FTSENT (a.k.a. struct _ftsent) require a change from libc.so.7 to .8 because of some resulting binary incompatibilities?"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 27 Sep 2026 20:19:15 UTC
On 9/24/26 20:06, Konstantin Belousov wrote: > On Thu, Sep 24, 2026 at 06:57:04PM -0700, Mark Millard wrote: >> On 9/24/26 17:16, Mark Millard wrote: >>> On 9/24/26 16:40, Warner Losh wrote: >>>> No. Symbol versioning. >>> >>> jevents has no symbol versioning for its own, internal implementation of >>> a function it decided to name fts_compare as far as I can tell. That >>> same fts_compare implementation is passed in everywhere that the same >>> libc.so.7 naming is in use and then is called no matter what, >>> independent of which fts.h vintage it was built with. >>> >>> If symbol versioning applies here, how does it work? >>> >>> (Why I ended up with the mix of an older jevents with a post-change >>> environment is a separate issue and is my fault. But nothing rejected or >>> fixed the combination. libc.so.8 vs. libc.so.7 would have rejected.) >> >> Your note caused me to somewhat better isolate the structure of the mix: >> >> The kernel is updated to : 1600026 >> The world is updating from: 1600019 (so: old fts.h) >> The world is updating to : 1600026 (or trying to) >> >> # readelf -a >> /usr/obj/BUILDs/main-CA76-dbg-clang/usr/main-src/arm64.aarch64/lib/libc/libc.so.7 >> | grep fts_open@ >> 0000000000243d10 00000c7a00000402 R_AARCH64_JUMP_SLOT >> 00000000000c0c40 fts_open@@FBSD_1.9 + 0 >> 3194: 00000000000c0c40 128 FUNC GLOBAL DEFAULT 14 >> fts_open@@FBSD_1.9 >> 3195: 00000000000c29c0 1016 FUNC GLOBAL DEFAULT 14 >> fts_open@FBSD_1.0 >> 3196: 00000000000c4260 924 FUNC GLOBAL DEFAULT 14 >> fts_open@FBSD_1.1 >> 3197: 00000000000c5b60 124 FUNC GLOBAL DEFAULT 14 >> fts_open@FBSD_1.5 >> >> (Associated with building from modern 1600026 source at the time.) >> >> jevents got: >> >> # readelf -a >> /usr/obj/BUILDs/main-CA76-dbg-clang/usr/main-src/arm64.aarch64/lib/libpmc/pmu-events/jevents >> | grep fts_open@ >> 0000000000037680 0000001300000402 R_AARCH64_JUMP_SLOT >> 0000000000000000 fts_open@FBSD_1.9 + 0 >> 19: 0000000000000000 0 FUNC GLOBAL DEFAULT UND >> fts_open@FBSD_1.9 >> >> >> But, as a build-tool, jevents was built with /usr/include/fts.h instead >> of with the /usr/main-src/ tree that I use for the build if the update. >> (/usr/src/ is from pkgbase.): >> >> # diff -u /usr/include/fts.h /usr/main-src/include/fts.h >> --- /usr/include/fts.h 2025-05-11 07:29:42.791259000 -0700 >> +++ /usr/main-src/include/fts.h 2026-09-18 16:13:35.766402000 -0700 >> @@ -1,4 +1,4 @@ >> -/*- >> +/* >> * SPDX-License-Identifier: BSD-3-Clause >> * >> * Copyright (c) 1989, 1993 >> @@ -92,6 +92,8 @@ >> char *fts_path; /* root path */ >> int fts_errno; /* errno for this node */ >> int fts_symfd; /* fd for symlink */ >> + int fts_dirfd; /* fd for this directory, if a >> directory */ >> + int __fts_reserved[3]; /* reserved for future use */ >> __size_t fts_pathlen; /* strlen(fts_path) */ >> __size_t fts_namelen; /* strlen(fts_name) */ >> >> @@ -146,6 +148,8 @@ >> #define fts_get_stream(ftsent) ((ftsent)->fts_fts) >> FTS *fts_open(char * const *, int, >> int (*)(const FTSENT * const *, const FTSENT * const *)); >> +FTS *fts_openat(int, char * const *, int, >> + int (*)(const FTSENT * const *, const FTSENT * const *)); >> #ifdef __BLOCKS__ >> FTS *fts_open_b(char * const *, int, >> int (^)(const FTSENT * const *, const FTSENT * const *)); >> >> Thus the result was a jevents using: >> >> ) the old /usr/include/fts.h header of its "host" environment >> but also: >> ) the new symbol version fts_open@@FBSD_1.9 was used. >> >> Nothing rejected the bad combination (other than a later SIGSEGV). > > Right, if it is the case, then the ABI mismatch is unavoidable. > By itself, this sounds like a serious bug in our build system. > >> >> I do not see how /usr/include/fts.h file content would end up somehow in >> control over fts_open@@FBSD_1.5 vs. fts_open@@FBSD_1.9 being used for >> the likes of the jevents build. > > Include files provide a part of the ABI, which is used by compiler. > In particular, include files define the layout of C structures. > > Shared libraries provide another part, giving the (default) versions to the > symbols referenced by the final object. Layout of the parameters to > the specific version of the function must match to what headers used > at compile time defined. > > Mixing these parts across ABI changes cannot work. > > I think I've identified what went wrong in the history of trying this update in my context: a separate installworld race issue (-j used) lead to an initial partial update of the chroot/jail tree, where: ) libc.so.7 updated before that installworld failed. ) /usr/include/fts.h did not. (Would have installed after the installworld failure point.) So later activity then had the incoherent mix without me identifying it at the time. For this sequencing, libc.so.8 use would not have helped. (Via avoiding -j use for installworld I've gotten all my chroot/jail tree personal builds to avoid the race.) -- === Mark Millard marklmi at yahoo.com