https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116809

--- Comment #22 from Mark Mentovai <mark at moxienet dot com> ---
(In reply to Iain Sandoe from comment #21)
> Thta is quite surprising - since the SDK should reflect the symbols exported
> by the libraries installed on the target system. Therefore, they should be
> present when the target is macOS 14;

For the purposes of having appropriate declarations available for compiling,
the declarations in the SDK’s headers generally are annotated with availability
and obsolescence annotations. Apple is fairly good about this.

For the purposes of linking, the SDK simply exposes the set of global symbols
exported by loadable modules, previously in stripped-down Mach-O format
containing little more than a symbol table, but nowadays (since SDK 10.11) in
.tbd format. Neither the Mach-O symbol table nor the .tbd format have a way to
express partial availability. The .tbd files are produced as a simple export of
the source Mach-O’s symbol table.

Because the libunwind symbols in question were never intended for user
consumption, but were part of a loose contract with toolchains, there weren’t
any viable declarations for them in SDK headers. The double-underscore prefix
is a hint of this (the third underscore added as “C” name decoration). Where
there were declarations (since SDK 10.7, in <unwind.h>), they were decorated
with __attribute__((unavailable)). This is as good as there being no
declaration at all. In fact, this still appears in SDK 15:

#if defined(__APPLE__)
#define LIBUNWIND_UNAVAIL __attribute__ (( unavailable ))
#else
#define LIBUNWIND_UNAVAIL
#endif
[…]
// Mac OS X 10.4 and 10.5 had implementations of these functions in
// libgcc_s.dylib, but they never worked.
/// These functions are no longer available on Mac OS X.
extern void __register_frame_info_bases(const void *fde, void *ob, void *tb,
                                        void *db) LIBUNWIND_UNAVAIL;
[…]

(from
https://github.com/llvm/llvm-project/blob/1187d8a62ba288e2221731f1795fa184571cd854/libunwind/include/unwind.h#L169)

But we’re not concerned with writing user code and calling these functions by
#including <unwind.h> in libgcc_s.1. We’re simply concerned with re-exporting
these symbols from libunwind, via the libSystem umbrella. That’s strictly a
linker concern, and again, the input to the linker carries no information about
availability, including partial availability or unavailability. If a symbol is
present in a macOS runtime, whether the header annotates it as
partially-available or unavailable or (absent an annotation) available without
qualification, it will also appear in that same macOS version’s SDK, as the
.tbd files are produced from the Mach-O files present in the runtime. So when
the runtime drops a symbol entirely, as is the case in macOS 15 for these
libunwind symbols, they disappear from the SDK as well. And when you build
against the macOS 15 SDK to target macOS 14 or an earlier version, you lose
access to the symbols dropped by macOS 15.

Largely, this is working as intended. The only reason that Apple felt
comfortable dropping these symbols from the runtime at all was that they
believed they were entirely unused. I explained this and provided further
justification in comment 10 (although I felt you kind of brushed that off—no
offense taken, though) in support of the idea that libgcc_s.1 could feasibly
drop the symbols as well, as I proposed in attachment 59179. If anyone had been
using those symbols, and successfully linked against a previous SDK, that code
would not have run on macOS 15, because the symbols are no longer part of the
runtime. They’re only safe to remove from the runtime if no code references
them, and if no code references them, then they’re also safe to remove from the
SDK.

> Perhaps something not conditional in the way it should be - or it is
> depending on support for attribute ((availability)) which is only currently
> committed on darwin branches.

Do Not Adjust Your Set. Availability is working as it should. This example is
iains/gcc-14-branch gcc-14-2-darwin:

mark@arm-and-hammer zsh% gcc -x c -c -o /dev/null - <<< 'void U()
__attribute__((unavailable)); void F() { U(); }'
<stdin>: In function 'F':
<stdin>:1:1: error: 'U' is unavailable
<stdin>:1:6: note: declared here

> If we build a compiler targeting macOS 15, but using xcode 16 on macOS 14 -
> then we should still eliminate the library.

Yes. But it’s difficult to cleanly detect what Xcode version you’re using, or
perhaps more directly, whether libSystem exposes any of these symbols. You
could do it with a configure check, but that seems like a little much for a
handful of symbols that nobody’s using.

Another option is to eliminate them from macOS 14 regardless of the SDK in use
(attachment 59189).

Reply via email to