pkgsrc-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: pkgsrc/lang



Module Name:    pkgsrc
Committed By:   adam
Date:           Sun Jul 19 11:17:45 UTC 2026

Modified Files:
        pkgsrc/lang/gcc15: Makefile Makefile.common distinfo options.mk
            version.mk
        pkgsrc/lang/gcc15-libs: Makefile
        pkgsrc/lang/gcc15/patches: patch-configure patch-configure.ac
            patch-gcc_config.gcc patch-gcc_targhooks.cc
            patch-libgcc_config.host patch-libgcobol_configure.tgt
Added Files:
        pkgsrc/lang/gcc15/patches: patch-fixincludes_fixincl.x
            patch-fixincludes_inclhack.def patch-gcc_ada_init.c
            patch-gcc_builtins.cc patch-gcc_c-family_c-attribs.cc
            patch-gcc_c-family_c-common.cc patch-gcc_c-family_c-common.h
            patch-gcc_c-family_c-lex.cc patch-gcc_c-family_c-opts.cc
            patch-gcc_c-family_c-pragma.h patch-gcc_c-family_c.opt
            patch-gcc_c_c-decl.cc patch-gcc_c_c-parser.cc patch-gcc_calls.cc
            patch-gcc_calls.h patch-gcc_collect2.cc patch-gcc_common.opt
            patch-gcc_common_config_aarch64_aarch64-common.cc
            patch-gcc_config_aarch64_aarch64-builtins.cc
            patch-gcc_config_aarch64_aarch64-c.cc
            patch-gcc_config_aarch64_aarch64-cores.def
            patch-gcc_config_aarch64_aarch64-protos.h
            patch-gcc_config_aarch64_aarch64-tune.md
            patch-gcc_config_aarch64_aarch64.cc
            patch-gcc_config_aarch64_aarch64.h
            patch-gcc_config_aarch64_aarch64.md
            patch-gcc_config_aarch64_aarch64.opt
            patch-gcc_config_aarch64_constraints.md
            patch-gcc_config_aarch64_darwin.h
            patch-gcc_config_aarch64_driver-aarch64.cc
            patch-gcc_config_aarch64_predicates.md
            patch-gcc_config_aarch64_t-aarch64-darwin
            patch-gcc_config_darwin-driver.cc patch-gcc_config_darwin-protos.h
            patch-gcc_config_darwin-sections.def patch-gcc_config_darwin.cc
            patch-gcc_config_darwin.h patch-gcc_config_darwin.opt
            patch-gcc_configure patch-gcc_configure.ac patch-gcc_cp_decl2.cc
            patch-gcc_cp_lex.cc patch-gcc_cp_parser.cc
            patch-gcc_cumulative-args.h patch-gcc_doc_invoke.texi
            patch-gcc_doc_tm.texi patch-gcc_doc_tm.texi.in
            patch-gcc_exec-tool.in patch-gcc_explow.cc patch-gcc_explow.h
            patch-gcc_function.cc patch-gcc_function.h
            patch-gcc_ginclude_stddef.h patch-gcc_opts.cc patch-gcc_target.def
            patch-gcc_target.h patch-gcc_targhooks.h
            patch-libgcc_config_aarch64_____arm__sme__state.S
            patch-libgcc_config_aarch64_____arm__tpidr2__restore.S
            patch-libgcc_config_aarch64_____arm__tpidr2__save.S
            patch-libgcc_config_aarch64_____arm__za__disable.S
            patch-libgcc_config_aarch64_aarch64-asm.h
            patch-libgcc_config_aarch64_lse.S
            patch-libgcc_config_aarch64_sfp-machine.h
            patch-libgcc_config_aarch64_t-darwin
            patch-libgcc_config_libbid_bid__binarydecimal.c
            patch-libitm_config_aarch64_sjlj.S patch-libitm_configure.tgt
            patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d
            patch-libsanitizer_configure.tgt
            patch-libsanitizer_sanitizer__common_sanitizer__common.h
            patch-libsanitizer_sanitizer__common_sanitizer__procmaps__mac.cpp

Log Message:
gcc15: updated to 15.3

15.3
This release is a bug-fix release, containing fixes for regressions in
GCC 15.2 relative to previous releases of GCC.

PkgSrc:
Allow building on Darwin/aarch64.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 pkgsrc/lang/gcc15/Makefile \
    pkgsrc/lang/gcc15/distinfo
cvs rdiff -u -r1.2 -r1.3 pkgsrc/lang/gcc15/Makefile.common \
    pkgsrc/lang/gcc15/options.mk pkgsrc/lang/gcc15/version.mk
cvs rdiff -u -r1.5 -r1.6 pkgsrc/lang/gcc15-libs/Makefile
cvs rdiff -u -r1.1 -r1.2 pkgsrc/lang/gcc15/patches/patch-configure \
    pkgsrc/lang/gcc15/patches/patch-configure.ac \
    pkgsrc/lang/gcc15/patches/patch-gcc_config.gcc \
    pkgsrc/lang/gcc15/patches/patch-gcc_targhooks.cc \
    pkgsrc/lang/gcc15/patches/patch-libgcc_config.host \
    pkgsrc/lang/gcc15/patches/patch-libgcobol_configure.tgt
cvs rdiff -u -r0 -r1.1 pkgsrc/lang/gcc15/patches/patch-fixincludes_fixincl.x \
    pkgsrc/lang/gcc15/patches/patch-fixincludes_inclhack.def \
    pkgsrc/lang/gcc15/patches/patch-gcc_ada_init.c \
    pkgsrc/lang/gcc15/patches/patch-gcc_builtins.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-attribs.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-common.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-common.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-lex.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-opts.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-pragma.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c.opt \
    pkgsrc/lang/gcc15/patches/patch-gcc_c_c-decl.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_c_c-parser.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_calls.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_calls.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_collect2.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_common.opt \
    pkgsrc/lang/gcc15/patches/patch-gcc_common_config_aarch64_aarch64-common.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-builtins.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-c.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-cores.def \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-protos.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-tune.md \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.md \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.opt \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_constraints.md \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_darwin.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_driver-aarch64.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_predicates.md \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_t-aarch64-darwin \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-driver.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-protos.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-sections.def \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.opt \
    pkgsrc/lang/gcc15/patches/patch-gcc_configure \
    pkgsrc/lang/gcc15/patches/patch-gcc_configure.ac \
    pkgsrc/lang/gcc15/patches/patch-gcc_cp_decl2.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_cp_lex.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_cp_parser.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_cumulative-args.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_doc_invoke.texi \
    pkgsrc/lang/gcc15/patches/patch-gcc_doc_tm.texi \
    pkgsrc/lang/gcc15/patches/patch-gcc_doc_tm.texi.in \
    pkgsrc/lang/gcc15/patches/patch-gcc_exec-tool.in \
    pkgsrc/lang/gcc15/patches/patch-gcc_explow.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_explow.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_function.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_function.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_ginclude_stddef.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_opts.cc \
    pkgsrc/lang/gcc15/patches/patch-gcc_target.def \
    pkgsrc/lang/gcc15/patches/patch-gcc_target.h \
    pkgsrc/lang/gcc15/patches/patch-gcc_targhooks.h \
    pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__sme__state.S \
    pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__tpidr2__restore.S \
    pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__tpidr2__save.S \
    pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__za__disable.S \
    pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_aarch64-asm.h \
    pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_lse.S \
    pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_sfp-machine.h \
    pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_t-darwin \
    pkgsrc/lang/gcc15/patches/patch-libgcc_config_libbid_bid__binarydecimal.c \
    pkgsrc/lang/gcc15/patches/patch-libitm_config_aarch64_sjlj.S \
    pkgsrc/lang/gcc15/patches/patch-libitm_configure.tgt \
    pkgsrc/lang/gcc15/patches/patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d \
    pkgsrc/lang/gcc15/patches/patch-libsanitizer_configure.tgt \
    pkgsrc/lang/gcc15/patches/patch-libsanitizer_sanitizer__common_sanitizer__common.h \
    pkgsrc/lang/gcc15/patches/patch-libsanitizer_sanitizer__common_sanitizer__procmaps__mac.cpp

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/lang/gcc15/Makefile
diff -u pkgsrc/lang/gcc15/Makefile:1.5 pkgsrc/lang/gcc15/Makefile:1.6
--- pkgsrc/lang/gcc15/Makefile:1.5      Fri Jul 10 21:28:41 2026
+++ pkgsrc/lang/gcc15/Makefile  Sun Jul 19 11:17:41 2026
@@ -1,10 +1,9 @@
-# $NetBSD: Makefile,v 1.5 2026/07/10 21:28:41 tsutsui Exp $
+# $NetBSD: Makefile,v 1.6 2026/07/19 11:17:41 adam Exp $
 
 PKGNAME=       ${GCC_PKGNAME}-${GCC15_DIST_VERSION}
 ## When bumping the PKGREVISION of this package the PKGREVISION of
 ## lang/gcc15-libs needs to be bumped to be at least 1 more than the
 ## PKGREVISION of this package!
-PKGREVISION=   2
 COMMENT=       The GNU Compiler Collection (GCC) - 15.0 Release Series
 
 LANGS=         c
Index: pkgsrc/lang/gcc15/distinfo
diff -u pkgsrc/lang/gcc15/distinfo:1.5 pkgsrc/lang/gcc15/distinfo:1.6
--- pkgsrc/lang/gcc15/distinfo:1.5      Fri Jul 10 21:28:41 2026
+++ pkgsrc/lang/gcc15/distinfo  Sun Jul 19 11:17:41 2026
@@ -1,33 +1,105 @@
-$NetBSD: distinfo,v 1.5 2026/07/10 21:28:41 tsutsui Exp $
+$NetBSD: distinfo,v 1.6 2026/07/19 11:17:41 adam Exp $
 
-BLAKE2s (gcc-15.2.0.tar.xz) = ee9b2705b03ef8e6b5a41cf523dad26dcdaa8047be3743121b1673ce2fcc8832
-SHA512 (gcc-15.2.0.tar.xz) = 89047a2e07bd9da265b507b516ed3635adb17491c7f4f67cf090f0bd5b3fc7f2ee6e4cc4008beef7ca884b6b71dffe2bb652b21f01a702e17b468cca2d10b2de
-Size (gcc-15.2.0.tar.xz) = 101056276 bytes
+BLAKE2s (gcc-15.3.0.tar.xz) = 4230d4aaa5a4740a3101d5a06478d92d265796df542be1ddd6985be695a3e6ee
+SHA512 (gcc-15.3.0.tar.xz) = 0de9e296153b52c021b1c7e63c9c62151d7a0ac03f23ce6e9f772c1b0eb783f6acdd81cc4567bfe4128a6f64968c2cfc8eff40b36229cba7425349f7d637c654
+Size (gcc-15.3.0.tar.xz) = 101253696 bytes
 BLAKE2s (isl-0.24.tar.xz) = a3013b0d39b7fe68a1b3e15dc7e925b347d555348ee946a80f5319a76973cd61
 SHA512 (isl-0.24.tar.xz) = ff6bdcff839e1cd473f2a0c1e4dd4a3612ec6fee4544ccbc62b530a7248db2cf93b4b99bf493a86ddf2aba00e768927265d5d411f92061ea85fd7929073428e8
 Size (isl-0.24.tar.xz) = 1930956 bytes
-SHA1 (patch-configure) = 8e33eda65a5a5ba212ebab8c26ca4dc2e5ae0c51
-SHA1 (patch-configure.ac) = b72e07578678926dca9ce5b008bacbfcecb68cbb
+SHA1 (patch-configure) = 42e956889e6004d9663e4337c6268df3d812f361
+SHA1 (patch-configure.ac) = 1ae9f230522c2814b85f3cb3c9cf7db02e52a4e0
+SHA1 (patch-fixincludes_fixincl.x) = f19c7245e4ba923e1354e6b994ef97c82bee4c8a
+SHA1 (patch-fixincludes_inclhack.def) = ae767c3bbaf15d8ae201bf3daf53ac77fa34d47b
 SHA1 (patch-gcc_Makefile.in) = a31ddc27f1092cfdf5ac896ca79c8590b5aceb47
-SHA1 (patch-gcc_config.gcc) = 65126c56f0cd9027f66b5f677773dfa9973b451c
+SHA1 (patch-gcc_ada_init.c) = 82a10cb603a553a63aa1f50426d0f0ae108f983b
+SHA1 (patch-gcc_builtins.cc) = 5aa27df4a8548d5a28d2eb93e675520d5b769129
+SHA1 (patch-gcc_c-family_c-attribs.cc) = 8e62594042dd978d1f91b3fc96c4fb626cecb897
+SHA1 (patch-gcc_c-family_c-common.cc) = e66a11618f9cd5ab084c3a059d5b3e114f3f404d
+SHA1 (patch-gcc_c-family_c-common.h) = d6146141cc1faff16dabc25e9455ae1aed396d0b
+SHA1 (patch-gcc_c-family_c-lex.cc) = f11f25cb7866450ca07564b020b324a46d052580
+SHA1 (patch-gcc_c-family_c-opts.cc) = f2dc8483325772569861dac9cc809c52a533a94c
+SHA1 (patch-gcc_c-family_c-pragma.h) = e8eb998eacd8e9530b00596246315271695c964f
+SHA1 (patch-gcc_c-family_c.opt) = 050ed115382439f9f522e5568621e55a419826c1
+SHA1 (patch-gcc_c_c-decl.cc) = 68bbad78673e8d333b899d9361df19ddb2600fd7
+SHA1 (patch-gcc_c_c-parser.cc) = c9036d10051c4f9b36d12a086bfd6f0dd9c3cbdd
+SHA1 (patch-gcc_calls.cc) = 999c8a40c89c5262c914581fdfce2c6a5f3cf29f
+SHA1 (patch-gcc_calls.h) = a66a37cdd293e4148c8ca512b981d7bbc11ca8e4
+SHA1 (patch-gcc_collect2.cc) = 6e6c1797215b36a1e5ffa7989cea1fe1eb2ae834
+SHA1 (patch-gcc_common.opt) = e06b8fc63f1d00ef41a22722397ec599b708243d
+SHA1 (patch-gcc_common_config_aarch64_aarch64-common.cc) = 4150450d2b41b7bad2be188fa3ff43bbc7389371
+SHA1 (patch-gcc_config.gcc) = 490dfef790893f4bef5bf48c35d2cca0f856c6dd
 SHA1 (patch-gcc_config.host) = bf95dd21bfdf79d173e745fbd35c9bb99fdf4087
+SHA1 (patch-gcc_config_aarch64_aarch64-builtins.cc) = 1b2e29c1749ab4aacad86422ef44b053d72550c7
+SHA1 (patch-gcc_config_aarch64_aarch64-c.cc) = e9e7e435d256e1e31fb0183716ea5475304f7c9b
+SHA1 (patch-gcc_config_aarch64_aarch64-cores.def) = 3e84397abc76811553cc879a941c9f7c2350cefc
 SHA1 (patch-gcc_config_aarch64_aarch64-netbsd.h) = abf19e2445bce1773162bddef16cd7f41eb36827
+SHA1 (patch-gcc_config_aarch64_aarch64-protos.h) = b23df0b354621e5352b8e875e14c2392d0170739
+SHA1 (patch-gcc_config_aarch64_aarch64-tune.md) = c249ca9a56101fbd8567b1e074e6b1a32f868c3c
+SHA1 (patch-gcc_config_aarch64_aarch64.cc) = f0d3780aa6a823f4bd5250bbf5de8716849ca694
+SHA1 (patch-gcc_config_aarch64_aarch64.h) = d8037d9c38cb8d058bdbd204c1e12c4174e2e14a
+SHA1 (patch-gcc_config_aarch64_aarch64.md) = 7645702fbfba43854c6363a1c91c72f2d4f9a490
+SHA1 (patch-gcc_config_aarch64_aarch64.opt) = ed019fb8b4eab04852dc18b12a770ede2d4a4a89
+SHA1 (patch-gcc_config_aarch64_constraints.md) = 970947255c9b480bd8813bcd489a396ee8f18d69
+SHA1 (patch-gcc_config_aarch64_darwin.h) = bb993ded98f1c5b1ef86c96cbc5d6e62b675263e
+SHA1 (patch-gcc_config_aarch64_driver-aarch64.cc) = 7b16eee32abfe8aed2cdffbf9e0ee49d89157d7f
+SHA1 (patch-gcc_config_aarch64_predicates.md) = 539ecca12e5e85859b1030d18173e9a5b9937bf3
+SHA1 (patch-gcc_config_aarch64_t-aarch64-darwin) = 3bddd708dc57283152419ee094378cc33f589eee
 SHA1 (patch-gcc_config_arm_arm.h) = 9d554349869d67d6393552c33a7824f0dd53cb11
 SHA1 (patch-gcc_config_arm_bpabi.h) = 0b0de5ad95442e34397cb46739ef6e36048d6f45
 SHA1 (patch-gcc_config_arm_elf.h) = 57748157084319cb92d892f2ea5b2f3355567551
 SHA1 (patch-gcc_config_arm_netbsd-eabi.h) = 85eb89de6f2e64fac50251f06d7e4eab35903dae
 SHA1 (patch-gcc_config_arm_netbsd-elf.h) = 568f537d624199ef9f9f56088fe4fff7e946b2e2
+SHA1 (patch-gcc_config_darwin-driver.cc) = a02dcb37b47c04dc0a6cc95b562651fb56f2331f
+SHA1 (patch-gcc_config_darwin-protos.h) = f97bafbfacee04eb686d73343541e44150da7bef
+SHA1 (patch-gcc_config_darwin-sections.def) = d652d541dc15bac80e674bf174abaae064325bc6
+SHA1 (patch-gcc_config_darwin.cc) = 1b81349a8c1703fb028c6e6f8be31ec5c3772c98
+SHA1 (patch-gcc_config_darwin.h) = 0183eba18473af366501b10a178a42ce677d567e
+SHA1 (patch-gcc_config_darwin.opt) = 5f8a8cb8f9cf3b3e4dac68c46d965cd1eda94921
 SHA1 (patch-gcc_config_i386_t-netbsd64) = 914b4d2fd65f5e46681aa2ea592d0bc75299f09a
 SHA1 (patch-gcc_config_netbsd.h) = ada05409eacb33bc1e7a659f3090f2f43551a35d
-SHA1 (patch-gcc_targhooks.cc) = a390b35d31afa207cee108c0642ce954c6291941
+SHA1 (patch-gcc_configure) = 2385e4a226671add690820d1145c76339ba3685b
+SHA1 (patch-gcc_configure.ac) = e60df53f5c3c0c19f68000d893519a60cfdf0bcf
+SHA1 (patch-gcc_cp_decl2.cc) = 5510717ac2fa61f7f238466710af6d762c561365
+SHA1 (patch-gcc_cp_lex.cc) = ce4efb0c05e455785a48e44f692fa45f79a0d75e
+SHA1 (patch-gcc_cp_parser.cc) = d622207e49aeb691449e720d56536828a8f80b9b
+SHA1 (patch-gcc_cumulative-args.h) = 75dfa81023f3c5dcabd38f8d1607a7dab1663249
+SHA1 (patch-gcc_doc_invoke.texi) = db61ed3420a219f8c640dce1cc07756416775888
+SHA1 (patch-gcc_doc_tm.texi) = 79c13d08af03f1fb871d99f3042f505b76c8ef81
+SHA1 (patch-gcc_doc_tm.texi.in) = ae5f2479284fb2557e11dc1503e3e71bd3d71c7d
+SHA1 (patch-gcc_exec-tool.in) = ae5f988c063602c41fc1ac8639d8d83962152c99
+SHA1 (patch-gcc_explow.cc) = a5b1da5a7c49fff46e4f4df91df24c253ee4d73d
+SHA1 (patch-gcc_explow.h) = 61dc56da27089e2036c6131242632a280d27d762
+SHA1 (patch-gcc_function.cc) = cdbacf95d93d1015d37599163aba4cebe374291c
+SHA1 (patch-gcc_function.h) = 61d16b5514917f84e373d08521dc99b3e8c37ffe
+SHA1 (patch-gcc_ginclude_stddef.h) = f8b31996d20a68f93073bd7faeb0b774899f474e
+SHA1 (patch-gcc_opts.cc) = 17910e702eae339647c6d6dd9de436019f55bc2d
+SHA1 (patch-gcc_target.def) = 9070aa0bf3bd1da611529a1ab351f8e2da15b7b1
+SHA1 (patch-gcc_target.h) = 3f1691da094d4b3b69c1dd51fd27f4f72b0caba8
+SHA1 (patch-gcc_targhooks.cc) = 54c521dcdf5c213cf6f5a281f04c6cc62589ecb5
+SHA1 (patch-gcc_targhooks.h) = 0ddb107a3759108d5ae2da1ae62b2742f86b42b7
 SHA1 (patch-isl_configure) = a6295c509bdc82e8b54d7dec5252994532463091
 SHA1 (patch-libffi_configure) = 919bbe094e3ce547a0186eeaddb20a662595f79a
 SHA1 (patch-libffi_testsuite_libffi.call_float2.c) = 89e2dd6aaf2c1f75726f02362d8a8bf7178694ea
-SHA1 (patch-libgcc_config.host) = c9ea8bda0e6a1a8c4c39e4b8320a34b86e1da278
+SHA1 (patch-libgcc_config.host) = 2a0929a15d6cc0ac7ad4ec54b81defbb018c54e3
+SHA1 (patch-libgcc_config_aarch64_____arm__sme__state.S) = 41cd05207f2f57e70ee06847a6b2756b73d31c72
+SHA1 (patch-libgcc_config_aarch64_____arm__tpidr2__restore.S) = 9dd42d6a53c784e2c1303c57bbfa26a69bc806a9
+SHA1 (patch-libgcc_config_aarch64_____arm__tpidr2__save.S) = 2e72142104a89b3c2833eae401e1dcaf044b8233
+SHA1 (patch-libgcc_config_aarch64_____arm__za__disable.S) = 4e83860fc2ae7ebf279e7d237d369165a54f55b8
+SHA1 (patch-libgcc_config_aarch64_aarch64-asm.h) = 1251cbabc7d3c7d35baaead23ae2b788db896eef
+SHA1 (patch-libgcc_config_aarch64_lse.S) = fa0428284cec93ae85f56f6690b50e8c8b3a4d88
+SHA1 (patch-libgcc_config_aarch64_sfp-machine.h) = a7f1c8a9eb5eb02103e0ea7edf12c8f10af74f2f
+SHA1 (patch-libgcc_config_aarch64_t-darwin) = 6da2ebe823e6eabd2013180ffc30bb9ab5e42926
+SHA1 (patch-libgcc_config_libbid_bid__binarydecimal.c) = b13189b9860f454971abe5542ca66f14c24dbbf8
 SHA1 (patch-libgcc_crtstuff.c) = dd7808497b058bcac4aa8d91388d6a7685bb5e5c
 SHA1 (patch-libgcc_enable-execute-stack-mprotect.c) = 9cec951183f5092d14d7736f73f50523cdba7592
-SHA1 (patch-libgcobol_configure.tgt) = d5a0e35e03ff8c835cbcb6cf17725ae82fd727af
+SHA1 (patch-libgcobol_configure.tgt) = 3c3771e26cb5b1f52d054d09e36326710891242d
 SHA1 (patch-libgfortran_io_io.h) = d44676239a7f45e42054d24bd5224f43c20055c0
+SHA1 (patch-libitm_config_aarch64_sjlj.S) = 80335ab84f4f01ecda2713f35b7d0ef33aed7b72
+SHA1 (patch-libitm_configure.tgt) = eed87d435f44628901eaa88cff6ad76ca170b28b
+SHA1 (patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d) = 481be1eb99c081e8b7d3c7c21f0126d9ba111d70
 SHA1 (patch-libquadmath_printf_quadmath-printf.c) = 78e09f1e6d61ee57cee83275093cf46b2335d204
 SHA1 (patch-libquadmath_strtod_strtod__l.c) = 6142c10d34174174cce7f06c37eab04dc431b2dc
+SHA1 (patch-libsanitizer_configure.tgt) = db1b5c935c9afab17d779ed5206bd839b454125a
+SHA1 (patch-libsanitizer_sanitizer__common_sanitizer__common.h) = edb6214b9e68cca8a7511b4fb500a52c440a80c4
+SHA1 (patch-libsanitizer_sanitizer__common_sanitizer__procmaps__mac.cpp) = 2509e6881a8026002005adebfa0ce5df2024b0a3
 SHA1 (patch-zlib_zutil.h) = ef6f2439488a1b97bca9c33fc16e2e7447f0d158

Index: pkgsrc/lang/gcc15/Makefile.common
diff -u pkgsrc/lang/gcc15/Makefile.common:1.2 pkgsrc/lang/gcc15/Makefile.common:1.3
--- pkgsrc/lang/gcc15/Makefile.common:1.2       Thu Jul 17 05:37:09 2025
+++ pkgsrc/lang/gcc15/Makefile.common   Sun Jul 19 11:17:41 2026
@@ -1,8 +1,8 @@
-# $NetBSD: Makefile.common,v 1.2 2025/07/17 05:37:09 wiz Exp $
+# $NetBSD: Makefile.common,v 1.3 2026/07/19 11:17:41 adam Exp $
 # used by lang/gcc15-libjit/Makefile
 
-GCC_PKGNAME=           gcc15
-.include               "version.mk"
+GCC_PKGNAME=   gcc15
+.include       "version.mk"
 
 DISTNAME=      gcc-${GCC15_DIST_VERSION}
 CATEGORIES=    lang
@@ -42,7 +42,6 @@ CONFIGURE_ARGS+=      --disable-libstdcxx-pch
 # error: 'for' loop initial declarations are only allowed in C99 mode
 FORCE_C_STD=           gnu99
 USE_CXX_FEATURES+=     c++14
-#FORCE_CXX_STD=                c++11
 
 UNLIMIT_RESOURCES+=    datasize
 UNLIMIT_RESOURCES+=    stacksize
@@ -58,6 +57,10 @@ CHECK_PORTABILITY_SKIP+=     gcc/configure.o
 BUILDLINK_TRANSFORM+=  rm:-nodefaultrpaths
 CONFIGURE_ARGS+=       --disable-darwin-at-rpath
 .endif
+# This has to be done manually to avoid conflicts.
+#PATCHFILES=           gcc-15.3.0.diff
+#PATCH_SITES=          https://raw.githubusercontent.com/Homebrew/homebrew-core/6e8384b/Patches/gcc/
+#PATCH_DIST_STRIP=     -p1
 
 ## For graphite support.
 .if !empty(PKG_OPTIONS:Mgcc-graphite)
Index: pkgsrc/lang/gcc15/options.mk
diff -u pkgsrc/lang/gcc15/options.mk:1.2 pkgsrc/lang/gcc15/options.mk:1.3
--- pkgsrc/lang/gcc15/options.mk:1.2    Sat Nov  8 07:04:02 2025
+++ pkgsrc/lang/gcc15/options.mk        Sun Jul 19 11:17:41 2026
@@ -1,4 +1,4 @@
-# $NetBSD: options.mk,v 1.2 2025/11/08 07:04:02 mrg Exp $
+# $NetBSD: options.mk,v 1.3 2026/07/19 11:17:41 adam Exp $
 
 PKG_OPTIONS_VAR=       PKG_OPTIONS.${GCC_PKGNAME}
 PKG_SUPPORTED_OPTIONS= nls gcc-inplace-math gcc-c++ gcc-cobol gcc-fortran \
@@ -11,10 +11,10 @@ PKG_SUGGESTED_OPTIONS=      gcc-c++ gcc-fortr
 
 .if ${OPSYS} == "NetBSD"
 PKG_SUGGESTED_OPTIONS+=        nls
-. if ${MACHINE_PLATFORM:M*-x86_64} || ${MACHINE_PLATFORM:M*-aarch64}
+.  if ${MACHINE_PLATFORM:M*-x86_64} || ${MACHINE_PLATFORM:M*-aarch64}
 # Test riscv64 as well, it should work.
 PKG_SUGGESTED_OPTIONS+=        gcc-cobol
-. endif
+.  endif
 .elif ${OPSYS} == "Linux"
 PKG_SUGGESTED_OPTIONS+=        nls
 .elif ${OPSYS} == "DragonFly"
Index: pkgsrc/lang/gcc15/version.mk
diff -u pkgsrc/lang/gcc15/version.mk:1.2 pkgsrc/lang/gcc15/version.mk:1.3
--- pkgsrc/lang/gcc15/version.mk:1.2    Sat Aug  9 15:53:10 2025
+++ pkgsrc/lang/gcc15/version.mk        Sun Jul 19 11:17:41 2026
@@ -1,3 +1,3 @@
-# $NetBSD: version.mk,v 1.2 2025/08/09 15:53:10 wiz Exp $
+# $NetBSD: version.mk,v 1.3 2026/07/19 11:17:41 adam Exp $
 
-GCC15_DIST_VERSION:=   15.2.0
+GCC15_DIST_VERSION:=   15.3.0

Index: pkgsrc/lang/gcc15-libs/Makefile
diff -u pkgsrc/lang/gcc15-libs/Makefile:1.5 pkgsrc/lang/gcc15-libs/Makefile:1.6
--- pkgsrc/lang/gcc15-libs/Makefile:1.5 Fri Jul 10 21:28:41 2026
+++ pkgsrc/lang/gcc15-libs/Makefile     Sun Jul 19 11:17:45 2026
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.5 2026/07/10 21:28:41 tsutsui Exp $
+# $NetBSD: Makefile,v 1.6 2026/07/19 11:17:45 adam Exp $
 
 GCC_PKGNAME=   gcc15
 .include       "../../lang/${GCC_PKGNAME}/version.mk"
@@ -9,7 +9,7 @@ PKGNAME=        ${GCC_PKGNAME}-libs-${GCC15_DIS
 ## The PKGREVISION of this package needs to be at least 1 more than the
 ## PKGREVISION of the lang/gcc15 package so that with the dependence pattern
 ## '{gcc15,gcc15-libs}>=15.1.*' pkg_add will choose gcc15-libs over gcc15.
-PKGREVISION=   3
+PKGREVISION=   1
 
 CATEGORIES=    lang
 MASTER_SITES=  # empty

Index: pkgsrc/lang/gcc15/patches/patch-configure
diff -u pkgsrc/lang/gcc15/patches/patch-configure:1.1 pkgsrc/lang/gcc15/patches/patch-configure:1.2
--- pkgsrc/lang/gcc15/patches/patch-configure:1.1       Sat Nov  8 07:04:02 2025
+++ pkgsrc/lang/gcc15/patches/patch-configure   Sun Jul 19 11:17:41 2026
@@ -1,10 +1,12 @@
-$NetBSD: patch-configure,v 1.1 2025/11/08 07:04:02 mrg Exp $
+$NetBSD: patch-configure,v 1.2 2026/07/19 11:17:41 adam Exp $
 
 Enable COBOL on NetBSD amd64/arm64/riscv64.
 
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
 
---- configure.orig     2025-08-07 23:51:39.874338130 -0700
-+++ configure  2025-11-05 19:28:09.763698065 -0800
+--- configure.orig     2026-06-12 06:10:23.755719904 +0000
++++ configure
 @@ -3581,14 +3581,14 @@ case ,${enable_languages}, in
      ;;
    *)
@@ -22,3 +24,12 @@ Enable COBOL on NetBSD amd64/arm64/riscv
          ;;
        *-*-*)
          unsupported_languages="$unsupported_languages cobol"
+@@ -3599,6 +3599,8 @@ esac
+
+ # Disable libffi for some systems.
+ case "${target}" in
++  aarch64*-*-darwin2*)
++    ;;
+   powerpc-*-darwin*)
+     ;;
+   i[3456789]86-*-darwin*)
Index: pkgsrc/lang/gcc15/patches/patch-configure.ac
diff -u pkgsrc/lang/gcc15/patches/patch-configure.ac:1.1 pkgsrc/lang/gcc15/patches/patch-configure.ac:1.2
--- pkgsrc/lang/gcc15/patches/patch-configure.ac:1.1    Sat Nov  8 07:04:02 2025
+++ pkgsrc/lang/gcc15/patches/patch-configure.ac        Sun Jul 19 11:17:41 2026
@@ -1,10 +1,12 @@
-$NetBSD: patch-configure.ac,v 1.1 2025/11/08 07:04:02 mrg Exp $
+$NetBSD: patch-configure.ac,v 1.2 2026/07/19 11:17:41 adam Exp $
 
 Enable COBOL on NetBSD amd64/arm64/riscv64.
 
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
 
---- configure.ac.orig  2025-08-07 23:51:39.874338130 -0700
-+++ configure.ac       2025-11-05 19:22:39.706058829 -0800
+--- configure.ac.orig  2026-06-12 06:09:05.615510417 +0000
++++ configure.ac
 @@ -801,14 +801,14 @@ case ,${enable_languages}, in
      ;;
    *)
@@ -22,3 +24,12 @@ Enable COBOL on NetBSD amd64/arm64/riscv
          ;;
        *-*-*)
          unsupported_languages="$unsupported_languages cobol"
+@@ -819,6 +819,8 @@ esac
+
+ # Disable libffi for some systems.
+ case "${target}" in
++  aarch64*-*-darwin2*)
++    ;;
+   powerpc-*-darwin*)
+     ;;
+   i[[3456789]]86-*-darwin*)
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config.gcc
diff -u pkgsrc/lang/gcc15/patches/patch-gcc_config.gcc:1.1 pkgsrc/lang/gcc15/patches/patch-gcc_config.gcc:1.2
--- pkgsrc/lang/gcc15/patches/patch-gcc_config.gcc:1.1  Mon Aug  4 02:48:24 2025
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config.gcc      Sun Jul 19 11:17:42 2026
@@ -1,9 +1,51 @@
-$NetBSD: patch-gcc_config.gcc,v 1.1 2025/08/04 02:48:24 mrg Exp $
+$NetBSD: patch-gcc_config.gcc,v 1.2 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
 
 Enable multilib support on amd64.
 
---- gcc/config.gcc.orig        2025-04-25 01:18:00.000000000 -0700
-+++ gcc/config.gcc     2025-08-03 17:22:06.592442114 -0700
+--- gcc/config.gcc.orig        2026-06-12 06:09:06.107518032 +0000
++++ gcc/config.gcc
+@@ -1174,13 +1174,22 @@ case ${target} in
+   ;;
+ esac
+
+-# Figure out if we need to enable heap trampolines by default
++# Figure out if we need to enable heap trampolines
++# and variadic functions handling.
+ case ${target} in
++aarch64*-*-darwin2*)
++  # This applies to arm64 Darwin variadic funtions.
++  tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=1"
++  # Executable stack is forbidden.
++  tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=1"
++  ;;
+ *-*-darwin2*)
++  tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0"
+   # Currently, we do this for macOS 11 and above.
+   tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=1"
+   ;;
+ *)
++  tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0"
+   tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=0"
+   ;;
+ esac
+@@ -1224,6 +1233,14 @@ aarch64*-*-elf | aarch64*-*-fuchsia* | a
+       done
+       TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
+       ;;
++aarch64-*-darwin* )
++      tm_file="${tm_file} aarch64/aarch64-errata.h"
++      tmake_file="${tmake_file} aarch64/t-aarch64 aarch64/t-aarch64-darwin"
++      tm_defines="${tm_defines} TARGET_DEFAULT_ASYNC_UNWIND_TABLES=1"
++      tm_defines="${tm_defines} DISABLE_AARCH64_AS_CRC_BUGFIX=1"
++      # Choose a default CPU version that will work for all current releases.
++      with_cpu=${with_cpu:-apple-m1}
++      ;;
+ aarch64*-*-freebsd*)
+       tm_file="${tm_file} elfos.h ${fbsd_tm_file}"
+       tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-errata.h aarch64/aarch64-freebsd.h"
 @@ -1992,6 +1992,7 @@
        ;;
  x86_64-*-netbsd*)
Index: pkgsrc/lang/gcc15/patches/patch-gcc_targhooks.cc
diff -u pkgsrc/lang/gcc15/patches/patch-gcc_targhooks.cc:1.1 pkgsrc/lang/gcc15/patches/patch-gcc_targhooks.cc:1.2
--- pkgsrc/lang/gcc15/patches/patch-gcc_targhooks.cc:1.1        Fri Jul 10 21:28:41 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_targhooks.cc    Sun Jul 19 11:17:44 2026
@@ -1,11 +1,58 @@
-$NetBSD: patch-gcc_targhooks.cc,v 1.1 2026/07/10 21:28:41 tsutsui Exp $
+$NetBSD: patch-gcc_targhooks.cc,v 1.2 2026/07/19 11:17:44 adam Exp $
 
-- Pull NetBSD local change for gcc's default_hidden_stack_protect_fail()
-  for NetBSD/i386
-   https://cvsweb.netbsd.org/bsdweb.cgi/src/external/gpl3/gcc/dist/gcc/targhooks.cc.diff?r1=1.1.1.2;r2=1.4
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
 
---- gcc/targhooks.cc.orig      2026-07-10 18:51:24.043844508 +0000
+Pull NetBSD local change for gcc's default_hidden_stack_protect_fail() for NetBSD/i386.
+https://cvsweb.netbsd.org/bsdweb.cgi/src/external/gpl3/gcc/dist/gcc/targhooks.cc.diff?r1=1.1.1.2;r2=1.4
+
+--- gcc/targhooks.cc.orig      2026-06-12 06:09:06.827529177 +0000
 +++ gcc/targhooks.cc
+@@ -163,6 +163,15 @@ default_promote_function_mode_always_pro
+ }
+
+ machine_mode
++default_promote_function_mode_ca (cumulative_args_t, function_arg_info arg,
++                                const_tree funtype, int *punsignedp,
++                                int for_return)
++{
++  return promote_function_mode (arg.type, arg.mode, punsignedp,
++                              funtype, for_return);
++}
++
++machine_mode
+ default_cc_modes_compatible (machine_mode m1, machine_mode m2)
+ {
+   if (m1 == m2)
+@@ -890,12 +899,28 @@ default_function_arg_boundary (machine_m
+ }
+
+ unsigned int
++default_function_arg_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED,
++                                const_tree type ATTRIBUTE_UNUSED,
++                                cumulative_args_t ca ATTRIBUTE_UNUSED)
++{
++  return default_function_arg_boundary (mode, type);
++}
++
++unsigned int
+ default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED,
+                                    const_tree type ATTRIBUTE_UNUSED)
+ {
+   return PARM_BOUNDARY;
+ }
+
++unsigned int
++default_function_arg_round_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED,
++                                      const_tree type ATTRIBUTE_UNUSED,
++                                      cumulative_args_t ca ATTRIBUTE_UNUSED)
++{
++  return default_function_arg_round_boundary (mode, type);
++}
++
+ void
+ hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED)
+ {
 @@ -1000,7 +1000,17 @@ default_hidden_stack_protect_fail (void)
        DECL_ARTIFICIAL (t) = 1;
        DECL_IGNORED_P (t) = 1;
Index: pkgsrc/lang/gcc15/patches/patch-libgcc_config.host
diff -u pkgsrc/lang/gcc15/patches/patch-libgcc_config.host:1.1 pkgsrc/lang/gcc15/patches/patch-libgcc_config.host:1.2
--- pkgsrc/lang/gcc15/patches/patch-libgcc_config.host:1.1      Sat Nov  8 07:04:02 2025
+++ pkgsrc/lang/gcc15/patches/patch-libgcc_config.host  Sun Jul 19 11:17:44 2026
@@ -1,11 +1,80 @@
-$NetBSD: patch-libgcc_config.host,v 1.1 2025/11/08 07:04:02 mrg Exp $
+$NetBSD: patch-libgcc_config.host,v 1.2 2026/07/19 11:17:44 adam Exp $
 
-Fix NetBSD/arm64.
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
 
+Fix NetBSD/arm64.
 
---- libgcc/config.host.orig    2025-08-07 23:51:44.833420855 -0700
-+++ libgcc/config.host 2025-11-07 03:15:28.811881325 -0800
-@@ -424,6 +424,7 @@ aarch64*-*-freebsd*)
+--- libgcc/config.host.orig    2026-06-12 06:09:09.987578090 +0000
++++ libgcc/config.host
+@@ -85,7 +85,7 @@ m32c*-*-*)
+         cpu_type=m32c
+       tmake_file=t-fdpbit
+         ;;
+-aarch64*-*-*)
++aarch64*-*-* | arm64*-*-*)
+       cpu_type=aarch64
+       ;;
+ alpha*-*-*)
+@@ -236,16 +236,16 @@ case ${host} in
+   esac
+   tmake_file="$tmake_file t-slibgcc-darwin"
+   case ${host} in
+-    x86_64-*-darwin2[0-2]*)
+-      tmake_file="t-darwin-min-11 t-darwin-libgccs1 $tmake_file"
+-      ;;
+     *-*-darwin2*)
+       tmake_file="t-darwin-min-11 $tmake_file"
+       ;;
+     *-*-darwin1[89]*)
+-      tmake_file="t-darwin-min-8 t-darwin-libgccs1 $tmake_file"
++      tmake_file="t-darwin-min-8 $tmake_file"
++      ;;
++    *-*-darwin1[67]*)
++      tmake_file="t-darwin-min-5 $tmake_file"
+       ;;
+-    *-*-darwin9* | *-*-darwin1[0-7]*)
++    *-*-darwin9* | *-*-darwin1[0-5]*)
+       tmake_file="t-darwin-min-5 t-darwin-libgccs1 $tmake_file"
+       ;;
+     *-*-darwin[4-8]*)
+@@ -280,7 +280,7 @@ case ${host} in
+   if test "x$enable_darwin_at_rpath" = "xyes"; then
+     tmake_file="$tmake_file t-darwin-rpath "
+   fi
+-  extra_parts="crt3.o libd10-uwfef.a crttms.o crttme.o libemutls_w.a"
++  extra_parts="crt3.o crttms.o crttme.o libemutls_w.a "
+   ;;
+ *-*-dragonfly*)
+   tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip"
+@@ -386,8 +386,8 @@ case ${host} in
+ esac
+ 
+ case ${host} in
+-*-*-darwin* | *-*-dragonfly* | *-*-freebsd* | *-*-netbsd* | *-*-openbsd* | \
+-  *-*-solaris2*)
++i[34567]86-*-darwin* | powerpc*-*-darwin* | x86_64-*-darwin* | \
++*-*-dragonfly* | *-*-freebsd* | *-*-netbsd* | *-*-openbsd* | *-*-solaris2*)
+   enable_execute_stack=enable-execute-stack-mprotect.c
+   ;;
+ i[34567]86-*-mingw* | x86_64-*-mingw*)
+@@ -412,6 +412,15 @@ aarch64*-*-elf | aarch64*-*-rtems*)
+       md_unwind_def_header=aarch64/aarch64-unwind-def.h
+       md_unwind_header=aarch64/aarch64-unwind.h
+       ;;
++aarch64*-*-darwin*)
++      extra_parts="$extra_parts crtfastmath.o libheapt_w.a"
++      tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
++      tmake_file="${tmake_file} ${cpu_type}/t-lse"
++      tmake_file="${tmake_file} t-crtfm t-dfprules"
++      tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp"
++      tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline"
++      tmake_file="${tmake_file} ${cpu_type}/t-no-eh"
++      ;;
+ aarch64*-*-freebsd*)
+       extra_parts="$extra_parts crtfastmath.o"
+       tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
+@@ -424,6 +433,7 @@ aarch64*-*-freebsd*)
  aarch64*-*-netbsd*)
        extra_parts="$extra_parts crtfastmath.o"
        tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
@@ -13,3 +82,35 @@ Fix NetBSD/arm64.
        tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm"
        tmake_file="${tmake_file} t-dfprules"
        md_unwind_def_header=aarch64/aarch64-unwind-def.h
+@@ -740,14 +750,14 @@ i[34567]86-*-darwin*)
+       tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi"
+       tm_file="$tm_file i386/darwin-lib.h"
+       extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o"
+-      extra_parts="$extra_parts crtfastmath.o libheapt_w.a"
++      extra_parts="$extra_parts crtfastmath.o libd10-uwfef.a libheapt_w.a"
+       tmake_file="${tmake_file} i386/t-heap-trampoline"
+       ;;
+ x86_64-*-darwin*)
+       tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi"
+       tm_file="$tm_file i386/darwin-lib.h"
+       extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o"
+-      extra_parts="$extra_parts crtfastmath.o libheapt_w.a"
++      extra_parts="$extra_parts crtfastmath.o libd10-uwfef.a libheapt_w.a"
+       tmake_file="${tmake_file} i386/t-heap-trampoline"
+       ;;
+ i[34567]86-*-elfiamcu)
+@@ -1221,12 +1231,14 @@ powerpc-*-darwin*)
+       # We build the darwin10 EH shim for Rosetta (running on x86 machines).
+       tm_file="$tm_file i386/darwin-lib.h"
+       tmake_file="$tmake_file rs6000/t-ppc64-fp rs6000/t-ibm-ldouble"
++      extra_parts="$extra_parts libd10-uwfef.a "
+       extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o"
+       ;;
+ powerpc64-*-darwin*)
+       # We build the darwin10 EH shim for Rosetta (running on x86 machines).
+       tm_file="$tm_file i386/darwin-lib.h"
+       tmake_file="$tmake_file rs6000/t-darwin64 rs6000/t-ibm-ldouble"
++      extra_parts="$extra_parts libd10-uwfef.a "
+       extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o"
+       ;;
+ powerpc*-*-freebsd*)
Index: pkgsrc/lang/gcc15/patches/patch-libgcobol_configure.tgt
diff -u pkgsrc/lang/gcc15/patches/patch-libgcobol_configure.tgt:1.1 pkgsrc/lang/gcc15/patches/patch-libgcobol_configure.tgt:1.2
--- pkgsrc/lang/gcc15/patches/patch-libgcobol_configure.tgt:1.1 Sat Nov  8 07:04:02 2025
+++ pkgsrc/lang/gcc15/patches/patch-libgcobol_configure.tgt     Sun Jul 19 11:17:45 2026
@@ -1,16 +1,18 @@
-$NetBSD: patch-libgcobol_configure.tgt,v 1.1 2025/11/08 07:04:02 mrg Exp $
+$NetBSD: patch-libgcobol_configure.tgt,v 1.2 2026/07/19 11:17:45 adam Exp $
 
-Enable libgcobol on NetBSD amd64, arm64, and riscv64.
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
 
+Enable libgcobol on NetBSD amd64, arm64, and riscv64.
 
---- libgcobol/configure.tgt.orig       2025-08-07 23:51:44.929422457 -0700
-+++ libgcobol/configure.tgt    2025-11-06 11:01:55.070054980 -0800
+--- libgcobol/configure.tgt.orig       2026-06-12 06:09:10.070579374 +0000
++++ libgcobol/configure.tgt
 @@ -26,7 +26,7 @@
  LIBGCOBOL_SUPPORTED=no
- 
+
  case "${target}" in
 -    aarch64*-*-linux*)
-+    aarch64*-*-linux* | aarch64*-*-netbsd*)
++    aarch64*-*-linux* | aarch64-*-darwin* | aarch64*-*-netbsd*)
        LIBGCOBOL_SUPPORTED=yes
        ;;
      powerpc64le-*-linux*)
@@ -29,3 +31,4 @@ Enable libgcobol on NetBSD amd64, arm64,
        if test x$ac_cv_sizeof_void_p = x8; then
                LIBGCOBOL_SUPPORTED=yes
        fi
+

Added files:

Index: pkgsrc/lang/gcc15/patches/patch-fixincludes_fixincl.x
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-fixincludes_fixincl.x:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-fixincludes_fixincl.x       Sun Jul 19 11:17:42 2026
@@ -0,0 +1,209 @@
+$NetBSD: patch-fixincludes_fixincl.x,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- fixincludes/fixincl.x.orig 2026-06-12 06:09:05.643510851 +0000
++++ fixincludes/fixincl.x
+@@ -2,11 +2,11 @@
+  *
+  * DO NOT EDIT THIS FILE   (fixincl.x)
+  *
+- * It has been AutoGen-ed  August 28, 2025 at 05:57:29 PM by AutoGen 5.18.16
++ * It has been AutoGen-ed  June 13, 2026 at 07:59:45 AM by AutoGen 5.18.16
+  * From the definitions    inclhack.def
+  * and the template file   fixincl
+  */
+-/* DO NOT MERGE THIS FILE, EITHER Thu Aug 28 17:57:29 BST 2025
++/* DO NOT MERGE THIS FILE, EITHER Sat Jun 13 07:59:45 BST 2026
+  *
+  * You must regenerate it.  Use the ./genfixes script.
+  *
+@@ -15,7 +15,7 @@
+  * certain ANSI-incompatible system header files which are fixed to work
+  * correctly with ANSI C and placed in a directory that GNU C will search.
+  *
+- * This file contains 274 fixup descriptions.
++ * This file contains 272 fixup descriptions.
+  *
+  * See README for more information.
+  *
+@@ -269,56 +269,6 @@ static const char* apzAab_Darwin7_9_Long
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * *
+  *
+- *  Description of Darwin_Api_Availability fix
+- */
+-tSCC zDarwin_Api_AvailabilityName[] =
+-     "darwin_api_availability";
+-
+-/*
+- *  File name selection pattern
+- */
+-tSCC zDarwin_Api_AvailabilityList[] =
+-  "os/availability.h\0";
+-/*
+- *  Machine/OS name selection pattern
+- */
+-tSCC* apzDarwin_Api_AvailabilityMachs[] = {
+-        "*-*-darwin*",
+-        (const char*)NULL };
+-
+-/*
+- *  content selection pattern - do fix if pattern found
+- */
+-tSCC zDarwin_Api_AvailabilitySelect0[] =
+-       " *#define __API_AVAILABLE.*\n\
+- *#define __API_DEPRECATED.*\n\
+- *#define __API_DEPRECATED_WITH_REPLACEMENT.*\n\
+- *#define __API_UNAVAILABLE.*\n";
+-
+-/*
+- *  content bypass pattern - skip fix if pattern found
+- */
+-tSCC zDarwin_Api_AvailabilityBypass0[] =
+-       "__IPHONE_OS_VERSION_MIN_REQUIRED";
+-
+-#define    DARWIN_API_AVAILABILITY_TEST_CT  2
+-static tTestDesc aDarwin_Api_AvailabilityTests[] = {
+-  { TT_NEGREP,   zDarwin_Api_AvailabilityBypass0, (regex_t*)NULL },
+-  { TT_EGREP,    zDarwin_Api_AvailabilitySelect0, (regex_t*)NULL }, };
+-
+-/*
+- *  Fix Command Arguments for Darwin_Api_Availability
+- */
+-static const char* apzDarwin_Api_AvailabilityPatch[] = {
+-    "format",
+-    "    #define API_AVAILABLE(...)\n\
+-    #define API_DEPRECATED(...)\n\
+-    #define API_DEPRECATED_WITH_REPLACEMENT(...)\n\
+-    #define API_UNAVAILABLE(...)\n",
+-    (char*)NULL };
+-
+-/* * * * * * * * * * * * * * * * * * * * * * * * * *
+- *
+  *  Description of Aab_Fd_Zero_Asm_Posix_Types_H fix
+  */
+ tSCC zAab_Fd_Zero_Asm_Posix_Types_HName[] =
+@@ -2765,51 +2715,6 @@ extern \"C\" {\n\
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * *
+  *
+- *  Description of Darwin_Availabilityinternal fix
+- */
+-tSCC zDarwin_AvailabilityinternalName[] =
+-     "darwin_availabilityinternal";
+-
+-/*
+- *  File name selection pattern
+- */
+-tSCC zDarwin_AvailabilityinternalList[] =
+-  "AvailabilityInternal.h\0";
+-/*
+- *  Machine/OS name selection pattern
+- */
+-tSCC* apzDarwin_AvailabilityinternalMachs[] = {
+-        "*-*-darwin*",
+-        (const char*)NULL };
+-
+-/*
+- *  content selection pattern - do fix if pattern found
+- */
+-tSCC zDarwin_AvailabilityinternalSelect0[] =
+-       "#define[ \t]+(__API_[ADU]\\([^)]*\\)).*";
+-
+-#define    DARWIN_AVAILABILITYINTERNAL_TEST_CT  1
+-static tTestDesc aDarwin_AvailabilityinternalTests[] = {
+-  { TT_EGREP,    zDarwin_AvailabilityinternalSelect0, (regex_t*)NULL }, };
+-
+-/*
+- *  Fix Command Arguments for Darwin_Availabilityinternal
+- */
+-static const char* apzDarwin_AvailabilityinternalPatch[] = {
+-    "format",
+-    "#if defined(__has_attribute)\n\
+-  #if __has_attribute(availability)\n\
+-%0\n\
+-  #else\n\
+-    #define %1\n\
+-  #endif\n\
+-#else\n\
+-    #define %1\n\
+-#endif",
+-    (char*)NULL };
+-
+-/* * * * * * * * * * * * * * * * * * * * * * * * * *
+- *
+  *  Description of Darwin_9_Long_Double_Funcs_2 fix
+  */
+ tSCC zDarwin_9_Long_Double_Funcs_2Name[] =
+@@ -8988,7 +8893,7 @@ tSCC* apzStdio_Stdarg_HMachs[] = {
+  *  content bypass pattern - skip fix if pattern found
+  */
+ tSCC zStdio_Stdarg_HBypass0[] =
+-       "include.*(stdarg.h|machine/ansi.h)";
++       "include.*(stdarg.h|machine/ansi.h|_stdio.h)";
+
+ #define    STDIO_STDARG_H_TEST_CT  1
+ static tTestDesc aStdio_Stdarg_HTests[] = {
+@@ -9026,7 +8931,7 @@ tSCC* apzStdio_Va_ListMachs[] = {
+  *  content bypass pattern - skip fix if pattern found
+  */
+ tSCC zStdio_Va_ListBypass0[] =
+-       "__gnuc_va_list|_BSD_VA_LIST_|__DJ_va_list|_G_va_list";
++       "__gnuc_va_list|_BSD_VA_LIST_|__DJ_va_list|_G_va_list|_stdio.h";
+
+ #define    STDIO_VA_LIST_TEST_CT  1
+ static tTestDesc aStdio_Va_ListTests[] = {
+@@ -11209,9 +11114,9 @@ static const char* apzX11_SprintfPatch[]
+  *
+  *  List of all fixes
+  */
+-#define REGEX_COUNT          319
++#define REGEX_COUNT          316
+ #define MACH_LIST_SIZE_LIMIT 187
+-#define FIX_COUNT            274
++#define FIX_COUNT            272
+
+ /*
+  *  Enumerate the fixes
+@@ -11220,7 +11125,6 @@ typedef enum {
+     AAB_AIX_STDIO_FIXIDX,
+     AAB_AIX_FCNTL_FIXIDX,
+     AAB_DARWIN7_9_LONG_DOUBLE_FUNCS_FIXIDX,
+-    DARWIN_API_AVAILABILITY_FIXIDX,
+     AAB_FD_ZERO_ASM_POSIX_TYPES_H_FIXIDX,
+     AAB_FD_ZERO_GNU_TYPES_H_FIXIDX,
+     AAB_FD_ZERO_SELECTBITS_H_FIXIDX,
+@@ -11282,7 +11186,6 @@ typedef enum {
+     CTRL_QUOTES_DEF_FIXIDX,
+     CTRL_QUOTES_USE_FIXIDX,
+     CXX_UNREADY_FIXIDX,
+-    DARWIN_AVAILABILITYINTERNAL_FIXIDX,
+     DARWIN_9_LONG_DOUBLE_FUNCS_2_FIXIDX,
+     DARWIN_EXTERNC_FIXIDX,
+     DARWIN_GCC4_BREAKAGE_FIXIDX,
+@@ -11509,11 +11412,6 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
+      AAB_DARWIN7_9_LONG_DOUBLE_FUNCS_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT,
+      aAab_Darwin7_9_Long_Double_FuncsTests,   apzAab_Darwin7_9_Long_Double_FuncsPatch, 0 },
+
+-  {  zDarwin_Api_AvailabilityName,    zDarwin_Api_AvailabilityList,
+-     apzDarwin_Api_AvailabilityMachs,
+-     DARWIN_API_AVAILABILITY_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+-     aDarwin_Api_AvailabilityTests,   apzDarwin_Api_AvailabilityPatch, 0 },
+-
+   {  zAab_Fd_Zero_Asm_Posix_Types_HName,    zAab_Fd_Zero_Asm_Posix_Types_HList,
+      apzAab_Fd_Zero_Asm_Posix_Types_HMachs,
+      AAB_FD_ZERO_ASM_POSIX_TYPES_H_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT,
+@@ -11819,11 +11717,6 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
+      CXX_UNREADY_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+      aCxx_UnreadyTests,   apzCxx_UnreadyPatch, 0 },
+
+-  {  zDarwin_AvailabilityinternalName,    zDarwin_AvailabilityinternalList,
+-     apzDarwin_AvailabilityinternalMachs,
+-     DARWIN_AVAILABILITYINTERNAL_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+-     aDarwin_AvailabilityinternalTests,   apzDarwin_AvailabilityinternalPatch, 0 },
+-
+   {  zDarwin_9_Long_Double_Funcs_2Name,    zDarwin_9_Long_Double_Funcs_2List,
+      apzDarwin_9_Long_Double_Funcs_2Machs,
+      DARWIN_9_LONG_DOUBLE_FUNCS_2_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
Index: pkgsrc/lang/gcc15/patches/patch-fixincludes_inclhack.def
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-fixincludes_inclhack.def:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-fixincludes_inclhack.def    Sun Jul 19 11:17:42 2026
@@ -0,0 +1,106 @@
+$NetBSD: patch-fixincludes_inclhack.def,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- fixincludes/inclhack.def.orig      2026-06-12 06:09:05.643510851 +0000
++++ fixincludes/inclhack.def
+@@ -195,33 +195,6 @@ fix = {
+ };
+ 
+ /*
+- *  SDKs for 10.13 and 10.14 omit the definitions for API_AVAILABLE where
+- *  __attribute__((availability)) is not supported.
+- */
+-fix = {
+-    hackname  = darwin_api_availability;
+-    mach      = "*-*-darwin*";
+-    files     = os/availability.h;
+-    bypass    = "__IPHONE_OS_VERSION_MIN_REQUIRED";
+-    select    =
+-    " *#define __API_AVAILABLE.*\n"
+-    " *#define __API_DEPRECATED.*\n"
+-    " *#define __API_DEPRECATED_WITH_REPLACEMENT.*\n"
+-    " *#define __API_UNAVAILABLE.*\n";
+-    c_fix     = format;
+-    c_fix_arg =
+-    "    #define API_AVAILABLE(...)\n"
+-    "    #define API_DEPRECATED(...)\n"
+-    "    #define API_DEPRECATED_WITH_REPLACEMENT(...)\n"
+-    "    #define API_UNAVAILABLE(...)\n";
+-    test_text =
+-    "#define __API_AVAILABLE(...)\n"
+-    "#define __API_DEPRECATED(...)\n"
+-    "#define __API_DEPRECATED_WITH_REPLACEMENT(...)\n"
+-    "#define __API_UNAVAILABLE(...)\n";
+-};
+-
+-/*
+  *  This fixes __FD_ZERO bug for linux 2.x.y (x <= 2 && y <= some n)
+  */
+ fix = {
+@@ -1352,32 +1325,6 @@ fix = {
+ };
+ 
+ /*
+- *  macOS 10.12 <AvailabilityInternal.h> uses __attribute__((availability))
+- *  unconditionally.
+- */
+-fix = {
+-    hackname  = darwin_availabilityinternal;
+-    mach      = "*-*-darwin*";
+-    files     = AvailabilityInternal.h;
+-    select    = "#define[ \t]+(__API_[ADU]\\([^)]*\\)).*";
+-    c_fix     = format;
+-    c_fix_arg = <<- _EOFix_
+-      #if defined(__has_attribute)
+-        #if __has_attribute(availability)
+-      %0
+-        #else
+-          #define %1
+-        #endif
+-      #else
+-          #define %1
+-      #endif
+-      _EOFix_;
+-
+-    test_text = "#define __API_A(x) __attribute__((availability(__API_AVAILABLE_PLATFORM_##x)))\n"
+-              "#define __API_D(msg,x) __attribute__((availability(__API_DEPRECATED_PLATFORM_##x,message=msg)))";
+-};
+-
+-/*
+  *  For the AAB_darwin7_9_long_double_funcs fix (and later fixes for long long)
+  *  to be useful, the main math.h must use <> and not "" includes.
+  */
+@@ -4473,13 +4420,13 @@ fix = {
+ 
+ /*
+  *  Arrange for stdio.h to use stdarg.h to define __gnuc_va_list.
+- *  On 4BSD-derived systems, stdio.h defers to machine/ansi.h; that's
+- *  OK too.
++ *  On 4BSD-derived systems, stdio.h defers to machine/ansi.h, that's
++ *  OK too. Modern macOS includes _stdio.h, and does not need the fix.
+  */
+ fix = {
+     hackname = stdio_stdarg_h;
+     files    = stdio.h;
+-    bypass   = "include.*(stdarg\.h|machine/ansi\.h)";
++    bypass   = "include.*(stdarg\.h|machine/ansi\.h|_stdio\.h)";
+     /*
+      * On Solaris 10, this fix is unncessary; <stdio.h> includes
+      * <iso/stdio_iso.h>, which includes <sys/va_list.h>.
+@@ -4500,12 +4447,12 @@ fix = {
+  *  of __gnuc_va_list, __DJ_va_list, or _G_va_list is taken to
+  *  indicate that the header knows what it's doing -- under SUSv2,
+  *  stdio.h is required to define va_list, and we shouldn't break
+- *  that.
++ *  that. Modern macOS includes _stdio.h, and does not need the fix.
+  */
+ fix = {
+     hackname = stdio_va_list;
+     files    = stdio.h;
+-    bypass   = '__gnuc_va_list|_BSD_VA_LIST_|__DJ_va_list|_G_va_list';
++    bypass   = '__gnuc_va_list|_BSD_VA_LIST_|__DJ_va_list|_G_va_list|_stdio.h';
+     /* 
+      * On Solaris 10, the definition in 
+      * <stdio.h> is guarded appropriately by the _XPG4 feature macro; 
Index: pkgsrc/lang/gcc15/patches/patch-gcc_ada_init.c
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_ada_init.c:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_ada_init.c      Sun Jul 19 11:17:42 2026
@@ -0,0 +1,18 @@
+$NetBSD: patch-gcc_ada_init.c,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/ada/init.c.orig        2026-06-12 06:09:05.877514473 +0000
++++ gcc/ada/init.c
+@@ -2564,7 +2564,10 @@ __gnat_map_signal (int sig, siginfo_t *s
+       /* Reset the use of alt stack, so that the alt stack will be used
+        for the next signal delivery.
+        The stack can't be used in case of stack checking.  */
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+       syscall (SYS_sigreturn, NULL, UC_RESET_ALT_STACK);
++#pragma GCC diagnostic pop
+       break;
+
+     case SIGFPE:
Index: pkgsrc/lang/gcc15/patches/patch-gcc_builtins.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_builtins.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_builtins.cc     Sun Jul 19 11:17:42 2026
@@ -0,0 +1,21 @@
+$NetBSD: patch-gcc_builtins.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/builtins.cc.orig       2026-06-12 06:09:06.067517413 +0000
++++ gcc/builtins.cc
+@@ -5962,6 +5962,13 @@ expand_builtin_trap (void)
+ static void
+ expand_builtin_unreachable (void)
+ {
++  /* If the target wants a trap in place of the fall-through, use that.  */
++  if (targetm.unreachable_should_trap ())
++    {
++      expand_builtin_trap ();
++      return;
++    }
++
+   /* Use gimple_build_builtin_unreachable or builtin_decl_unreachable
+      to avoid this.  */
+   gcc_checking_assert (!sanitize_flags_p (SANITIZE_UNREACHABLE));
Index: pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-attribs.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-attribs.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-attribs.cc   Sun Jul 19 11:17:42 2026
@@ -0,0 +1,26 @@
+$NetBSD: patch-gcc_c-family_c-attribs.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/c-family/c-attribs.cc.orig     2026-06-12 06:09:06.070517460 +0000
++++ gcc/c-family/c-attribs.cc
+@@ -721,6 +721,18 @@ set_musttail_on_return (tree retval, loc
+     error_at (loc, "cannot tail-call: return value must be a call");
+ }
+
++/* Returns TRUE iff the attribute indicated by ATTR_ID needs its
++   arguments converted to string constants.  */
++
++bool
++attribute_clang_form_p (const_tree attr_id)
++{
++  const struct attribute_spec *spec = lookup_attribute_spec (attr_id);
++  if (spec && !strcmp ("availability", spec->name))
++    return true;
++  return false;
++}
++
+ /* Verify that argument value POS at position ARGNO to attribute NAME
+    applied to function FN (which is either a function declaration or function
+    type) refers to a function parameter at position POS and the expected type
Index: pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-common.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-common.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-common.cc    Sun Jul 19 11:17:42 2026
@@ -0,0 +1,40 @@
+$NetBSD: patch-gcc_c-family_c-common.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/c-family/c-common.cc.orig      2026-06-12 06:09:06.071517475 +0000
++++ gcc/c-family/c-common.cc
+@@ -354,7 +354,11 @@ static constexpr hf_feature_info has_fea
+   { "enumerator_attributes",            HF_FLAG_NONE, 0 },
+   { "tls",                              HF_FLAG_NONE, 0 },
+   { "gnu_asm_goto_with_outputs",        HF_FLAG_EXT, 0 },
+-  { "gnu_asm_goto_with_outputs_full",   HF_FLAG_EXT, 0 }
++  { "gnu_asm_goto_with_outputs_full",   HF_FLAG_EXT, 0 },
++  { "attribute_availability",           HF_FLAG_NONE, 0 },
++  { "attribute_availability_with_message",  HF_FLAG_NONE, 0 },
++  { "attribute_availability_with_replacement",  HF_FLAG_NONE, 0 },
++  { "attribute_availability_with_version_underscores",  HF_FLAG_NONE, 0 }
+ };
+
+ /* Global visibility options.  */
+@@ -392,8 +396,8 @@ static bool nonnull_check_p (tree, unsig
+ */
+ const struct c_common_resword c_common_reswords[] =
+ {
+-  { "_Alignas",               RID_ALIGNAS,   D_CONLY },
+-  { "_Alignof",               RID_ALIGNOF,   D_CONLY },
++  { "_Alignas",               RID_ALIGNAS,   D_EXT_C_IN_CXX },
++  { "_Alignof",               RID_ALIGNOF,   D_EXT_C_IN_CXX },
+   { "_Atomic",                RID_ATOMIC,    D_CONLY },
+   { "_BitInt",                RID_BITINT,    D_CONLY },
+   { "_Bool",          RID_BOOL,      D_CONLY },
+@@ -413,7 +417,7 @@ const struct c_common_resword c_common_r
+   { "_Fract",           RID_FRACT,     D_CONLY | D_EXT },
+   { "_Accum",           RID_ACCUM,     D_CONLY | D_EXT },
+   { "_Sat",             RID_SAT,       D_CONLY | D_EXT },
+-  { "_Static_assert",   RID_STATIC_ASSERT, D_CONLY },
++  { "_Static_assert",   RID_STATIC_ASSERT, D_EXT_C_IN_CXX },
+   { "_Noreturn",        RID_NORETURN,  D_CONLY },
+   { "_Generic",         RID_GENERIC,   D_CONLY },
+   { "_Thread_local",    RID_THREAD,    D_CONLY },
Index: pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-common.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-common.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-common.h     Sun Jul 19 11:17:42 2026
@@ -0,0 +1,24 @@
+$NetBSD: patch-gcc_c-family_c-common.h,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/c-family/c-common.h.orig       2026-06-12 06:09:06.072517491 +0000
++++ gcc/c-family/c-common.h
+@@ -447,6 +447,8 @@ extern machine_mode c_default_pointer_mo
+ #define D_CXX20               0x8000  /* In C++, C++20 only.  */
+ #define D_CXX_COROUTINES 0x10000  /* In C++, only with coroutines.  */
+ #define D_CXX_MODULES 0x20000  /* In C++, only with modules.  */
++#define D_EXT_C_IN_CXX        0x40000  /* In C++, allow additional C keywords.  */
++#define D_EXT_CXX_IN_C        0x80000  /* In C, allow additional C++ keywords.  */
+
+ #define D_CXX_CONCEPTS_FLAGS D_CXXONLY | D_CXX_CONCEPTS
+ #define D_CXX_CHAR8_T_FLAGS D_CXXONLY | D_CXX_CHAR8_T
+@@ -1671,6 +1673,7 @@ extern void check_for_xor_used_as_pow (l
+ /* In c-attribs.cc.  */
+ extern bool attribute_takes_identifier_p (const_tree);
+ extern tree handle_deprecated_attribute (tree *, tree, tree, int, bool *);
++extern bool attribute_clang_form_p (const_tree);
+ extern tree handle_unused_attribute (tree *, tree, tree, int, bool *);
+ extern tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *);
+ extern int parse_tm_stmt_attr (tree, int);
Index: pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-lex.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-lex.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-lex.cc       Sun Jul 19 11:17:42 2026
@@ -0,0 +1,28 @@
+$NetBSD: patch-gcc_c-family_c-lex.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/c-family/c-lex.cc.orig 2026-06-12 06:09:06.073517506 +0000
++++ gcc/c-family/c-lex.cc
+@@ -586,6 +586,21 @@ c_lex_with_flags (tree *value, location_
+
+     case CPP_NUMBER:
+       {
++      /* If the user wants number-like entities to be returned as a raw
++         string, then don't try to classify them, which emits unwanted
++         diagnostics.  */
++      if (lex_flags & C_LEX_NUMBER_AS_STRING)
++        {
++          /* build_string adds a trailing NUL at [len].  */
++          tree num_string = build_string (tok->val.str.len + 1,
++                                          (const char *) tok->val.str.text);
++          TREE_TYPE (num_string) = char_array_type_node;
++          *value = num_string;
++          /* We will effectively note this as CPP_N_INVALID, because we
++             made no checks here.  */
++          break;
++        }
++
+       const char *suffix = NULL;
+       unsigned int flags = cpp_classify_number (parse_in, tok, &suffix, *loc);
Index: pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-opts.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-opts.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-opts.cc      Sun Jul 19 11:17:42 2026
@@ -0,0 +1,16 @@
+$NetBSD: patch-gcc_c-family_c-opts.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/c-family/c-opts.cc.orig        2026-06-12 06:09:06.074517522 +0000
++++ gcc/c-family/c-opts.cc
+@@ -1192,7 +1192,7 @@ c_common_post_options (const char **pfil
+
+   if (flag_extern_tls_init)
+     {
+-      if (!TARGET_SUPPORTS_ALIASES || !SUPPORTS_WEAK)
++      if (!SUPPORTS_WEAK)
+       {
+         /* Lazy TLS initialization for a variable in another TU requires
+            alias and weak reference support.  */
Index: pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-pragma.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-pragma.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c-pragma.h     Sun Jul 19 11:17:42 2026
@@ -0,0 +1,17 @@
+$NetBSD: patch-gcc_c-family_c-pragma.h,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/c-family/c-pragma.h.orig       2026-06-12 06:09:06.074517522 +0000
++++ gcc/c-family/c-pragma.h
+@@ -289,6 +289,9 @@ extern void pragma_lex_discard_to_eol ()
+ #define C_LEX_STRING_NO_JOIN    2 /* Do not concatenate strings
+                                      nor translate them into execution
+                                      character set.  */
++#define C_LEX_NUMBER_AS_STRING          4 /* Do not classify a number, but
++                                     instead return it as a raw
++                                     string.  */
+
+ /* This is not actually available to pragma parsers.  It's merely a
+    convenient location to declare this function for c-lex, after
Index: pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c.opt
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c.opt:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_c-family_c.opt  Sun Jul 19 11:17:42 2026
@@ -0,0 +1,26 @@
+$NetBSD: patch-gcc_c-family_c.opt,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/c-family/c.opt.orig    2026-06-12 06:09:06.076517552 +0000
++++ gcc/c-family/c.opt
+@@ -1806,6 +1806,18 @@ static-libmpxwrappers
+ Driver WarnRemoved
+ Removed in GCC 9.  This switch has no effect.
+
++fallow-const-var-array-size
++C ObjC C++ ObjC++ LTO Var(flag_allow_const_var_array_size) Init(0)
++Allow arrays sizes to be const-qualified vars in C and Objective-C.
++
++fallow-extended-attribute-placement
++C ObjC C++ ObjC++ LTO Var(flag_allow_ext_attr_placement) Init(0)
++Allow placement of attributes on function definitions.
++
++fallow-extra-keywords
++C ObjC C++ ObjC++ LTO Var(flag_allow_extra_keywords) Init(0)
++Allow additional C keywords in C++ and vice versa.
++
+ fcilkplus
+ C ObjC C++ ObjC++ LTO Undocumented Ignore
+ Removed in GCC 8.  This switch has no effect.
Index: pkgsrc/lang/gcc15/patches/patch-gcc_c_c-decl.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_c_c-decl.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_c_c-decl.cc     Sun Jul 19 11:17:42 2026
@@ -0,0 +1,43 @@
+$NetBSD: patch-gcc_c_c-decl.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/c/c-decl.cc.orig       2026-06-12 06:09:06.079517599 +0000
++++ gcc/c/c-decl.cc
+@@ -7360,6 +7360,25 @@ grokdeclarator (const struct c_declarato
+                 }
+
+               size = c_fully_fold (size, false, &size_maybe_const);
++              bool size_const_var = false;
++              if (flag_allow_const_var_array_size)
++                {
++                  tree maybe_const_size = TREE_CODE (size) == NOP_EXPR
++                                          ? TREE_OPERAND (size, 0) : size;
++                  size_const_var
++                    = (TREE_CODE (maybe_const_size) == VAR_DECL
++                       && TREE_READONLY (maybe_const_size)
++                       && !TREE_THIS_VOLATILE (maybe_const_size));
++                  if (size_const_var
++                      && size_maybe_const
++                      && DECL_INITIAL (maybe_const_size))
++                    {
++                      size = DECL_INITIAL (maybe_const_size);
++                      size = c_fully_fold (size, false, &size_maybe_const);
++                      size_int_const = (TREE_CODE (size) == INTEGER_CST
++                                        && !TREE_OVERFLOW (size));
++                    }
++                }
+
+               if (pedantic && size_maybe_const && integer_zerop (size))
+                 {
+@@ -7401,6 +7420,9 @@ grokdeclarator (const struct c_declarato
+                         this_size_varies = size_varies = true;
+                       warn_variable_length_array (name, size);
+                     }
++                  if (flag_allow_const_var_array_size && size_const_var)
++                    pedwarn (input_location, OPT_Wpedantic,
++                             "variably modified %qE at file scope", name);
+                 }
+               else if ((decl_context == NORMAL || decl_context == FIELD)
+                        && current_scope == file_scope)
Index: pkgsrc/lang/gcc15/patches/patch-gcc_c_c-parser.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_c_c-parser.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_c_c-parser.cc   Sun Jul 19 11:17:42 2026
@@ -0,0 +1,177 @@
+$NetBSD: patch-gcc_c_c-parser.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/c/c-parser.cc.orig     2026-06-12 06:09:06.082517646 +0000
++++ gcc/c/c-parser.cc
+@@ -220,6 +220,9 @@ struct GTY(()) c_parser {
+      should translate them to the execution character set (false
+      inside attributes).  */
+   BOOL_BITFIELD translate_strings_p : 1;
++  /* True if we want to lex arbitrary number-like sequences as their
++     string representation.  */
++  BOOL_BITFIELD lex_number_as_string : 1;
+
+   /* Objective-C specific parser/lexer information.  */
+
+@@ -326,10 +329,10 @@ c_lex_one_token (c_parser *parser, c_tok
+
+   if (raw || vec_safe_length (parser->raw_tokens) == 0)
+     {
++      int lex_flags = parser->lex_joined_string ? 0 : C_LEX_STRING_NO_JOIN;
++      lex_flags |= parser->lex_number_as_string ? C_LEX_NUMBER_AS_STRING : 0;
+       token->type = c_lex_with_flags (&token->value, &token->location,
+-                                    &token->flags,
+-                                    (parser->lex_joined_string
+-                                     ? 0 : C_LEX_STRING_NO_JOIN));
++                                    &token->flags, lex_flags);
+       token->id_kind = C_ID_NONE;
+       token->keyword = RID_MAX;
+       token->pragma_kind = PRAGMA_NONE;
+@@ -2765,15 +2768,28 @@ c_parser_declaration_or_fndef (c_parser
+           d = d->declarator;
+         underspec_name = d->u.id.id;
+       }
++      tree postfix_attrs = NULL_TREE;
++      if (flag_allow_ext_attr_placement
++        && c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
++      {
++        postfix_attrs = c_parser_gnu_attributes (parser);
++        /* IF we have a function definition, and we're allowing it then
++           treat these attributes as if they had been prepended.  */
++        if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
++          {
++            all_prefix_attrs = chainon (all_prefix_attrs, postfix_attrs);
++            postfix_attrs = NULL_TREE;
++          }
++      }
+       if (c_parser_next_token_is (parser, CPP_EQ)
+         || c_parser_next_token_is (parser, CPP_COMMA)
+         || c_parser_next_token_is (parser, CPP_SEMICOLON)
+         || c_parser_next_token_is_keyword (parser, RID_ASM)
+         || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
++        || postfix_attrs
+         || c_parser_next_token_is_keyword (parser, RID_IN))
+       {
+         tree asm_name = NULL_TREE;
+-        tree postfix_attrs = NULL_TREE;
+         if (!diagnosed_no_specs && !specs->declspecs_seen_p)
+           {
+             diagnosed_no_specs = true;
+@@ -2785,8 +2801,9 @@ c_parser_declaration_or_fndef (c_parser
+         if (c_parser_next_token_is_keyword (parser, RID_ASM))
+           asm_name = c_parser_simple_asm_expr (parser);
+         if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
++          postfix_attrs = c_parser_gnu_attributes (parser);
++        if (postfix_attrs)
+           {
+-            postfix_attrs = c_parser_gnu_attributes (parser);
+             if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
+               {
+                 /* This means there is an attribute specifier after
+@@ -5522,6 +5539,88 @@ c_parser_gnu_attribute_any_word (c_parse
+   return attr_name;
+ }
+
++/* Handle parsing clang-form attribute arguments, where we need to adjust
++   the parsing rules to relate to a specific attribute.  */
++
++static tree
++c_parser_clang_attribute_arguments (c_parser *parser, tree /*attr_id*/)
++{
++  /* We can, if required, alter the parsing on the basis of the attribute.
++     At present, we handle the availability attr, where ach entry can be :
++      identifier
++      identifier=N.MM.Z
++      identifier="string"
++      followed by ',' or ) for the last entry*/
++
++  tree attr_args = NULL_TREE;
++  do
++    {
++      tree name = NULL_TREE;
++      tree value = NULL_TREE;
++
++      if (c_parser_next_token_is (parser, CPP_NAME)
++        && c_parser_peek_token (parser)->id_kind == C_ID_ID)
++      {
++        name = c_parser_peek_token (parser)->value;
++        c_parser_consume_token (parser);
++      }
++      else if (c_parser_next_token_is (parser, CPP_COMMA))
++      name = error_mark_node; /* Comma handled below.  */
++      else
++      {
++        bool saved_join_state = parser->lex_joined_string;
++        parser->lex_number_as_string = 1;
++        parser->lex_joined_string = 1;
++        c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
++                                   "expected an attribute keyword");
++        parser->lex_number_as_string = 0;
++        parser->lex_joined_string = saved_join_state;
++        return error_mark_node;
++      }
++      if (c_parser_next_token_is (parser, CPP_EQ))
++      {
++        c_parser_consume_token (parser); /* eat the '=' */
++        /* We need to bludgeon the lexer into not trying to interpret the
++           xx.yy.zz form, since that just looks like a malformed float.
++           Also, as a result of macro processing, we can have strig literals
++           that are in multiple pieces so, for this specific part of the
++           parse, we need to join strings.  */
++        bool saved_join_state = parser->lex_joined_string;
++        parser->lex_number_as_string = 1;
++        parser->lex_joined_string = 1;
++        /* So look at the next token, expecting a string, or something that
++           looks initially like a number, but might be a version number.  */
++        c_parser_peek_token (parser);
++        /* Done with the funky number parsing.  */
++        parser->lex_number_as_string = 0;
++        parser->lex_joined_string = saved_join_state;
++        if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)
++            && c_parser_next_token_is_not (parser, CPP_COMMA))
++          {
++            value = c_parser_peek_token (parser)->value;
++            /* ???: check for error mark and early-return?  */
++            c_parser_consume_token (parser);
++          }
++        /* else value is absent.  */
++      }
++      else if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)
++             && c_parser_next_token_is_not (parser, CPP_COMMA))
++      {
++        c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
++                                   "expected %<,%> or %<=%>");
++        return error_mark_node;
++      }
++    if (c_parser_next_token_is (parser, CPP_COMMA))
++      c_parser_consume_token (parser); /* Just skip the comma.  */
++    tree t = tree_cons (value, name, NULL);
++    if (!attr_args)
++      attr_args = t;
++    else
++      chainon (attr_args, t);
++  } while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
++  return attr_args;
++}
++
+ /* Parse attribute arguments.  This is a common form of syntax
+    covering all currently valid GNU and standard attributes.
+
+@@ -5687,9 +5786,13 @@ c_parser_gnu_attribute (c_parser *parser
+       attrs = chainon (attrs, attr);
+       return attrs;
+     }
+-  c_parser_consume_token (parser);
++  c_parser_consume_token (parser); /* The '('.  */
+
+-  tree attr_args
++  tree attr_args;
++  if (attribute_clang_form_p (attr_name))
++    attr_args = c_parser_clang_attribute_arguments (parser, attr_name);
++  else
++    attr_args
+     = c_parser_attribute_arguments (parser,
+                                   attribute_takes_identifier_p (attr_name),
+                                   false,
Index: pkgsrc/lang/gcc15/patches/patch-gcc_calls.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_calls.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_calls.cc        Sun Jul 19 11:17:42 2026
@@ -0,0 +1,86 @@
+$NetBSD: patch-gcc_calls.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/calls.cc.orig  2026-06-12 06:09:06.085517692 +0000
++++ gcc/calls.cc
+@@ -1413,7 +1413,8 @@ initialize_argument_information (int num
+        with those made by function.cc.  */
+
+       /* See if this argument should be passed by invisible reference.  */
+-      function_arg_info arg (type, argpos < n_named_args);
++      function_arg_info arg (type, argpos < n_named_args,
++                           argpos == n_named_args - 1);
+       if (pass_by_reference (args_so_far_pnt, arg))
+       {
+         const bool callee_copies
+@@ -1533,10 +1534,13 @@ initialize_argument_information (int num
+
+       unsignedp = TYPE_UNSIGNED (type);
+       arg.type = type;
+-      arg.mode
+-      = promote_function_mode (type, TYPE_MODE (type), &unsignedp,
+-                               fndecl ? TREE_TYPE (fndecl) : fntype, 0);
+-
++      arg.mode = TYPE_MODE (type);
++//      arg.mode
++//    = promote_function_mode (type, TYPE_MODE (type), &unsignedp,
++//                             fndecl ? TREE_TYPE (fndecl) : fntype, 0);
++      arg.mode = promote_function_mode (args_so_far, arg,
++                                      fndecl ? TREE_TYPE (fndecl) : fntype,
++                                      &unsignedp, 0);
+       args[i].unsignedp = unsignedp;
+       args[i].mode = arg.mode;
+
+@@ -1586,6 +1590,7 @@ initialize_argument_information (int num
+ #endif
+                            reg_parm_stack_space,
+                            args[i].pass_on_stack ? 0 : args[i].partial,
++                           args_so_far,
+                            fndecl, args_size, &args[i].locate);
+ #ifdef BLOCK_REG_PADDING
+       else
+@@ -4149,6 +4154,7 @@ split_complex_types (tree types)
+   return types;
+ }
+ 
++extern void debug_tree (tree);
+ /* Output a library call to function ORGFUN (a SYMBOL_REF rtx)
+    for a value of mode OUTMODE,
+    with NARGS different arguments, passed as ARGS.
+@@ -4334,6 +4340,7 @@ emit_library_call_value_1 (int retval, r
+                          argvec[count].reg != 0,
+ #endif
+                          reg_parm_stack_space, 0,
++                         args_so_far,
+                          NULL_TREE, &args_size, &argvec[count].locate);
+
+       if (argvec[count].reg == 0 || argvec[count].partial != 0
+@@ -4404,8 +4411,16 @@ emit_library_call_value_1 (int retval, r
+         val = force_operand (XEXP (slot, 0), NULL_RTX);
+       }
+
+-      arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p,
+-                                      NULL_TREE, 0);
++//      arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p,
++//                                    NULL_TREE, 0);
++      tree t = arg.type;
++if (t)
++  debug_tree (t);
++gcc_assert (!t);
++      arg.type = NULL_TREE;
++      arg.mode = promote_function_mode (args_so_far, arg, NULL_TREE,
++                                      &unsigned_p, 0);
++      arg.type = t;
+       argvec[count].mode = arg.mode;
+       argvec[count].value = convert_modes (arg.mode, GET_MODE (val), val,
+                                          unsigned_p);
+@@ -4425,6 +4440,7 @@ emit_library_call_value_1 (int retval, r
+                              argvec[count].reg != 0,
+ #endif
+                              reg_parm_stack_space, argvec[count].partial,
++                             args_so_far,
+                              NULL_TREE, &args_size, &argvec[count].locate);
+         args_size.constant += argvec[count].locate.size.constant;
+         gcc_assert (!argvec[count].locate.size.var);
Index: pkgsrc/lang/gcc15/patches/patch-gcc_calls.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_calls.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_calls.h Sun Jul 19 11:17:42 2026
@@ -0,0 +1,65 @@
+$NetBSD: patch-gcc_calls.h,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/calls.h.orig   2026-06-12 06:09:06.085517692 +0000
++++ gcc/calls.h
+@@ -35,24 +35,43 @@ class function_arg_info
+ {
+ public:
+   function_arg_info ()
+-    : type (NULL_TREE), mode (VOIDmode), named (false),
++    : type (NULL_TREE), mode (VOIDmode), named (false), last_named (false),
+       pass_by_reference (false)
+   {}
+
+   /* Initialize an argument of mode MODE, either before or after promotion.  */
+   function_arg_info (machine_mode mode, bool named)
+-    : type (NULL_TREE), mode (mode), named (named), pass_by_reference (false)
++    : type (NULL_TREE), mode (mode), named (named), last_named (false),
++      pass_by_reference (false)
++  {}
++
++  function_arg_info (machine_mode mode, bool named, bool last_named)
++    : type (NULL_TREE), mode (mode), named (named), last_named (last_named),
++      pass_by_reference (false)
+   {}
+
+   /* Initialize an unpromoted argument of type TYPE.  */
+   function_arg_info (tree type, bool named)
+-    : type (type), mode (TYPE_MODE (type)), named (named),
++    : type (type), mode (TYPE_MODE (type)), named (named), last_named (false),
+       pass_by_reference (false)
+   {}
+
++  /* Initialize an unpromoted argument of type TYPE.  */
++  function_arg_info (tree type, bool named, bool last_named)
++    : type (type), mode (TYPE_MODE (type)), named (named),
++      last_named (last_named), pass_by_reference (false)
++  {}
++
+   /* Initialize an argument with explicit properties.  */
+   function_arg_info (tree type, machine_mode mode, bool named)
+-    : type (type), mode (mode), named (named), pass_by_reference (false)
++    : type (type), mode (mode), named (named), last_named (false),
++      pass_by_reference (false)
++  {}
++
++  /* Initialize an argument with explicit properties.  */
++  function_arg_info (tree type, machine_mode mode, bool named, bool last_named)
++    : type (type), mode (mode), named (named), last_named (last_named),
++      pass_by_reference (false)
+   {}
+
+   /* Return true if the gimple-level type is an aggregate.  */
+@@ -105,6 +124,9 @@ public:
+      "...").  See also TARGET_STRICT_ARGUMENT_NAMING.  */
+   unsigned int named : 1;
+
++  /* True if this is the last named argument. */
++  unsigned int last_named : 1;
++
+   /* True if we have decided to pass the argument by reference, in which case
+      the function_arg_info describes a pointer to the original argument.  */
+   unsigned int pass_by_reference : 1;
Index: pkgsrc/lang/gcc15/patches/patch-gcc_collect2.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_collect2.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_collect2.cc     Sun Jul 19 11:17:42 2026
@@ -0,0 +1,119 @@
+$NetBSD: patch-gcc_collect2.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/collect2.cc.orig       2026-06-12 06:09:06.100517924 +0000
++++ gcc/collect2.cc
+@@ -73,7 +73,7 @@ along with GCC; see the file COPYING3.
+    In a cross-compiler, this means you need a cross nm,
+    but that is not quite as unpleasant as special headers.  */
+
+-#if !defined (OBJECT_FORMAT_COFF)
++#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_MACHO)
+ #define OBJECT_FORMAT_NONE
+ #endif
+
+@@ -107,7 +107,7 @@ along with GCC; see the file COPYING3.
+
+ #endif /* OBJECT_FORMAT_COFF */
+
+-#ifdef OBJECT_FORMAT_NONE
++#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO)
+
+ /* Default flags to pass to nm.  */
+ #ifndef NM_FLAGS
+@@ -525,7 +525,7 @@ static const char *const target_machine
+
+    Return 0 if not found, otherwise return its name, allocated with malloc.  */
+
+-#ifdef OBJECT_FORMAT_NONE
++#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO)
+
+ /* Add an entry for the object file NAME to object file list LIST.
+    New entries are added at the end of the list. The original pointer
+@@ -764,6 +764,12 @@ do_link (char **ld_argv, const char *ats
+     }
+ }
+ 
++#if defined (OBJECT_FORMAT_MACHO)
++# define LLD_NAME "ld64.lld"
++#else
++# define LLD_NAME "ld.lld"
++#endif
++
+ /* Main program.  */
+
+ int
+@@ -777,16 +783,19 @@ main (int argc, char **argv)
+       USE_BFD_LD,
+       USE_LLD_LD,
+       USE_MOLD_LD,
++      USE_CLASSIC_LD,
+       USE_LD_MAX
+     } selected_linker = USE_DEFAULT_LD;
++
+   static const char *const ld_suffixes[USE_LD_MAX] =
+     {
+       "ld",
+       PLUGIN_LD_SUFFIX,
+       "ld.gold",
+       "ld.bfd",
+-      "ld.lld",
+-      "ld.mold"
++      LLD_NAME,
++      "ld.mold",
++      "ld-classic"
+     };
+   static const char *const real_ld_suffix = "real-ld";
+   static const char *const collect_ld_suffix = "collect-ld";
+@@ -868,7 +877,7 @@ main (int argc, char **argv)
+ #ifdef CROSS_DIRECTORY_STRUCTURE
+     /* lld and mold are platform-agnostic and not prefixed with target
+        triple.  */
+-    if (!(i == USE_LLD_LD || i == USE_MOLD_LD))
++    if (!(i == USE_LLD_LD || i == USE_MOLD_LD || i == USE_CLASSIC_LD))
+       full_ld_suffixes[i] = concat (target_machine, "-", ld_suffixes[i],
+                                   NULL);
+     else
+@@ -956,14 +965,22 @@ main (int argc, char **argv)
+           if (selected_linker == USE_DEFAULT_LD)
+             selected_linker = USE_PLUGIN_LD;
+         }
++#if !defined (OBJECT_FORMAT_MACHO)
+       else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
+         selected_linker = USE_BFD_LD;
+       else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
+         selected_linker = USE_GOLD_LD;
++#endif
+       else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
+         selected_linker = USE_LLD_LD;
+       else if (strcmp (argv[i], "-fuse-ld=mold") == 0)
+         selected_linker = USE_MOLD_LD;
++#if defined (OBJECT_FORMAT_MACHO)
++      else if (strcmp (argv[i], "-fuse-ld=classic") == 0)
++        selected_linker = USE_CLASSIC_LD;
++#endif
++      else if (strcmp (argv[i], "-fuse-ld=") == 0)
++         selected_linker = USE_DEFAULT_LD;
+       else if (startswith (argv[i], "-o"))
+         {
+           /* Parse the output filename if it's given so that we can make
+@@ -1056,7 +1073,8 @@ main (int argc, char **argv)
+   ld_file_name = 0;
+ #ifdef DEFAULT_LINKER
+   if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
+-      selected_linker == USE_LLD_LD || selected_linker == USE_MOLD_LD)
++      selected_linker == USE_LLD_LD || selected_linker == USE_MOLD_LD ||
++      selected_linker == USE_CLASSIC_LD)
+     {
+       char *linker_name;
+ # ifdef HOST_EXECUTABLE_SUFFIX
+@@ -2272,7 +2290,7 @@ write_aix_file (FILE *stream, struct id
+ }
+ #endif
+ 
+-#ifdef OBJECT_FORMAT_NONE
++#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO)
+
+ /* Check to make sure the file is an LTO object file.  */
Index: pkgsrc/lang/gcc15/patches/patch-gcc_common.opt
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_common.opt:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_common.opt      Sun Jul 19 11:17:42 2026
@@ -0,0 +1,28 @@
+$NetBSD: patch-gcc_common.opt,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/common.opt.orig        2026-06-12 06:09:06.102517955 +0000
++++ gcc/common.opt
+@@ -3017,6 +3017,10 @@ fstack-usage
+ Common RejectNegative Var(flag_stack_usage)
+ Output stack usage information on a per-function basis.
+
++fstack-use-cumulative-args
++Common RejectNegative Var(flag_stack_use_cumulative_args) Init(STACK_USE_CUMULATIVE_ARGS_INIT)
++Use cumulative args-based stack layout hooks.
++
+ fstrength-reduce
+ Common Ignore
+ Does nothing.  Preserved for backward compatibility.
+@@ -3390,6 +3394,10 @@ fuse-ld=mold
+ Common Driver Negative(fuse-ld=mold)
+ Use the Modern linker (MOLD) linker instead of the default linker.
+
++fuse-ld=classic
++Common Driver Negative(fuse-ld=classic)
++Use the ld-classic linker instead of the default linker.
++
+ fuse-linker-plugin
+ Common Undocumented Var(flag_use_linker_plugin)
Index: pkgsrc/lang/gcc15/patches/patch-gcc_common_config_aarch64_aarch64-common.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_common_config_aarch64_aarch64-common.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_common_config_aarch64_aarch64-common.cc Sun Jul 19 11:17:42 2026
@@ -0,0 +1,45 @@
+$NetBSD: patch-gcc_common_config_aarch64_aarch64-common.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/common/config/aarch64/aarch64-common.cc.orig   2026-06-12 06:09:06.103685764 +0000
++++ gcc/common/config/aarch64/aarch64-common.cc
+@@ -644,8 +644,12 @@ aarch64_get_extension_string_for_isa_fla
+
+      However, assemblers with Armv8-R AArch64 support should not have this
+      issue, so we don't need this fix when targeting Armv8-R.  */
+-  auto explicit_flags = (!(current_flags & AARCH64_FL_V8R)
+-                       ? AARCH64_FL_CRC : 0);
++  aarch64_feature_flags explicit_flags =
++#ifndef DISABLE_AARCH64_AS_CRC_BUGFIX
++     (!(current_flags & AARCH64_FL_V8R) ? AARCH64_FL_CRC : 0);
++#else
++     0;
++#endif
+
+   /* Add the features in isa_flags & ~current_flags using the smallest
+      possible number of extensions.  We can do this by iterating over the
+@@ -675,7 +679,10 @@ aarch64_get_extension_string_for_isa_fla
+     if (added & opt.flag_canonical)
+       {
+       outstr += "+";
+-      outstr += opt.name;
++      if (startswith (opt.name, "rdm"))
++        outstr += "rdm";
++      else
++        outstr += opt.name;
+       }
+
+   /* Remove the features in current_flags & ~isa_flags.  If the feature does
+@@ -704,7 +711,10 @@ aarch64_get_extension_string_for_isa_fla
+       {
+         current_flags &= ~opt.flags_off;
+         outstr += "+no";
+-        outstr += opt.name;
++        if (startswith (opt.name, "rdm"))
++          outstr += "rdm";
++        else
++          outstr += opt.name;
+       }
+     }
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-builtins.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-builtins.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-builtins.cc      Sun Jul 19 11:17:42 2026
@@ -0,0 +1,82 @@
+$NetBSD: patch-gcc_config_aarch64_aarch64-builtins.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/aarch64-builtins.cc.orig        2026-06-12 06:09:06.108247229 +0000
++++ gcc/config/aarch64/aarch64-builtins.cc
+@@ -889,6 +889,8 @@ enum aarch64_builtins
+   AARCH64_BUILTIN_GCSPR,
+   AARCH64_BUILTIN_GCSPOPM,
+   AARCH64_BUILTIN_GCSSS,
++  /* OS-specific */
++  AARCH64_BUILTIN_CFSTRING,
+   AARCH64_BUILTIN_MAX
+ };
+
+@@ -1022,6 +1024,9 @@ tree aarch64_fp16_ptr_type_node = NULL_T
+ /* Back-end node type for brain float (bfloat) types.  */
+ tree aarch64_bf16_ptr_type_node = NULL_TREE;
+
++/* Pointer to __float128 on Mach-O, where the 128b float is not long double.  */
++tree aarch64_float128_ptr_type_node = NULL_TREE;
++
+ /* Wrapper around add_builtin_function.  NAME is the name of the built-in
+    function, TYPE is the function type, CODE is the function subcode
+    (relative to AARCH64_BUILTIN_GENERAL), and ATTRS is the function
+@@ -2051,6 +2056,29 @@ aarch64_init_bf16_types (void)
+   aarch64_bf16_ptr_type_node = build_pointer_type (bfloat16_type_node);
+ }
+
++/* Initialize the backend REAL_TYPE type supporting __float128 on Mach-O,
++   as well as the related built-ins.  */
++static void
++aarch64_init_float128_types (void)
++{
++  /* The __float128 type.  The node has already been created as
++     _Float128, so for C we only need to register the __float128 name for
++     it.  For C++, we create a distinct type which will mangle differently
++     (g) vs. _Float128 (DF128_) and behave backwards compatibly.  */
++  if (float128t_type_node == NULL_TREE)
++    {
++      float128t_type_node = make_node (REAL_TYPE);
++      TYPE_PRECISION (float128t_type_node)
++      = TYPE_PRECISION (float128_type_node);
++      SET_TYPE_MODE (float128t_type_node, TYPE_MODE (float128_type_node));
++      layout_type (float128t_type_node);
++    }
++  lang_hooks.types.register_builtin_type (float128t_type_node, "__float128");
++
++  aarch64_float128_ptr_type_node = build_pointer_type (float128t_type_node);
++}
++
++
+ /* Pointer authentication builtins that will become NOP on legacy platform.
+    Currently, these builtins are for internal use only (libgcc EH unwinder).  */
+
+@@ -2465,8 +2493,9 @@ aarch64_general_init_builtins (void)
+   aarch64_init_fp8_types ();
+
+   aarch64_init_fp16_types ();
+-
+   aarch64_init_bf16_types ();
++  if (TARGET_MACHO)
++    aarch64_init_float128_types ();
+
+   {
+     aarch64_target_switcher switcher (AARCH64_FL_SIMD);
+@@ -2508,6 +2537,14 @@ aarch64_general_init_builtins (void)
+     handle_arm_acle_h ();
+ }
+
++void
++aarch64_init_subtarget_builtins (void)
++{
++#ifdef SUBTARGET_INIT_BUILTINS
++  SUBTARGET_INIT_BUILTINS;
++#endif
++}
++
+ /* Implement TARGET_BUILTIN_DECL for the AARCH64_BUILTIN_GENERAL group.  */
+ tree
+ aarch64_general_builtin_decl (unsigned code, bool)
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-c.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-c.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-c.cc     Sun Jul 19 11:17:42 2026
@@ -0,0 +1,33 @@
+$NetBSD: patch-gcc_config_aarch64_aarch64-c.cc,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/aarch64-c.cc.orig       2026-06-12 06:09:06.108518048 +0000
++++ gcc/config/aarch64/aarch64-c.cc
+@@ -313,6 +313,16 @@ aarch64_cpu_cpp_builtins (cpp_reader *pf
+ {
+   aarch64_define_unconditional_macros (pfile);
+   aarch64_update_cpp_builtins (pfile);
++
++  if (TARGET_MACHO)
++    {
++      builtin_define ("__builtin_copysignq=__builtin_copysignf128");
++      builtin_define ("__builtin_fabsq=__builtin_fabsf128");
++      builtin_define ("__builtin_huge_valq=__builtin_huge_valf128");
++      builtin_define ("__builtin_infq=__builtin_inff128");
++      builtin_define ("__builtin_nanq=__builtin_nanf128");
++      builtin_define ("__builtin_nansq=__builtin_nansf128");
++    }
+ }
+
+ /* Hook to validate the current #pragma GCC target and set the state, and
+@@ -451,4 +461,8 @@ aarch64_register_pragmas (void)
+   targetm.check_builtin_call = aarch64_check_builtin_call;
+
+   c_register_pragma ("GCC", "aarch64", aarch64_pragma_aarch64);
++
++#ifdef REGISTER_SUBTARGET_PRAGMAS
++  REGISTER_SUBTARGET_PRAGMAS ();
++#endif
+ }
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-cores.def
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-cores.def:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-cores.def        Sun Jul 19 11:17:42 2026
@@ -0,0 +1,30 @@
+$NetBSD: patch-gcc_config_aarch64_aarch64-cores.def,v 1.1 2026/07/19 11:17:42 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/aarch64-cores.def.orig  2026-06-12 06:09:06.108518048 +0000
++++ gcc/config/aarch64/aarch64-cores.def
+@@ -177,7 +177,8 @@ AARCH64_CORE("cortex-r82ae", cortexr82ae
+ /* Apple (A12 and M) cores.
+    Known part numbers as listed in other public sources.
+    Placeholders for schedulers, generic_armv8_a for costs.
+-   A12 seems mostly 8.3, M1 is 8.5 without BTI, M2 and M3 are 8.6
++   A12 seems mostly 8.3, M1 is 8.5 without BTI, M2 and M3 are 8.6.
++   M4 is 9.2 but without SVE, so the closest match is 8.7.
+    From measurements made so far the odd-number core IDs are performance.  */
+ AARCH64_CORE("apple-a12", applea12, cortexa53, V8_3A,  (), generic_armv8_a, 0x61, 0x12, -1)
+ AARCH64_CORE("apple-m1", applem1_0, cortexa57, V8_5A,  (), generic_armv8_a, 0x61, AARCH64_BIG_LITTLE (0x21, 0x20), -1)
+@@ -188,7 +189,12 @@ AARCH64_CORE("apple-m2", applem2_0, cort
+ AARCH64_CORE("apple-m2", applem2_1, cortexa57, V8_6A,  (), generic_armv8_a, 0x61, AARCH64_BIG_LITTLE (0x33, 0x32), -1)
+ AARCH64_CORE("apple-m2", applem2_2, cortexa57, V8_6A,  (), generic_armv8_a, 0x61, AARCH64_BIG_LITTLE (0x35, 0x34), -1)
+ AARCH64_CORE("apple-m2", applem2_3, cortexa57, V8_6A,  (), generic_armv8_a, 0x61, AARCH64_BIG_LITTLE (0x39, 0x38), -1)
+-AARCH64_CORE("apple-m3", applem3_0, cortexa57, V8_6A,  (), generic_armv8_a, 0x61, AARCH64_BIG_LITTLE (0x49, 0x48), -1)
++AARCH64_CORE("apple-m3", applem3_0, cortexa57, V8_6A,  (), generic_armv8_a, 0x61, AARCH64_BIG_LITTLE (0x43, 0x42), -1)
++AARCH64_CORE("apple-m3", applem3_1, cortexa57, V8_6A,  (), generic_armv8_a, 0x61, AARCH64_BIG_LITTLE (0x45, 0x44), -1)
++AARCH64_CORE("apple-m3", applem3_2, cortexa57, V8_6A,  (), generic_armv8_a, 0x61, AARCH64_BIG_LITTLE (0x49, 0x48), -1)
++AARCH64_CORE("apple-m4", applem4_0, cortexa57, V8_7A,  (), generic_armv8_a, 0x61, AARCH64_BIG_LITTLE (0x53, 0x52), -1)
++AARCH64_CORE("apple-m4", applem4_1, cortexa57, V8_7A,  (), generic_armv8_a, 0x61, AARCH64_BIG_LITTLE (0x55, 0x54), -1)
++AARCH64_CORE("apple-m4", applem4_2, cortexa57, V8_7A,  (), generic_armv8_a, 0x61, AARCH64_BIG_LITTLE (0x59, 0x58), -1)
+
+ /* Armv9.0-A Architecture Processors.  */
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-protos.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-protos.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-protos.h Sun Jul 19 11:17:43 2026
@@ -0,0 +1,50 @@
+$NetBSD: patch-gcc_config_aarch64_aarch64-protos.h,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/aarch64-protos.h.orig   2026-06-12 06:09:06.109518064 +0000
++++ gcc/config/aarch64/aarch64-protos.h
+@@ -109,6 +109,14 @@ enum aarch64_symbol_type
+   SYMBOL_TLSLE24,
+   SYMBOL_TLSLE32,
+   SYMBOL_TLSLE48,
++  SYMBOL_MO_SMALL_ABS,
++  SYMBOL_MO_SMALL_PCR,
++  SYMBOL_MO_SMALL_GOT,
++  SYMBOL_MO_SMALL_TLS,
++  SYMBOL_MO_LARGE_ABS,
++  SYMBOL_MO_LARGE_PCR,
++  SYMBOL_MO_LARGE_GOT,
++  SYMBOL_MO_LARGE_TLS,
+   SYMBOL_FORCE_TO_MEM
+ };
+
+@@ -849,6 +857,7 @@ void aarch64_post_cfi_startproc (void);
+ poly_int64 aarch64_initial_elimination_offset (unsigned, unsigned);
+ int aarch64_get_condition_code (rtx);
+ bool aarch64_address_valid_for_prefetch_p (rtx, bool);
++bool aarch64_address_valid_for_unscaled_prefetch_p (rtx, bool);
+ bool aarch64_bitmask_imm (unsigned HOST_WIDE_INT val, machine_mode);
+ unsigned HOST_WIDE_INT aarch64_and_split_imm1 (HOST_WIDE_INT val_in);
+ unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in);
+@@ -886,7 +895,11 @@ bool aarch64_is_extend_from_extract (sca
+ bool aarch64_is_long_call_p (rtx);
+ bool aarch64_is_noplt_call_p (rtx);
+ bool aarch64_label_mentioned_p (rtx);
++#if TARGET_MACHO
++void aarch64_darwin_declare_function_name (FILE *, const char*, tree );
++#else
+ void aarch64_declare_function_name (FILE *, const char*, tree);
++#endif
+ void aarch64_asm_output_alias (FILE *, const tree, const tree);
+ void aarch64_asm_output_external (FILE *, tree, const char*);
+ bool aarch64_legitimate_pic_operand_p (rtx);
+@@ -1113,6 +1126,7 @@ void aarch64_override_options_internal (
+
+ const char *aarch64_general_mangle_builtin_type (const_tree);
+ void aarch64_general_init_builtins (void);
++void aarch64_init_subtarget_builtins (void);
+ tree aarch64_general_fold_builtin (unsigned int, tree, unsigned int, tree *);
+ gimple *aarch64_general_gimple_fold_builtin (unsigned int, gcall *,
+                                            gimple_stmt_iterator *);
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-tune.md
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-tune.md:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64-tune.md  Sun Jul 19 11:17:43 2026
@@ -0,0 +1,14 @@
+$NetBSD: patch-gcc_config_aarch64_aarch64-tune.md,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/aarch64-tune.md.orig    2026-06-12 06:10:23.639718108 +0000
++++ gcc/config/aarch64/aarch64-tune.md
+@@ -1,5 +1,5 @@
+ ;; -*- buffer-read-only: t -*-
+ ;; Generated automatically by gentune.sh from aarch64-cores.def
+ (define_attr "tune"
+-      
"cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,hip12,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,applea12,applem1_0,applem1_1,applem1_2,applem1_3,applem2_0,applem2_1,applem2_2,applem2_3,applem3_0,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neo
 versev2,grace,neoversev3,neoversev3ae,demeter,olympus,gb10,generic,generic_armv8_a,generic_armv9_a"
++      
"cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,hip12,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,applea12,applem1_0,applem1_1,applem1_2,applem1_3,applem2_0,applem2_1,applem2_2,applem2_3,applem3_0,applem3_1,applem3_2,applem4_0,applem4_1,applem4_2,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,corte
 xx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,demeter,olympus,gb10,generic,generic_armv8_a,generic_armv9_a"
+       (const (symbol_ref "((enum attr_tune) aarch64_tune)")))
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.cc       Sun Jul 19 11:17:43 2026
@@ -0,0 +1,1478 @@
+$NetBSD: patch-gcc_config_aarch64_aarch64.cc,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/aarch64.cc.orig 2026-06-12 06:09:06.118518203 +0000
++++ gcc/config/aarch64/aarch64.cc
+@@ -344,8 +344,10 @@ static bool aarch64_vfp_is_call_or_retur
+                                                    const_tree,
+                                                    machine_mode *, int *,
+                                                    bool *, bool);
++#if !TARGET_MACHO
+ static void aarch64_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED;
+ static void aarch64_elf_asm_destructor (rtx, int) ATTRIBUTE_UNUSED;
++#endif
+ static void aarch64_override_options_after_change (void);
+ static bool aarch64_vector_mode_supported_p (machine_mode);
+ static int aarch64_address_cost (rtx, machine_mode, addr_space_t, bool);
+@@ -863,6 +865,9 @@ static const attribute_spec aarch64_gnu_
+ {
+   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
+        affects_type_identity, handler, exclude } */
++#ifdef SUBTARGET_ATTRIBUTE_TABLE
++  SUBTARGET_ATTRIBUTE_TABLE,
++#endif
+   { "aarch64_vector_pcs", 0, 0, false, true,  true,  true,
+                         handle_aarch64_vector_pcs_attribute, NULL },
+   { "indirect_return",    0, 0, false, true, true, true, NULL, NULL },
+@@ -876,9 +881,6 @@ static const attribute_spec aarch64_gnu_
+   { "dllimport", 0, 0, false, false, false, false, handle_dll_attribute, NULL },
+   { "dllexport", 0, 0, false, false, false, false, handle_dll_attribute, NULL },
+ #endif
+-#ifdef SUBTARGET_ATTRIBUTE_TABLE
+-  SUBTARGET_ATTRIBUTE_TABLE
+-#endif
+ };
+
+ static const scoped_attribute_specs aarch64_gnu_attribute_table =
+@@ -2299,7 +2301,7 @@ aarch64_hard_regno_mode_ok (unsigned reg
+       if (known_le (GET_MODE_SIZE (mode), 8))
+       return true;
+       if (known_le (GET_MODE_SIZE (mode), 16))
+-      return (regno & 1) == 0;
++      return (regno & 1) == 0 || TARGET_MACHO; /* darwinpcs D.4 */
+     }
+   else if (FP_REGNUM_P (regno))
+     {
+@@ -2345,8 +2347,10 @@ static bool
+ aarch64_takes_arguments_in_sve_regs_p (const_tree fntype)
+ {
+   CUMULATIVE_ARGS args_so_far_v;
++  /* This does not apply to variadic functions, so all the (currently
++     uncounted) arguments must be named.  */
+   aarch64_init_cumulative_args (&args_so_far_v, NULL_TREE, NULL_RTX,
+-                              NULL_TREE, 0, true);
++                              NULL_TREE, -1, true);
+   cumulative_args_t args_so_far = pack_cumulative_args (&args_so_far_v);
+
+   for (tree chain = TYPE_ARG_TYPES (fntype);
+@@ -2813,7 +2817,11 @@ aarch64_constant_alignment (const_tree e
+ unsigned
+ aarch64_data_alignment (const_tree type, unsigned align)
+ {
+-  if (optimize_size)
++  /* For now, on Darwin we do not give global entities any extra
++     alignment TODO: determine if we should for some optimisation
++     level.  */
++
++  if (optimize_size || TARGET_MACHO)
+     return align;
+
+   if (AGGREGATE_TYPE_P (type))
+@@ -3199,6 +3207,7 @@ aarch64_load_symref_appropriately (rtx d
+   switch (type)
+     {
+     case SYMBOL_SMALL_ABSOLUTE:
++    case SYMBOL_MO_SMALL_PCR:
+       {
+       /* In ILP32, the mode of dest can be either SImode or DImode.  */
+       rtx tmp_reg = dest;
+@@ -3222,6 +3231,21 @@ aarch64_load_symref_appropriately (rtx d
+         }
+       imm = plus_constant (mode, imm, -mid_const);
+
++      if (TARGET_MACHO)
++        {
++          rtx sym, off;
++          split_const (imm, &sym, &off);
++          /* Negative offsets don't work, whether by intention is TBD.  */
++          if (INTVAL (off) < 0 || INTVAL (off) >= 4 * 1024 * 1024)
++            {
++              emit_move_insn (tmp_reg, gen_rtx_HIGH (mode, sym));
++              emit_insn (gen_add_losym (dest, tmp_reg, sym));
++              /* FIXME: add the SI option if/when we support ilp32.  */
++              emit_insn (gen_adddi3 (dest, dest, off));
++              return;
++            }
++         /* else small enough positive offset is OK.  */
++        }
+       emit_move_insn (tmp_reg, gen_rtx_HIGH (mode, copy_rtx (imm)));
+       if (mid_const)
+         emit_set_insn (tmp_reg, plus_constant (mode, tmp_reg, mid_const));
+@@ -3307,6 +3331,7 @@ aarch64_load_symref_appropriately (rtx d
+       return;
+       }
+
++    case SYMBOL_MO_SMALL_GOT:
+     case SYMBOL_SMALL_GOT_4G:
+       emit_insn (gen_rtx_SET (dest, imm));
+       return;
+@@ -6416,6 +6441,7 @@ aarch64_expand_mov_immediate (rtx dest,
+       case SYMBOL_SMALL_TLSIE:
+       case SYMBOL_SMALL_GOT_28K:
+       case SYMBOL_SMALL_GOT_4G:
++      case SYMBOL_MO_SMALL_GOT:
+       case SYMBOL_TINY_GOT:
+       case SYMBOL_TINY_TLSIE:
+         if (const_offset != 0)
+@@ -6429,6 +6455,7 @@ aarch64_expand_mov_immediate (rtx dest,
+         /* FALLTHRU */
+
+       case SYMBOL_SMALL_ABSOLUTE:
++      case SYMBOL_MO_SMALL_PCR:
+       case SYMBOL_TINY_ABSOLUTE:
+       case SYMBOL_TLSLE12:
+       case SYMBOL_TLSLE24:
+@@ -7035,6 +7062,7 @@ aarch64_return_in_memory (const_tree typ
+   gcc_unreachable ();
+ }
+
++#if !TARGET_MACHO
+ static bool
+ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode,
+                              const_tree type, int *nregs)
+@@ -7044,6 +7072,7 @@ aarch64_vfp_is_call_candidate (cumulativ
+                                                 &pcum->aapcs_vfp_rmode,
+                                                 nregs, NULL, pcum->silent_p);
+ }
++#endif
+
+ /* Given MODE and TYPE of a function argument, return the alignment in
+    bits.  The idea is to suppress any stronger alignment requested by
+@@ -7072,7 +7101,7 @@ aarch64_function_arg_alignment (machine_
+   if (integer_zerop (TYPE_SIZE (type)))
+     return 0;
+
+-  gcc_assert (TYPE_MODE (type) == mode);
++  gcc_assert (TARGET_MACHO || TYPE_MODE (type) == mode);
+
+   if (!AGGREGATE_TYPE_P (type))
+     {
+@@ -7270,6 +7299,14 @@ aarch64_layout_arg (cumulative_args_t pc
+      Both behaviors were wrong, but in different cases.  */
+
+   pcum->aapcs_arg_processed = true;
++  if (TARGET_MACHO)
++    {
++      /* Set suitable defaults for queries.  */
++      pcum->darwinpcs_arg_boundary
++      = aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9,
++                                        &abi_break_gcc_13, &abi_break_gcc_14);
++      pcum->darwinpcs_arg_padding = BITS_PER_UNIT;
++    }
+
+   pure_scalable_type_info pst_info;
+   if (type && pst_info.analyze_registers (type))
+@@ -7329,13 +7366,29 @@ aarch64_layout_arg (cumulative_args_t pc
+     /* No frontends can create types with variable-sized modes, so we
+        shouldn't be asked to pass or return them.  */
+     size = GET_MODE_SIZE (mode).to_constant ();
++
++  if (TARGET_MACHO)
++    /* Since we can pack things on the stack, we need the unrounded size.  */
++    pcum->darwinpcs_stack_bytes = size;
++
+   size = ROUND_UP (size, UNITS_PER_WORD);
+
+   allocate_ncrn = (type) ? !(FLOAT_TYPE_P (type)) : !FLOAT_MODE_P (mode);
++  bool is_ha = false;
++#if !TARGET_MACHO
+   allocate_nvrn = aarch64_vfp_is_call_candidate (pcum_v,
+                                                mode,
+                                                type,
+                                                &nregs);
++#else
++  /* We care if the value is a homogenous aggregate when laying out the stack,
++     so use this call directly.  */
++  allocate_nvrn
++    = aarch64_vfp_is_call_or_return_candidate (mode, type,
++                                              &pcum->aapcs_vfp_rmode,
++                                              &nregs, &is_ha,
++                                              pcum->silent_p);
++#endif
+   gcc_assert (!sve_p || !allocate_nvrn);
+
+   unsigned int alignment
+@@ -7364,7 +7417,13 @@ aarch64_layout_arg (cumulative_args_t pc
+       if (!pcum->silent_p && !TARGET_FLOAT)
+       aarch64_err_no_fpadvsimd (mode);
+
+-      if (nvrn + nregs <= NUM_FP_ARG_REGS)
++      if (TARGET_MACHO
++        && !arg.named)
++      {
++        pcum->aapcs_nextnvrn = NUM_FP_ARG_REGS;
++        goto on_stack;
++      }
++      else if (nvrn + nregs <= NUM_FP_ARG_REGS)
+       {
+         pcum->aapcs_nextnvrn = nvrn + nregs;
+         if (!aarch64_composite_type_p (type, mode))
+@@ -7394,6 +7453,7 @@ aarch64_layout_arg (cumulative_args_t pc
+               }
+             pcum->aapcs_reg = par;
+           }
++        pcum->darwinpcs_stack_bytes = 0;
+         return;
+       }
+       else
+@@ -7410,14 +7470,24 @@ aarch64_layout_arg (cumulative_args_t pc
+   /* C6 - C9.  though the sign and zero extension semantics are
+      handled elsewhere.  This is the case where the argument fits
+      entirely general registers.  */
++
+   if (allocate_ncrn && (ncrn + nregs <= NUM_ARG_REGS))
+     {
+       gcc_assert (nregs == 0 || nregs == 1 || nregs == 2);
+
++      if (TARGET_MACHO
++        && !arg.named)
++      {
++        pcum->aapcs_nextncrn = NUM_ARG_REGS;
++        goto on_stack;
++      }
++
+       /* C.8 if the argument has an alignment of 16 then the NGRN is
+        rounded up to the next even number.  */
+       if (nregs == 2
+-        && ncrn % 2)
++        && ncrn % 2
++        /* Darwin PCS deletes rule C.8.  */
++        && !TARGET_MACHO)
+       {
+         /* Emit a warning if the alignment changed when taking the
+            'packed' attribute into account.  */
+@@ -7487,8 +7557,8 @@ aarch64_layout_arg (cumulative_args_t pc
+           }
+         pcum->aapcs_reg = par;
+       }
+-
+       pcum->aapcs_nextncrn = ncrn + nregs;
++      pcum->darwinpcs_stack_bytes = 0;
+       return;
+     }
+
+@@ -7498,7 +7568,81 @@ aarch64_layout_arg (cumulative_args_t pc
+   /* The argument is passed on stack; record the needed number of words for
+      this argument and align the total size if necessary.  */
+ on_stack:
+-  pcum->aapcs_stack_words = size / UNITS_PER_WORD;
++
++  if (TARGET_MACHO)
++    {
++      /* Darwin does not round up the allocation for smaller entities to 8
++       bytes.  It only requires the natural alignment for these.
++
++       but we don't do this for:
++        * unnamed parms in variadic functions
++        * complex types
++        * unions
++        * aggregates (except for homogeneous ones which are handles as the
++          enclosed type).
++       each entry starts a new slot.
++
++      16 byte entities are naturally aligned on the stack.
++      There was no darwinpcs for GCC 9, so neither the implementation
++      change nor the warning should fire here (i.e. we do not need to check
++      if 16byte entities alter the stack size).  */
++
++      gcc_checking_assert (arg.named == pcum->named_p);
++      pcum->darwinpcs_arg_padding = BITS_PER_UNIT;
++      if (!pcum->named_p
++        || TREE_CODE (type) == COMPLEX_TYPE
++        || (TREE_CODE (type) == RECORD_TYPE
++            && !is_ha && !SCALAR_FLOAT_MODE_P (pcum->aapcs_vfp_rmode))
++        || TREE_CODE (type) == UNION_TYPE)
++      {
++        pcum->aapcs_stack_words = size / UNITS_PER_WORD;
++        pcum->darwinpcs_sub_word_offset = 0;
++        pcum->darwinpcs_sub_word_pos = 0;
++        pcum->darwinpcs_arg_boundary = MAX (alignment, PARM_BOUNDARY);
++        if (!pcum->named_p)
++          pcum->darwinpcs_arg_padding = PARM_BOUNDARY;
++        return;
++      }
++
++      /* Updated sub-word offset aligned for the new object.
++       We are looking for the case that the new object will fit after some
++       existing object(s) in the same stack slot.  In that case, we do not
++       need to add any more stack space for it.  */
++      int new_off
++      = ROUND_UP (pcum->darwinpcs_sub_word_pos, alignment / BITS_PER_UNIT);
++
++      if (new_off >= UNITS_PER_WORD)
++      {
++        /* That exceeds a stack slot, start a new one.  */
++        pcum->darwinpcs_sub_word_offset = 0;
++        pcum->darwinpcs_sub_word_pos = 0;
++        new_off = 0;
++      }
++      /* This is the end of the new object.  */
++      int new_pos = new_off + pcum->darwinpcs_stack_bytes;
++
++      if (pcum->darwinpcs_sub_word_pos == 0)
++      /* New stack slot, just allocate one or more words, and note where
++        the next arg will start.  */
++      pcum->aapcs_stack_words = size / UNITS_PER_WORD;
++      else if (new_pos <= UNITS_PER_WORD)
++      /* Old stack slot, object starts at new_off and goes to new_pos, we do
++         not add any stack space.  */
++      pcum->darwinpcs_sub_word_offset = new_off;
++      pcum->darwinpcs_sub_word_pos = new_pos;
++      pcum->darwinpcs_arg_boundary = alignment ;
++      if (pcum->last_named_p && new_pos > 0)
++      {
++        /* Round the last named arg to the start of the next stack slot.  */
++        if (new_pos <= 4)
++          pcum->darwinpcs_arg_padding = PARM_BOUNDARY;
++        else if (new_pos <= 6)
++          pcum->darwinpcs_arg_padding = 4 * BITS_PER_UNIT;
++        else if (pcum->darwinpcs_sub_word_pos <= 7)
++          pcum->darwinpcs_arg_padding = 2 * BITS_PER_UNIT;
++      }
++      return;
++    }
+
+   if (warn_pcs_change_le_gcc14
+       && abi_break_gcc_13
+@@ -7514,6 +7658,8 @@ on_stack:
+     inform (input_location, "parameter passing for argument of type "
+           "%qT changed in GCC 14.1", type);
+
++  /* size was already rounded up to PARM_BOUNDARY.  */
++  pcum->aapcs_stack_words = size / UNITS_PER_WORD;
+   if (alignment == 16 * BITS_PER_UNIT)
+     {
+       int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD);
+@@ -7622,12 +7768,33 @@ aarch64_init_cumulative_args (CUMULATIVE
+   pcum->aapcs_arg_processed = false;
+   pcum->aapcs_stack_words = 0;
+   pcum->aapcs_stack_size = 0;
++  pcum->darwinpcs_stack_bytes = 0;
++  pcum->darwinpcs_sub_word_offset = 0;
++  pcum->darwinpcs_sub_word_pos = 0;
++  pcum->darwinpcs_arg_boundary = BITS_PER_UNIT;
++  pcum->darwinpcs_arg_padding = BITS_PER_UNIT;
++  /* If we have been invoked for incoming args, then n_named will have been
++     set to -1, but we should have a function decl - so pick up the named
++     count from that.  If that fails, and we end up with -1, this effectively
++     corresponds to assuming that there is an arbitrary number of named
++     args.  */
++  pcum->darwinpcs_n_named = n_named;
++  if (n_named == (unsigned)-1 && fndecl)
++    {
++      tree fnt = TREE_TYPE (fndecl);
++      if (fnt && TYPE_ARG_TYPES (fnt))
++      pcum->darwinpcs_n_named = list_length (TYPE_ARG_TYPES (fnt));
++    }
++  pcum->darwinpcs_n_args_processed = 0;
++  pcum->named_p = pcum->darwinpcs_n_named != 0;
++  pcum->last_named_p = pcum->darwinpcs_n_named == 1;
+   pcum->silent_p = silent_p;
+   pcum->shared_za_flags
+     = (fntype ? aarch64_fntype_shared_flags (fntype, "za") : 0U);
+   pcum->shared_zt0_flags
+     = (fntype ? aarch64_fntype_shared_flags (fntype, "zt0") : 0U);
+   pcum->num_sme_mode_switch_args = 0;
++  pcum->aapcs_vfp_rmode = VOIDmode;
+
+   if (!silent_p
+       && !TARGET_FLOAT
+@@ -7666,9 +7833,11 @@ aarch64_function_arg_advance (cumulative
+       || pcum->pcs_variant == ARM_PCS_SVE)
+     {
+       aarch64_layout_arg (pcum_v, arg);
+-      gcc_assert ((pcum->aapcs_reg != NULL_RTX)
+-                != (pcum->aapcs_stack_words != 0));
+-      if (pcum->aapcs_reg
++      pcum->darwinpcs_n_args_processed++;
++      gcc_assert (TARGET_MACHO
++                || (pcum->aapcs_reg != NULL_RTX)
++                    != (pcum->aapcs_stack_words != 0));
++     if (pcum->aapcs_reg
+         && aarch64_call_switches_pstate_sm (pcum->isa_mode))
+       aarch64_record_sme_mode_switch_args (pcum);
+
+@@ -7679,6 +7848,12 @@ aarch64_function_arg_advance (cumulative
+       pcum->aapcs_stack_size += pcum->aapcs_stack_words;
+       pcum->aapcs_stack_words = 0;
+       pcum->aapcs_reg = NULL_RTX;
++      pcum->darwinpcs_arg_boundary = BITS_PER_UNIT;
++      pcum->darwinpcs_arg_padding = BITS_PER_UNIT;
++      pcum->named_p
++      = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named;
++      pcum->last_named_p
++      = pcum->darwinpcs_n_args_processed + 1 == pcum->darwinpcs_n_named;
+     }
+ }
+
+@@ -7690,12 +7865,15 @@ aarch64_function_arg_regno_p (unsigned r
+         || (PR_REGNUM_P (regno) && regno < P0_REGNUM + NUM_PR_ARG_REGS));
+ }
+
+-/* Implement FUNCTION_ARG_BOUNDARY.  Every parameter gets at least
+-   PARM_BOUNDARY bits of alignment, but will be given anything up
+-   to STACK_BOUNDARY bits if the type requires it.  This makes sure
+-   that both before and after the layout of each argument, the Next
+-   Stacked Argument Address (NSAA) will have a minimum alignment of
+-   8 bytes.  */
++/* Implement FUNCTION_ARG_BOUNDARY.
++   For AAPCS64, Every parameter gets at least PARM_BOUNDARY bits of
++   alignment, but will be given anything up to STACK_BOUNDARY bits
++   if the type requires it.  This makes sure that both before and after
++   the layout of each argument, the Next Stacked Argument Address (NSAA)
++   will have a minimum alignment of 8 bytes.
++
++   For darwinpcs, this is only called to lower va_arg entries which are
++   always aligned as for AAPCS64.  */
+
+ static unsigned int
+ aarch64_function_arg_boundary (machine_mode mode, const_tree type)
+@@ -7709,8 +7887,108 @@ aarch64_function_arg_boundary (machine_m
+                                                          &abi_break_gcc_14);
+   /* We rely on aarch64_layout_arg and aarch64_gimplify_va_arg_expr
+      to emit warnings about ABI incompatibility.  */
++#if TARGET_MACHO
++  /* This can only work for unnamed args.  */
++  machine_mode comp_mode = VOIDmode;
++  int nregs;
++  bool is_ha;
++  aarch64_vfp_is_call_or_return_candidate (mode, type, &comp_mode, &nregs,
++                                         &is_ha, /*silent*/true);
++  if (TREE_CODE (type) == COMPLEX_TYPE
++      || (TREE_CODE (type) == RECORD_TYPE
++        && !is_ha && !SCALAR_FLOAT_MODE_P (comp_mode))
++      || TREE_CODE (type) == UNION_TYPE)
++    return MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
++  return MIN (alignment, STACK_BOUNDARY);
++#else
+   alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
+   return alignment;
++#endif
++}
++
++/* For Darwin, we want to use the arg boundary computed when laying out the
++   function arg, to cope with items packed on the stack and the different
++   rules applied to unnamed parms.  */
++
++static unsigned int
++aarch64_function_arg_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED,
++                                const_tree type ATTRIBUTE_UNUSED,
++                                cumulative_args_t ca ATTRIBUTE_UNUSED)
++{
++  unsigned int abi_break_gcc_9;
++  unsigned int abi_break_gcc_13;
++  unsigned int abi_break_gcc_14;
++  unsigned int alignment
++    = aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9,
++                                    &abi_break_gcc_13, &abi_break_gcc_14);
++  /* We rely on aarch64_layout_arg and aarch64_gimplify_va_arg_expr
++     to emit warnings about ABI incompatibility.  */
++#if TARGET_MACHO
++  CUMULATIVE_ARGS *pcum = get_cumulative_args (ca);
++gcc_checking_assert (pcum->aapcs_arg_processed);
++
++  bool named_p = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named;
++gcc_checking_assert (named_p == pcum->named_p);
++  machine_mode comp_mode = VOIDmode;
++  int nregs;
++  bool is_ha;
++  aarch64_vfp_is_call_or_return_candidate (mode, type, &comp_mode, &nregs,
++                                         &is_ha, /*silent*/true);
++  bool no_pack = (TREE_CODE (type) == COMPLEX_TYPE
++      || (TREE_CODE (type) == RECORD_TYPE
++        && !is_ha && !SCALAR_FLOAT_MODE_P (comp_mode))
++      || TREE_CODE (type) == UNION_TYPE);
++
++  bool in_regs = (pcum->aapcs_reg != NULL_RTX);
++
++  if ((named_p && !no_pack) || in_regs)
++    ; /* Leave the alignment as natural.  */
++  else
++    alignment = MAX (alignment, PARM_BOUNDARY);
++gcc_checking_assert (alignment == pcum->darwinpcs_arg_boundary);
++  return MIN (alignment, STACK_BOUNDARY);
++
++#else
++  alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
++  return alignment;
++#endif
++}
++
++/* Implement TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA for darwinpcs which allows
++   non-standard passing of byte-aligned items [D.2].  This is done by pulling
++   the values out of the cumulative args struct.  */
++
++static unsigned int
++aarch64_function_arg_round_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED,
++                                      const_tree type ATTRIBUTE_UNUSED,
++                                      cumulative_args_t ca)
++{
++  CUMULATIVE_ARGS *pcum = get_cumulative_args (ca);
++gcc_checking_assert (pcum->aapcs_arg_processed);
++  bool named_p = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named;
++gcc_checking_assert (named_p == pcum->named_p);
++  bool last_named_p = pcum->darwinpcs_n_args_processed + 1 == pcum->darwinpcs_n_named;
++gcc_checking_assert (last_named_p == pcum->last_named_p);
++
++  unsigned boundary = BITS_PER_UNIT;
++  if (last_named_p && pcum->darwinpcs_sub_word_pos > 0)
++    {
++      /* Round the last named arg to the start of the next stack slot.  */
++      if (pcum->darwinpcs_sub_word_pos <= 4)
++      boundary = PARM_BOUNDARY;
++      else if (pcum->darwinpcs_sub_word_pos <= 6)
++      boundary = 4 * BITS_PER_UNIT;
++      else if (pcum->darwinpcs_sub_word_pos <= 7)
++      boundary = 2 * BITS_PER_UNIT;
++    }
++  else if (named_p)
++    /* Named args are naturally aligned, but with no rounding.  */
++    ;
++  else
++    /* un-named args are rounded to fill slots.  */
++    boundary = PARM_BOUNDARY;
++gcc_checking_assert (boundary == pcum->darwinpcs_arg_padding);
++  return boundary;
+ }
+
+ /* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE.  */
+@@ -11135,6 +11413,7 @@ aarch64_classify_address (struct aarch64
+       /* load literal: pc-relative constant pool entry.  Only supported
+          for SI mode or larger.  */
+       info->type = ADDRESS_SYMBOLIC;
++      info->offset = NULL_RTX;
+
+       if (!load_store_pair_p
+         && GET_MODE_SIZE (mode).is_constant (&const_size)
+@@ -11142,6 +11421,7 @@ aarch64_classify_address (struct aarch64
+       {
+         poly_int64 offset;
+         rtx sym = strip_offset_and_salt (x, &offset);
++
+         return ((LABEL_REF_P (sym)
+                  || (SYMBOL_REF_P (sym)
+                      && CONSTANT_POOL_ADDRESS_P (sym)
+@@ -11159,10 +11439,13 @@ aarch64_classify_address (struct aarch64
+         poly_int64 offset;
+         HOST_WIDE_INT const_offset;
+         rtx sym = strip_offset_and_salt (info->offset, &offset);
++
+         if (SYMBOL_REF_P (sym)
+             && offset.is_constant (&const_offset)
+             && (aarch64_classify_symbol (sym, const_offset)
+-                == SYMBOL_SMALL_ABSOLUTE))
++                  == SYMBOL_SMALL_ABSOLUTE
++                || aarch64_classify_symbol (sym, const_offset)
++                    == SYMBOL_MO_SMALL_PCR))
+           {
+             /* The symbol and offset must be aligned to the access size.  */
+             unsigned int align;
+@@ -11212,6 +11495,55 @@ aarch64_address_valid_for_prefetch_p (rt
+   if (!res)
+     return false;
+
++  /* For ELF targets using GAS, we emit prfm unconditionally; GAS will alter
++     the instruction to pick the prfum form where possible (i.e. when the
++     offset is in the range -256..255) and fall back to prfm otherwise.
++     We can reject cases where the offset exceeds the range usable by both
++     insns [-256..32760], or for offsets > 255 when the value is not divisible
++     by 8.
++     For Mach-O (Darwin) where the assembler uses the LLVM back end, that does
++     not yet do the substitution, so we must reject all prfum cases.  */
++  if (addr.offset)
++    {
++      HOST_WIDE_INT offs = INTVAL (addr.offset);
++      if (offs < -256) /* Out of range for both prfum and prfm.  */
++      return false;
++      if (offs > 32760) /* Out of range for prfm.  */
++      return false;
++      if (offs & 0x07) /* We cannot use prfm.  */
++      {
++        if (offs > 255) /* Out of range for prfum.  */
++          return false;
++        if (TARGET_MACHO)
++          return false;
++      }
++      if (TARGET_MACHO && offs < 0)
++      return false;
++    }
++
++  /* ... except writeback forms.  */
++  return addr.type != ADDRESS_REG_WB;
++}
++
++/* Return true if the address X is valid for a PRFUM instruction.
++   STRICT_P is true if we should do strict checking with
++   aarch64_classify_address.  */
++
++bool
++aarch64_address_valid_for_unscaled_prefetch_p (rtx x, bool strict_p)
++{
++  struct aarch64_address_info addr;
++
++  /* PRFUM accepts the same addresses as DImode, but constrained to a range
++     -256..255.  */
++  bool res = aarch64_classify_address (&addr, x, DImode, strict_p);
++  if (!res)
++    return false;
++
++  if (addr.offset && ((INTVAL (addr.offset) > 255)
++                     || (INTVAL (addr.offset) < -256)))
++     return false;
++
+   /* ... except writeback forms.  */
+   return addr.type != ADDRESS_REG_WB;
+ }
+@@ -12379,6 +12711,144 @@ sizetochar (int size)
+     }
+ }
+
++static void
++output_macho_postfix_expr (FILE *file, rtx x, const char *postfix)
++{
++  char buf[256];
++
++ restart:
++  switch (GET_CODE (x))
++    {
++    case PC:
++      putc ('.', file);
++      break;
++
++    case SYMBOL_REF:
++      if (SYMBOL_REF_DECL (x))
++      assemble_external (SYMBOL_REF_DECL (x));
++      assemble_name (file, XSTR (x, 0));
++      fprintf (file, "@%s", postfix);
++      break;
++
++    case LABEL_REF:
++      x = label_ref_label (x);
++      /* Fall through.  */
++    case CODE_LABEL:
++      ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
++      assemble_name (file, buf);
++      fprintf (file, "@%s", postfix);
++      break;
++
++    case CONST_INT:
++      fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
++      break;
++
++    case CONST:
++      /* This used to output parentheses around the expression,
++       but that does not work on the 386 (either ATT or BSD assembler).  */
++      output_macho_postfix_expr (file, XEXP (x, 0), postfix);
++      break;
++
++    case CONST_WIDE_INT:
++      /* We do not know the mode here so we have to use a round about
++       way to build a wide-int to get it printed properly.  */
++      {
++      wide_int w = wide_int::from_array (&CONST_WIDE_INT_ELT (x, 0),
++                                         CONST_WIDE_INT_NUNITS (x),
++                                         CONST_WIDE_INT_NUNITS (x)
++                                         * HOST_BITS_PER_WIDE_INT,
++                                         false);
++      print_decs (w, file);
++      }
++      break;
++
++    case CONST_DOUBLE:
++      if (CONST_DOUBLE_AS_INT_P (x))
++      {
++        /* We can use %d if the number is one word and positive.  */
++        if (CONST_DOUBLE_HIGH (x))
++          fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
++                   (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x),
++                   (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
++        else if (CONST_DOUBLE_LOW (x) < 0)
++          fprintf (file, HOST_WIDE_INT_PRINT_HEX,
++                   (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
++        else
++          fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
++      }
++      else
++      /* We can't handle floating point constants;
++         PRINT_OPERAND must handle them.  */
++      output_operand_lossage ("floating constant misused");
++      break;
++
++    case CONST_FIXED:
++      fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_FIXED_VALUE_LOW (x));
++      break;
++
++    case PLUS:
++      /* Some assemblers need integer constants to appear last (eg masm).  */
++      if (CONST_INT_P (XEXP (x, 0)))
++      {
++        output_macho_postfix_expr (file, XEXP (x, 1), postfix);
++        if (INTVAL (XEXP (x, 0)) >= 0)
++          fprintf (file, "+");
++        output_addr_const (file, XEXP (x, 0));
++      }
++      else
++      {
++        output_macho_postfix_expr (file, XEXP (x, 0), postfix);
++        if (!CONST_INT_P (XEXP (x, 1))
++            || INTVAL (XEXP (x, 1)) >= 0)
++          fprintf (file, "+");
++        output_addr_const (file, XEXP (x, 1));
++      }
++      break;
++
++    case MINUS:
++      /* Avoid outputting things like x-x or x+5-x,
++       since some assemblers can't handle that.  */
++      x = simplify_subtraction (x);
++      if (GET_CODE (x) != MINUS)
++      goto restart;
++
++      output_macho_postfix_expr (file, XEXP (x, 0), postfix);
++      fprintf (file, "-");
++      if ((CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) >= 0)
++        || GET_CODE (XEXP (x, 1)) == PC
++        || GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
++      output_addr_const (file, XEXP (x, 1));
++      else
++      {
++        fputs (targetm.asm_out.open_paren, file);
++        output_addr_const (file, XEXP (x, 1));
++        fputs (targetm.asm_out.close_paren, file);
++      }
++      break;
++
++    case ZERO_EXTEND:
++    case SIGN_EXTEND:
++    case SUBREG:
++    case TRUNCATE:
++      output_addr_const (file, XEXP (x, 0));
++      break;
++
++    case  UNSPEC:
++      if (XINT (x, 1) == UNSPEC_SALT_ADDR)
++      {
++        output_macho_postfix_expr (file, XVECEXP (x, 0, 0), postfix);
++        break;
++      }
++      /* FALLTHROUGH */
++    default:
++      if (targetm.asm_out.output_addr_const_extra (file, x))
++      break;
++
++      output_operand_lossage ("invalid expression as operand");
++    }
++
++}
++
+ /* Print operand X to file F in a target specific manner according to CODE.
+    The acceptable formatting commands given by CODE are:
+      'c':             An integer or symbol address without a preceding #
+@@ -12452,6 +12922,12 @@ aarch64_print_operand (FILE *f, rtx x, i
+       }
+       break;
+
++    case 'J':
++      output_macho_postfix_expr (f, x, "PAGEOFF");
++      break;
++    case 'O':
++      output_macho_postfix_expr (f, x, "GOTPAGEOFF");
++      break;
+     case 'e':
+       {
+       x = unwrap_const_vec_duplicate (x);
+@@ -12784,7 +13260,7 @@ aarch64_print_operand (FILE *f, rtx x, i
+     case 'A':
+       if (GET_CODE (x) == HIGH)
+       x = XEXP (x, 0);
+-
++#if !TARGET_MACHO
+       switch (aarch64_classify_symbolic_expression (x))
+       {
+       case SYMBOL_SMALL_GOT_4G:
+@@ -12815,9 +13291,26 @@ aarch64_print_operand (FILE *f, rtx x, i
+         break;
+       }
+       output_addr_const (asm_out_file, x);
++#endif
++#if TARGET_MACHO
++      switch (aarch64_classify_symbolic_expression (x))
++      {
++      case SYMBOL_MO_SMALL_PCR:
++        output_macho_postfix_expr (asm_out_file, x, "PAGE");
++        break;
++      case SYMBOL_MO_SMALL_GOT:
++        output_macho_postfix_expr (asm_out_file, x, "GOTPAGE");
++        break;
++      default:
++        /* large code model unimplemented.  */
++        gcc_unreachable ();
++        break;
++      }
++#endif
+       break;
+
+     case 'L':
++#if !TARGET_MACHO
+       switch (aarch64_classify_symbolic_expression (x))
+       {
+       case SYMBOL_SMALL_GOT_4G:
+@@ -12855,10 +13348,12 @@ aarch64_print_operand (FILE *f, rtx x, i
+       default:
+         break;
+       }
++#endif
+       output_addr_const (asm_out_file, x);
+       break;
+
+     case 'G':
++#if !TARGET_MACHO
+       switch (aarch64_classify_symbolic_expression (x))
+       {
+       case SYMBOL_TLSLE24:
+@@ -12867,6 +13362,7 @@ aarch64_print_operand (FILE *f, rtx x, i
+       default:
+         break;
+       }
++#endif
+       output_addr_const (asm_out_file, x);
+       break;
+
+@@ -13032,8 +13528,13 @@ aarch64_print_address_internal (FILE *f,
+       break;
+
+       case ADDRESS_LO_SUM:
++#if TARGET_MACHO
++      asm_fprintf (f, "[%s, #", reg_names [REGNO (addr.base)]);
++      output_macho_postfix_expr (f, addr.offset, "PAGEOFF");
++#else
+       asm_fprintf (f, "[%s, #:lo12:", reg_names [REGNO (addr.base)]);
+       output_addr_const (f, addr.offset);
++#endif
+       asm_fprintf (f, "]");
+       return true;
+
+@@ -13350,7 +13851,23 @@ aarch64_frame_pointer_required ()
+ {
+   /* If the function needs to record the incoming value of PSTATE.SM,
+      make sure that the slot is accessible from the frame pointer.  */
+-  return aarch64_need_old_pstate_sm ();
++  if (!TARGET_MACHO)
++    return aarch64_need_old_pstate_sm ();
++
++  /* We could do with some more general test.
++  gcc_checking_assert (!aarch64_need_old_pstate_sm ());*/
++
++  if (crtl->calls_eh_return || aarch64_need_old_pstate_sm ())
++    return true;
++
++  /* Not used in leaf functions (unless forced).  */
++  if (flag_omit_leaf_frame_pointer && leaf_function_p ())
++    return false;
++
++  /* NOTE: We are allowing the user to force omission of the frame
++     pointer, (despite that it is not ABI-compliant).  */
++
++  return flag_omit_frame_pointer != 1;
+ }
+
+ static bool
+@@ -13579,6 +14096,8 @@ aarch64_asm_output_labelref (FILE* f, co
+   asm_fprintf (f, "%U%s", name);
+ }
+
++#if !TARGET_MACHO
++
+ static void
+ aarch64_elf_asm_constructor (rtx symbol, int priority)
+ {
+@@ -13618,6 +14137,7 @@ aarch64_elf_asm_destructor (rtx symbol,
+       assemble_aligned_integer (POINTER_BYTES, symbol);
+     }
+ }
++#endif
+
+ const char*
+ aarch64_output_casesi (rtx *operands)
+@@ -13770,7 +14290,11 @@ aarch64_select_rtx_section (machine_mode
+   if (aarch64_can_use_per_function_literal_pools_p ())
+     return function_section (current_function_decl);
+
++#if TARGET_MACHO
++  return machopic_select_rtx_section (mode, x, align);
++#else
+   return default_elf_select_rtx_section (mode, x, align);
++#endif
+ }
+
+ /* Implement ASM_OUTPUT_POOL_EPILOGUE.  */
+@@ -16180,15 +16704,17 @@ aarch64_init_builtins ()
+ {
+   aarch64_general_init_builtins ();
+   aarch64_sve::init_builtins ();
+-#ifdef SUBTARGET_INIT_BUILTINS
+-  SUBTARGET_INIT_BUILTINS;
+-#endif
++  aarch64_init_subtarget_builtins ();
+ }
+
+ /* Implement TARGET_FOLD_BUILTIN.  */
+ static tree
+ aarch64_fold_builtin (tree fndecl, int nargs, tree *args, bool)
+ {
++#ifdef SUBTARGET_FOLD_BUILTIN
++  if (tree res = SUBTARGET_FOLD_BUILTIN (fndecl, nargs, args, false))
++    return res;
++#endif
+   unsigned int code = DECL_MD_FUNCTION_CODE (fndecl);
+   unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT;
+   tree type = TREE_TYPE (TREE_TYPE (fndecl));
+@@ -19425,10 +19951,14 @@ initialize_aarch64_code_model (struct gc
+       }
+       break;
+     case AARCH64_CMODEL_LARGE:
+-      if (opts->x_flag_pic)
++      if (TARGET_MACHO)
++      /* We need to implement fPIC here (arm64_32 also accepts the large
++         model).  */
++      sorry ("code model %qs not supported yet", "large");
++      else if (opts->x_flag_pic)
+       sorry ("code model %qs with %<-f%s%>", "large",
+              opts->x_flag_pic > 1 ? "PIC" : "pic");
+-      if (opts->x_aarch64_abi == AARCH64_ABI_ILP32)
++      else if (opts->x_aarch64_abi == AARCH64_ABI_ILP32)
+       sorry ("code model %qs not supported in ilp32 mode", "large");
+       break;
+     case AARCH64_CMODEL_TINY_PIC:
+@@ -21368,7 +21898,9 @@ aarch64_classify_symbol (rtx x, HOST_WID
+       case AARCH64_CMODEL_SMALL_SPIC:
+       case AARCH64_CMODEL_SMALL_PIC:
+       case AARCH64_CMODEL_SMALL:
+-        return SYMBOL_SMALL_ABSOLUTE;
++        return TARGET_MACHO
++               ? SYMBOL_MO_SMALL_PCR
++               : SYMBOL_SMALL_ABSOLUTE;
+
+       default:
+         gcc_unreachable ();
+@@ -21405,12 +21937,23 @@ aarch64_classify_symbol (rtx x, HOST_WID
+
+         return SYMBOL_TINY_ABSOLUTE;
+
+-
+       case AARCH64_CMODEL_SMALL_SPIC:
+       case AARCH64_CMODEL_SMALL_PIC:
+       case AARCH64_CMODEL_SMALL:
+-        if (!TARGET_PECOFF
+-            && (flag_pic || SYMBOL_REF_WEAK (x))
++#if TARGET_MACHO
++        if (TARGET_MACHO)
++          {
++            /* Constant pool addresses are always TU-local and PC-
++               relative.  We indirect common, external and weak
++               symbols (but weak only if not hidden).  */
++            if (!CONSTANT_POOL_ADDRESS_P (x)
++                && (MACHO_SYMBOL_MUST_INDIRECT_P (x)
++                    || !aarch64_symbol_binds_local_p (x)))
++              return SYMBOL_MO_SMALL_GOT;
++          }
++        else
++#endif
++        if (!TARGET_PECOFF && (flag_pic || SYMBOL_REF_WEAK (x))
+             && !aarch64_symbol_binds_local_p (x))
+           return aarch64_cmodel == AARCH64_CMODEL_SMALL_SPIC
+                   ? SYMBOL_SMALL_GOT_28K : SYMBOL_SMALL_GOT_4G;
+@@ -21421,7 +21964,8 @@ aarch64_classify_symbol (rtx x, HOST_WID
+               || offset_within_block_p (x, offset)))
+           return SYMBOL_FORCE_TO_MEM;
+
+-        return SYMBOL_SMALL_ABSOLUTE;
++        return TARGET_MACHO ? SYMBOL_MO_SMALL_PCR
++                            : SYMBOL_SMALL_ABSOLUTE;
+
+       case AARCH64_CMODEL_LARGE:
+         /* This is alright even in PIC code as the constant
+@@ -21551,7 +22095,10 @@ static GTY(()) tree va_list_type;
+      void *__vr_top;
+      int   __gr_offs;
+      int   __vr_offs;
+-   };  */
++   };
++
++  darwinpcs uses 'char *' for the va_list (in common with other platform
++  ports).  */
+
+ static tree
+ aarch64_build_builtin_va_list (void)
+@@ -21559,6 +22106,13 @@ aarch64_build_builtin_va_list (void)
+   tree va_list_name;
+   tree f_stack, f_grtop, f_vrtop, f_groff, f_vroff;
+
++  /* darwinpcs uses a simple char * for this.  */
++  if (TARGET_MACHO)
++    {
++      va_list_type = build_pointer_type (char_type_node);
++      return va_list_type;
++    }
++
+   /* Create the type.  */
+   va_list_type = lang_hooks.types.make_type (RECORD_TYPE);
+   /* Give it the required name.  */
+@@ -21631,6 +22185,13 @@ aarch64_expand_builtin_va_start (tree va
+   int vr_save_area_size = cfun->va_list_fpr_size;
+   int vr_offset;
+
++  /* darwinpcs uses the default, char * va_list impl.  */
++  if (TARGET_MACHO)
++    {
++      std_expand_builtin_va_start (valist, nextarg);
++      return;
++    }
++
+   cum = &crtl->args.info;
+   if (cfun->va_list_gpr_size)
+     gr_save_area_size = MIN ((NUM_ARG_REGS - cum->aapcs_ncrn) * UNITS_PER_WORD,
+@@ -21721,6 +22282,9 @@ aarch64_gimplify_va_arg_expr (tree valis
+   HOST_WIDE_INT size, rsize, adjust, align;
+   tree t, u, cond1, cond2;
+
++  if (TARGET_MACHO)
++    return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
++
+   indirect_p = pass_va_arg_by_reference (type);
+   if (indirect_p)
+     type = build_pointer_type (type);
+@@ -21925,8 +22489,18 @@ aarch64_gimplify_va_arg_expr (tree valis
+         field_ptr_t = double_ptr_type_node;
+         break;
+       case E_TFmode:
+-        field_t = long_double_type_node;
+-        field_ptr_t = long_double_ptr_type_node;
++        if (TARGET_MACHO)
++          {
++            /* Darwin has __float128, and long double is the same as
++               double.  */
++            field_t = float128_type_node;
++            field_ptr_t = aarch64_float128_ptr_type_node;
++          }
++        else
++          {
++            field_t = long_double_type_node;
++            field_ptr_t = long_double_ptr_type_node;
++          }
+         break;
+       case E_SDmode:
+         field_t = dfloat32_type_node;
+@@ -22009,6 +22583,9 @@ aarch64_setup_incoming_varargs (cumulati
+   int gr_saved = cfun->va_list_gpr_size;
+   int vr_saved = cfun->va_list_fpr_size;
+
++  if (TARGET_MACHO)
++    return default_setup_incoming_varargs (cum_v, arg, pretend_size, no_rtl);
++
+   /* The caller has advanced CUM up to, but not beyond, the last named
+      argument.  Advance a local copy of CUM past the last "real" named
+      argument, to find out how many registers are left over.  */
+@@ -22861,6 +23438,12 @@ aarch64_autovectorize_vector_modes (vect
+ static const char *
+ aarch64_mangle_type (const_tree type)
+ {
++  /* The darwinpcs ABI documents say that "__va_list" has to be
++     mangled as char *.  */
++  if (TARGET_MACHO
++      && lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type))
++    return "Pc";
++
+   /* The AArch64 ABI documents say that "__va_list" has to be
+      mangled as if it is in the "std" namespace.  */
+   if (lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type))
+@@ -22881,6 +23464,12 @@ aarch64_mangle_type (const_tree type)
+   if (TYPE_MAIN_VARIANT (type) == aarch64_mfp8_type_node)
+     return "u6__mfp8";
+
++  /* __float128 is mangled as "g" on darwin.  _Float128 is not mangled here,
++     but handled in common code (as "DF128_").  */
++  if (TARGET_MACHO && TYPE_MODE (type) == TFmode
++      && TYPE_MAIN_VARIANT (type) == float128t_type_node)
++    return "g";
++
+   /* Mangle AArch64-specific internal types.  TYPE_NAME is non-NULL_TREE for
+      builtin types.  */
+   if (TYPE_NAME (type) != NULL)
+@@ -23796,7 +24385,8 @@ aarch64_mov_operand_p (rtx x, machine_mo
+
+   /* GOT accesses are valid moves.  */
+   if (SYMBOL_REF_P (x)
+-      && aarch64_classify_symbolic_expression (x) == SYMBOL_SMALL_GOT_4G)
++      && (aarch64_classify_symbolic_expression (x) == SYMBOL_SMALL_GOT_4G
++        || aarch64_classify_symbolic_expression (x) == SYMBOL_MO_SMALL_GOT))
+     return true;
+
+   if (SYMBOL_REF_P (x) && mode == DImode && CONSTANT_ADDRESS_P (x))
+@@ -25265,12 +25855,8 @@ aarch64_asm_output_variant_pcs (FILE *st
+ static std::string aarch64_last_printed_arch_string;
+ static std::string aarch64_last_printed_tune_string;
+
+-/* Implement ASM_DECLARE_FUNCTION_NAME.  Output the ISA features used
+-   by the function fndecl.  */
+-
+-void
+-aarch64_declare_function_name (FILE *stream, const char* name,
+-                              tree fndecl)
++static void
++aarch64_function_options_preamble (tree fndecl)
+ {
+   tree target_parts = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+
+@@ -25305,15 +25891,60 @@ aarch64_declare_function_name (FILE *str
+                  this_tune->name);
+       aarch64_last_printed_tune_string = this_tune->name;
+     }
++}
++
++/* Implement ASM_DECLARE_FUNCTION_NAME.  Output the ISA features used
++   by the function fndecl.  */
++
++#if TARGET_MACHO
++void
++aarch64_darwin_declare_function_name (FILE *stream, const char* name,
++                                    tree fndecl)
++{
++  gcc_checking_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
++  gcc_checking_assert (!DECL_COMMON (fndecl));
+
++  /* Update .arch and .tune as needed.  */
++  aarch64_function_options_preamble (fndecl);
++
++  /* Darwin does not emit pcs variant info.  */
++
++  rtx decl_rtx = XEXP (DECL_RTL (fndecl), 0);
++  if (GET_CODE (decl_rtx) != SYMBOL_REF)
++    name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
++
++  if (! DECL_WEAK (fndecl)
++      && ((TREE_STATIC (fndecl) && !TREE_PUBLIC (fndecl))
++        || DECL_INITIAL (fndecl)))
++    machopic_define_symbol (DECL_RTL (fndecl));
++  if ((TREE_STATIC (fndecl) && !TREE_PUBLIC (fndecl))
++       || DECL_INITIAL (fndecl))
++    (* targetm.encode_section_info) (fndecl, DECL_RTL (fndecl), false);
++  ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl);
++
++  cfun->machine->label_is_assembled = true;
++}
++
++#else
++
++void
++aarch64_declare_function_name (FILE *stream, const char* name,
++                              tree fndecl)
++{
++  /* Update .arch and .tune as needed.  */
++  aarch64_function_options_preamble (fndecl);
++  /* Emit any necessary pcs information.  */
+   aarch64_asm_output_variant_pcs (stream, fndecl, name);
+
+   /* Don't forget the type directive for ELF.  */
++#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
+   ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function");
++#endif
+   ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl);
+
+   cfun->machine->label_is_assembled = true;
+ }
++#endif
+
+ /* Implement PRINT_PATCHABLE_FUNCTION_ENTRY.  */
+
+@@ -25370,12 +26001,17 @@ aarch64_output_patchable_area (unsigned
+ /* Implement ASM_OUTPUT_DEF_FROM_DECLS.  Output .variant_pcs for aliases.  */
+
+ void
+-aarch64_asm_output_alias (FILE *stream, const tree decl, const tree target)
++aarch64_asm_output_alias (FILE *stream, const tree decl,
++                        const tree target ATTRIBUTE_UNUSED)
+ {
+   const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
++#ifdef ASM_OUTPUT_DEF
+   const char *value = IDENTIFIER_POINTER (target);
++#endif
+   aarch64_asm_output_variant_pcs (stream, decl, name);
++#ifdef ASM_OUTPUT_DEF
+   ASM_OUTPUT_DEF (stream, name, value);
++#endif
+ }
+
+ /* Implement ASM_OUTPUT_EXTERNAL.  Output .variant_pcs for undefined
+@@ -25417,7 +26053,10 @@ aarch64_start_file (void)
+   asm_fprintf (asm_out_file, "\t.arch %s\n",
+              arch_string.c_str ());
+
+-  default_file_start ();
++   default_file_start ();
++#if TARGET_MACHO
++  darwin_file_start ();
++#endif
+ }
+
+ /* Emit load exclusive.  */
+@@ -25919,6 +26558,16 @@ aarch64_output_simd_imm (rtx const_vecto
+     }
+
+   gcc_assert (CONST_INT_P (info.u.mov.value));
++  unsigned HOST_WIDE_INT value = UINTVAL (info.u.mov.value);
++
++  /* We have signed chars which can result in a sign-extended 8bit value
++     which is then emitted as an unsigned hex value, and the LLVM back end
++     assembler rejects that as being too big.  */
++  if (TARGET_MACHO && (known_eq (GET_MODE_BITSIZE (info.elt_mode), 8)))
++    {
++      unsigned HOST_WIDE_INT mask = (1U << GET_MODE_BITSIZE (info.elt_mode))-1;
++      value &= mask;
++    }
+
+   if (which == AARCH64_CHECK_MOV)
+     {
+@@ -25945,16 +26594,16 @@ aarch64_output_simd_imm (rtx const_vecto
+                 ? "msl" : "lsl");
+       if (lane_count == 1)
+       snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX,
+-                mnemonic, UINTVAL (info.u.mov.value));
++                mnemonic, value);
+       else if (info.u.mov.shift)
+       snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, "
+                 HOST_WIDE_INT_PRINT_HEX ", %s %d", mnemonic, lane_count,
+-                element_char, UINTVAL (info.u.mov.value), shift_op,
++                element_char, value, shift_op,
+                 info.u.mov.shift);
+       else
+       snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, "
+                 HOST_WIDE_INT_PRINT_HEX, mnemonic, lane_count,
+-                element_char, UINTVAL (info.u.mov.value));
++                element_char, value);
+     }
+   else
+     {
+@@ -25975,12 +26624,12 @@ aarch64_output_simd_imm (rtx const_vecto
+       else if (info.u.mov.shift)
+       snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
+                 HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count,
+-                element_char, UINTVAL (info.u.mov.value), "lsl",
++                element_char, value, "lsl",
+                 info.u.mov.shift);
+       else
+       snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
+                 HOST_WIDE_INT_PRINT_DEC, mnemonic, lane_count,
+-                element_char, UINTVAL (info.u.mov.value));
++                element_char, value);
+     }
+   return templ;
+ }
+@@ -27864,6 +28513,8 @@ aarch64_expand_subvti (rtx op0, rtx low_
+ static unsigned HOST_WIDE_INT
+ aarch64_asan_shadow_offset (void)
+ {
++  if (TARGET_MACHO)
++    return 0; /* macOS uses a dynamic allocation.  */
+   if (TARGET_ILP32)
+     return (HOST_WIDE_INT_1 << 29);
+   else
+@@ -29257,7 +29908,8 @@ aarch64_libgcc_floating_mode_supported_p
+ }
+
+ /* Implement TARGET_SCALAR_MODE_SUPPORTED_P - return TRUE
+-   if MODE is [BH]Fmode, and punt to the generic implementation otherwise.  */
++   if MODE is [BH]Fmode, or TFmode on Mach-O, and punt to the generic
++   implementation otherwise.  */
+
+ static bool
+ aarch64_scalar_mode_supported_p (scalar_mode mode)
+@@ -29265,7 +29917,7 @@ aarch64_scalar_mode_supported_p (scalar_
+   if (DECIMAL_FLOAT_MODE_P (mode))
+     return default_decimal_float_supported_p ();
+
+-  return ((mode == HFmode || mode == BFmode)
++  return ((mode == HFmode || mode == BFmode || (mode == TFmode && TARGET_MACHO))
+         ? true
+         : default_scalar_mode_supported_p (mode));
+ }
+@@ -29356,7 +30008,8 @@ static machine_mode
+ aarch64_c_mode_for_floating_type (enum tree_index ti)
+ {
+   if (ti == TI_LONG_DOUBLE_TYPE)
+-    return TFmode;
++    /* Darwinpcs amends AAPCS S7 to use double as the type for long double.  */
++    return TARGET_MACHO ? DFmode : TFmode;
+   return default_mode_for_floating_type (ti);
+ }
+
+@@ -30239,19 +30892,37 @@ aarch64_sls_emit_shared_blr_thunks (FILE
+       continue;
+
+       const char *name = indirect_symbol_names[regnum];
+-      switch_to_section (get_named_section (decl, NULL, 0));
++      /* If the target uses a unique section for this switch to it.  */
++      if (DECL_SECTION_NAME (decl))
++      switch_to_section (get_named_section (decl, NULL, 0));
++      else
++      switch_to_section (text_section);
+       ASM_OUTPUT_ALIGN (out_file, 2);
+-      targetm.asm_out.globalize_label (out_file, name);
++      if (!TARGET_MACHO)
++      targetm.asm_out.globalize_label (out_file, name);
++#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
++      ASM_OUTPUT_TYPE_DIRECTIVE (out_file, name, "function");
++#endif
++      if (TARGET_MACHO)
++      {
++#ifdef ASM_WEAKEN_DECL
++        if (DECL_WEAK (decl))
++          ASM_WEAKEN_DECL (out_file, decl, name, 0);
++        else
++#endif
++          targetm.asm_out.globalize_decl_name (out_file, decl);
++      }
+       /* Only emits if the compiler is configured for an assembler that can
+        handle visibility directives.  */
+       targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN);
+-      ASM_OUTPUT_TYPE_DIRECTIVE (out_file, name, "function");
+       ASM_OUTPUT_LABEL (out_file, name);
+       aarch64_sls_emit_function_stub (out_file, regnum);
+       /* Use the most conservative target to ensure it can always be used by any
+        function in the translation unit.  */
+       asm_fprintf (out_file, "\tdsb\tsy\n\tisb\n");
++#ifdef ASM_DECLARE_FUNCTION_SIZE
+       ASM_DECLARE_FUNCTION_SIZE (out_file, name, decl);
++#endif
+     }
+ }
+
+@@ -31534,6 +32205,59 @@ aarch64_expand_reversed_crc_using_pmull
+     }
+ }
+
++#if TARGET_MACHO
++/* This handles the promotion of function return values.
++   It also handles function args under two specific curcumstances:
++     - called from combine with a register argument
++     - caller for a libcall with type == NULL.
++   The remaining cases for argument promotion are handled with access to
++   cumulative args data, below.  */
++machine_mode
++aarch64_darwin_promote_fn_mode (const_tree type, machine_mode mode,
++                             int *punsignedp,
++                             const_tree funtype ATTRIBUTE_UNUSED,
++                             int for_return ATTRIBUTE_UNUSED)
++{
++  /* With the amended use of promote using cargs, the only cases that arrive
++     here with for_return == 0 are from combine (where the value is definitely
++     in a register) and for libcalls, where type == NULL.  We want to promote
++     function return values in the callee, so this becomes pretty much
++     unconditional now.  */
++  if (type != NULL_TREE)
++    return promote_mode (type, mode, punsignedp);
++  return mode;
++}
++
++/* Ensure that we only promote the mode of named parms when they are passed in
++   a register.  Named values passed on the stack retain their original mode and
++   alignment.  */
++machine_mode
++aarch64_darwin_promote_function_mode_ca (cumulative_args_t ca,
++                                       function_arg_info arg,
++                                       const_tree funtype ATTRIBUTE_UNUSED,
++                                       int *punsignedp,
++                                       int for_return ATTRIBUTE_UNUSED)
++{
++  tree type = arg.type;
++  machine_mode mode = arg.mode;
++  machine_mode new_mode = promote_mode (type, mode, punsignedp);
++  if (new_mode == mode || arg.named == false
++      || GET_MODE_CLASS (new_mode) != MODE_INT
++      || known_gt (GET_MODE_SIZE (new_mode), 4))
++    return new_mode;
++
++  CUMULATIVE_ARGS *pcum = get_cumulative_args (ca);
++  /* Make sure that changes in assumption do not get missed.  */
++  gcc_checking_assert (for_return == 0 && new_mode == SImode
++                     && !pcum->aapcs_arg_processed);
++  /* We have a named integer value that fits in a reg; if there's one available
++     then promote the value.  */
++  if (pcum->aapcs_ncrn < 8)
++    return new_mode;
++  return mode;
++}
++#endif
++
+ /* Target-specific selftests.  */
+
+ #if CHECKING_P
+@@ -31759,6 +32483,15 @@ aarch64_run_selftests (void)
+ #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
+ #endif
+
++#if TARGET_MACHO
++#undef TARGET_ASM_UNALIGNED_HI_OP
++#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
++#undef TARGET_ASM_UNALIGNED_SI_OP
++#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
++#undef TARGET_ASM_UNALIGNED_DI_OP
++#define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
++#endif
++
+ #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
+ #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
+   hook_bool_const_tree_hwi_hwi_const_tree_true
+@@ -31864,6 +32597,12 @@ aarch64_run_selftests (void)
+ #undef TARGET_FUNCTION_ARG_BOUNDARY
+ #define TARGET_FUNCTION_ARG_BOUNDARY aarch64_function_arg_boundary
+
++#undef TARGET_FUNCTION_ARG_BOUNDARY_CA
++#define TARGET_FUNCTION_ARG_BOUNDARY_CA aarch64_function_arg_boundary_ca
++
++#undef  TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA
++#define TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA aarch64_function_arg_round_boundary_ca
++
+ #undef TARGET_FUNCTION_ARG_PADDING
+ #define TARGET_FUNCTION_ARG_PADDING aarch64_function_arg_padding
+
+@@ -32126,8 +32865,16 @@ aarch64_libgcc_floating_mode_supported_p
+
+ /* Section anchor support.  */
+
++#if !TARGET_MACHO
+ #undef TARGET_MIN_ANCHOR_OFFSET
+ #define TARGET_MIN_ANCHOR_OFFSET -256
++#else
++/* The static linker is allowed to split objects at visible symbol boundaries,
++   so we must ensure that anchors are at the beginning of a block.  */
++#undef TARGET_MIN_ANCHOR_OFFSET
++#define TARGET_MIN_ANCHOR_OFFSET 0
++#endif
++
+
+ /* Limit the maximum anchor offset to 4k-1, since that's the limit for a
+    byte offset; we can do much more for larger data types, but have no way
+@@ -32184,6 +32931,11 @@ aarch64_libgcc_floating_mode_supported_p
+ #undef TARGET_ASAN_SHADOW_OFFSET
+ #define TARGET_ASAN_SHADOW_OFFSET aarch64_asan_shadow_offset
+
++#if TARGET_MACHO
++#undef TARGET_ASAN_DYNAMIC_SHADOW_OFFSET_P
++#define TARGET_ASAN_DYNAMIC_SHADOW_OFFSET_P hook_bool_void_true
++#endif
++
+ #undef TARGET_LEGITIMIZE_ADDRESS
+ #define TARGET_LEGITIMIZE_ADDRESS aarch64_legitimize_address
+
+@@ -32232,7 +32984,7 @@ aarch64_libgcc_floating_mode_supported_p
+
+ /* The architecture reserves bits 0 and 1 so use bit 2 for descriptors.  */
+ #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
+-#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 4
++#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS AARCH64_CUSTOM_FUNCTION_TEST
+
+ #undef TARGET_HARD_REGNO_NREGS
+ #define TARGET_HARD_REGNO_NREGS aarch64_hard_regno_nregs
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.h        Sun Jul 19 11:17:43 2026
@@ -0,0 +1,82 @@
+$NetBSD: patch-gcc_config_aarch64_aarch64.h,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/aarch64.h.orig  2026-06-12 06:09:06.118518203 +0000
++++ gcc/config/aarch64/aarch64.h
+@@ -72,6 +72,10 @@
+ #define BYTES_BIG_ENDIAN (TARGET_BIG_END != 0)
+ #define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN)
+
++/* If this is non-zero then generated code of the object format, ABI and
++   assembler syntax used by Darwin (Mach-O) platforms.  */
++#define TARGET_MACHO          0
++
+ #define UNITS_PER_WORD                8
+
+ #define UNITS_PER_VREG                16
+@@ -132,6 +136,12 @@
+ /* Heap alignment (same as BIGGEST_ALIGNMENT and STACK_BOUNDARY).  */
+ #define MALLOC_ABI_ALIGNMENT  128
+
++/* We will and with this value to test if a custom function descriptor needs
++   a static chain.  The function boundary must the adjusted so that the bit
++   this represents is no longer part of the address.  0 Disables the custom
++   function descriptors.  */
++#define AARCH64_CUSTOM_FUNCTION_TEST 4
++
+ /* Defined by the ABI */
+ #define WCHAR_TYPE "unsigned int"
+ #define WCHAR_TYPE_SIZE                       32
+@@ -1198,6 +1208,24 @@ typedef struct
+                                  aapcs_reg == NULL_RTX.  */
+   int aapcs_stack_size;               /* The total size (in words, per 8 byte) of the
+                                  stack arg area so far.  */
++
++  /* In the darwinpcs, items smaller than one word are packed onto the stack
++     naturally aligned.  Unnamed parameters passed in a variadic call are,
++     however, aligned the same way as the AAPCS64.  This means that we need to
++     pad the last named arg to the next parm boundary (and hence notice when
++     we are processing that arg).  */
++  int darwinpcs_stack_bytes;  /* If the argument is passed on the stack, this
++                                 the byte-size.  */
++  int darwinpcs_sub_word_offset;/* This is the offset of this arg within a word
++                                 when placing smaller items for darwinpcs.  */
++  int darwinpcs_sub_word_pos; /* The next byte available within the word for
++                                 darwinpcs.  */
++  unsigned darwinpcs_arg_boundary; /* The computed argument boundary.  */
++  unsigned darwinpcs_arg_padding; /* The computed argument padding.  */
++  unsigned darwinpcs_n_named; /* Number of named arguments.  */
++  unsigned darwinpcs_n_args_processed; /* Processed so far.  */
++  bool named_p;                       /* Is this arg named? */
++  bool last_named_p;          /* Is this the last named arg? */
+   bool silent_p;              /* True if we should act silently, rather than
+                                  raise an error for invalid calls.  */
+
+@@ -1522,8 +1550,13 @@ extern const char *is_host_cpu_not_armv8
+ #define ASM_CPU_SPEC \
+    MARCH_REWRITE_SPEC
+
++#ifndef SUBTARGET_EXTRA_SPECS
++#define SUBTARGET_EXTRA_SPECS
++#endif
++
+ #define EXTRA_SPECS                                           \
+-  { "asm_cpu_spec",           ASM_CPU_SPEC }
++  { "asm_cpu_spec",           ASM_CPU_SPEC },                 \
++  SUBTARGET_EXTRA_SPECS
+
+ #define ASM_OUTPUT_POOL_EPILOGUE  aarch64_asm_output_pool_epilogue
+
+@@ -1541,6 +1574,10 @@ extern GTY(()) tree aarch64_fp16_ptr_typ
+    bfloat16_type_node.  Defined in aarch64-builtins.cc.  */
+ extern GTY(()) tree aarch64_bf16_ptr_type_node;
+
++/* A pointer to the user-visible __float128 (on Mach-O).  Defined in
++   aarch64-builtins.c.  */
++extern GTY(()) tree aarch64_float128_ptr_type_node;
++
+ /* The generic unwind code in libgcc does not initialize the frame pointer.
+    So in order to unwind a function using a frame pointer, the very first
+    function that is unwound must save the frame pointer.  That way the frame
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.md
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.md:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.md       Sun Jul 19 11:17:43 2026
@@ -0,0 +1,82 @@
+$NetBSD: patch-gcc_config_aarch64_aarch64.md,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/aarch64.md.orig 2026-06-12 06:09:06.119518218 +0000
++++ gcc/config/aarch64/aarch64.md
+@@ -392,6 +392,7 @@
+     ;; Wraps a constant integer that should be multiplied by the number
+     ;; of quadwords in an SME vector.
+     UNSPEC_SME_VQ
++    UNSPEC_MACHOPIC_OFFSET    ; Common to Mach-O ports.
+ ])
+ 
+ (define_c_enum "unspecv" [
+@@ -1062,6 +1063,37 @@
+   [(set_attr "type" "load_4")]
+ )
+ 
++(define_insn "prefetch_unscaled"
++  [(prefetch (match_operand:DI 0 "aarch64_unscaled_prefetch_operand" "Du")
++            (match_operand:QI 1 "const_int_operand" "")
++            (match_operand:QI 2 "const_int_operand" ""))]
++  ""
++  {
++    const char * pftype[2][4] =
++    {
++      {"prfum\\tPLDL1STRM, %0",
++       "prfum\\tPLDL3KEEP, %0",
++       "prfum\\tPLDL2KEEP, %0",
++       "prfum\\tPLDL1KEEP, %0"},
++      {"prfum\\tPSTL1STRM, %0",
++       "prfum\\tPSTL3KEEP, %0",
++       "prfum\\tPSTL2KEEP, %0",
++       "prfum\\tPSTL1KEEP, %0"},
++    };
++
++    int locality = INTVAL (operands[2]);
++
++    gcc_assert (IN_RANGE (locality, 0, 3));
++
++    /* PRFUM accepts the same addresses as a 64-bit LDR so wrap
++       the address into a DImode MEM so that aarch64_print_operand knows
++       how to print it.  */
++    operands[0] = gen_rtx_MEM (DImode, operands[0]);
++    return pftype[INTVAL(operands[1])][locality];
++  }
++  [(set_attr "type" "load_4")]
++)
++
+ (define_insn "trap"
+   [(trap_if (const_int 1) (const_int 8))]
+   ""
+@@ -1598,7 +1630,7 @@
+      [w  , m  ; load_4   , fp  , 4] ldr\t%s0, %1
+      [m  , r Z; store_4  , *   , 4] str\t%w1, %0
+      [m  , w  ; store_4  , fp  , 4] str\t%s1, %0
+-     [r  , Usw; load_4   , *   , 8] adrp\t%x0, %A1\;ldr\t%w0, [%x0, %L1]
++     [r  , Usw; load_4   , *   , 8] << TARGET_MACHO ? \"adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %O1]\" : \"adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1]\";
+      [r  , Usa; adr      , *   , 4] adr\t%x0, %c1
+      [r  , Ush; adr      , *   , 4] adrp\t%x0, %A1
+      [w  , r Z; f_mcr    , fp  , 4] fmov\t%s0, %w1
+@@ -1637,7 +1669,7 @@
+      [w, m   ; load_8   , fp  , 4] ldr\t%d0, %1
+      [m, r Z ; store_8  , *   , 4] str\t%x1, %0
+      [m, w   ; store_8  , fp  , 4] str\t%d1, %0
+-     [r, Usw ; load_8   , *   , 8] << TARGET_ILP32 ? "adrp\t%0, %A1\;ldr\t%w0, [%0, %L1]" : "adrp\t%0, %A1\;ldr\t%0, [%0, %L1]";
++     [r, Usw ; load_8   , *   , 8] << TARGET_ILP32 ? (TARGET_MACHO ? \"adrp\\t%0, %A1\;ldr\\t%w0, [%0, %O1]\" : \"adrp\\t%0, %A1\;ldr\\t%w0, [%0, %L1]\") : (TARGET_MACHO ? \"adrp\\t%0, 
%A1\;ldr\\t%0, [%0, %O1]\" : \"adrp\\t%0, %A1\;ldr\\t%0, [%0, %L1]\");
+      [r, Usa ; adr      , *   , 4] adr\t%x0, %c1
+      [r, Ush ; adr      , *   , 4] adrp\t%x0, %A1
+      [w, r Z ; f_mcr    , fp  , 4] fmov\t%d0, %x1
+@@ -7662,7 +7694,10 @@
+       (lo_sum:P (match_operand:P 1 "register_operand" "r")
+                 (match_operand 2 "aarch64_valid_symref" "S")))]
+   ""
+-  "add\\t%<w>0, %<w>1, :lo12:%c2"
++  { return TARGET_MACHO
++    ? "add\\t%<w>0, %<w>1, %J2;"
++    : "add\\t%<w>0, %<w>1, :lo12:%c2";
++  }
+   [(set_attr "type" "alu_imm")]
+ )
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.opt
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.opt:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_aarch64.opt      Sun Jul 19 11:17:43 2026
@@ -0,0 +1,21 @@
+$NetBSD: patch-gcc_config_aarch64_aarch64.opt,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/aarch64.opt.orig        2026-06-12 06:09:06.119518218 +0000
++++ gcc/config/aarch64/aarch64.opt
+@@ -202,6 +202,13 @@ Enum(aarch64_abi) String(ilp32) Value(AA
+ EnumValue
+ Enum(aarch64_abi) String(lp64) Value(AARCH64_ABI_LP64)
+
++EnumValue
++Enum(aarch64_abi) String(darwinpcs) Value(AARCH64_ABI_LP64)
++
++m64
++Target RejectNegative Alias(mabi=, darwinpcs)
++On Darwin for compatibility with other platform variants.
++
+ mpc-relative-literal-loads
+ Target Save Var(pcrelative_literal_loads) Init(2) Save
+ PC relative literal loads.
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_constraints.md
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_constraints.md:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_constraints.md   Sun Jul 19 11:17:43 2026
@@ -0,0 +1,30 @@
+$NetBSD: patch-gcc_config_aarch64_constraints.md,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/constraints.md.orig     2026-06-12 06:09:06.122518264 +0000
++++ gcc/config/aarch64/constraints.md
+@@ -206,7 +206,9 @@
+    A constraint that matches a small GOT access."
+   (and (match_code "const,symbol_ref")
+        (match_test "aarch64_classify_symbolic_expression (op)
+-                   == SYMBOL_SMALL_GOT_4G")))
++                   == SYMBOL_SMALL_GOT_4G
++                  || aarch64_classify_symbolic_expression (op)
++                   == SYMBOL_MO_SMALL_GOT")))
+ 
+ (define_constraint "Uss"
+   "@internal
+@@ -581,6 +583,11 @@
+  An address valid for a prefetch instruction."
+  (match_test "aarch64_address_valid_for_prefetch_p (op, true)"))
+ 
++(define_address_constraint "Du"
++  "@internal
++ An address valid for a prefetch instruction with an unscaled offset."
++ (match_test "aarch64_address_valid_for_unscaled_prefetch_p (op, true)"))
++
+ (define_constraint "vgb"
+   "@internal
+    A constraint that matches an immediate offset valid for SVE LD1B
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_darwin.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_darwin.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_darwin.h Sun Jul 19 11:17:43 2026
@@ -0,0 +1,276 @@
+$NetBSD: patch-gcc_config_aarch64_darwin.h,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/darwin.h.orig   2026-07-19 09:48:42.153772651 +0000
++++ gcc/config/aarch64/darwin.h
+@@ -0,0 +1,268 @@
++/* Target definitions for Arm64/Aarch64 running on macOS/iOS.
++
++Copyright The GNU Toolchain Authors.
++Contributed by Iain Sandoe.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/* Enable Mach-O bits in generic Aarch64 code.  */
++#undef TARGET_MACHO
++#define TARGET_MACHO 1
++
++#undef DARWIN_ARM64
++#define DARWIN_ARM64 1
++
++/* This is used in generic code in darwin.cc (at present, we have no support
++   for the arm64_32 target).  */
++#undef TARGET_64BIT
++#define TARGET_64BIT 1
++
++#undef  PTRDIFF_TYPE
++#define PTRDIFF_TYPE "long int"
++
++#undef TARGET_PROMOTE_FUNCTION_MODE
++#define TARGET_PROMOTE_FUNCTION_MODE aarch64_darwin_promote_fn_mode
++
++#undef TARGET_PROMOTE_FUNCTION_MODE_CA
++#define TARGET_PROMOTE_FUNCTION_MODE_CA aarch64_darwin_promote_function_mode_ca
++
++/* NOTE that arm64_32 is a valid thing and corresponds to darwinpcs
++   and TARGET_ILP32, but we are not implementing that for now.  */
++#define TARGET_OS_CPP_BUILTINS()              \
++  do {                                                \
++    builtin_define ("__LITTLE_ENDIAN__");     \
++    builtin_define ("__arm64");                       \
++    builtin_define ("__arm64__");             \
++    darwin_cpp_builtins (pfile);              \
++  } while (0)
++
++/* In Darwin's Arm64 ABI, chars are signed.  */
++
++#undef DEFAULT_SIGNED_CHAR
++#define DEFAULT_SIGNED_CHAR 1
++
++/* Disable custom function descriptors on Darwin (we use heap-based
++   trampolines).  */
++#undef AARCH64_CUSTOM_FUNCTION_TEST
++#define AARCH64_CUSTOM_FUNCTION_TEST 0
++
++/* Non-PIE executables are forbidden by the Arm64-darwin security model;
++   remove the option from link-lines since they just produce a warning from
++   ld64 and are then ignored anyway.  */
++#undef DARWIN_NOPIE_SPEC
++#define DARWIN_NOPIE_SPEC \
++" %<no-pie %<fno-pie %<fno-PIE "
++
++/* Force the default endianness and ABI flags onto the command line
++   in order to make the other specs easier to write.  Match clang in
++   silently ignoring mdynamic-no-pic */
++#undef DRIVER_SELF_SPECS
++#define DRIVER_SELF_SPECS \
++"%{mbig-endian:%eDarwin platforms do not support big-endian arm64}" \
++"%{!mlittle-endian:-mlittle-endian} " \
++"%{mabi=ilp32:%eSorry, support for Darwin ilp32 arm64 is not implemented} " \
++"%{!mabi=*:-mabi=lp64} " \
++" %<mdynamic-no-pic* " \
++  MCPU_MTUNE_NATIVE_SPECS \
++  SUBTARGET_DRIVER_SELF_SPECS
++
++/* We want -fPIC by default, unless we're using -static to compile for
++   the kernel or some such.  */
++
++#undef CC1_SPEC
++#define CC1_SPEC \
++"%{!mkernel:%{!static:-fPIC}} " DARWIN_CC1_SPEC
++
++#undef ASM_SPEC
++#define ASM_SPEC "-arch %(darwin_arch) %{march*} %{mtune*} "\
++  ASM_OPTIONS " %{static} " ASM_MMACOSX_VERSION_MIN_SPEC
++
++#undef ENDFILE_SPEC
++#define ENDFILE_SPEC \
++  " " TM_DESTRUCTOR
++
++/* The arch is known as 'arm64' by the system tools.  */
++#define DARWIN_ARCH_SPEC "arm64"
++
++#undef SUBTARGET_EXTRA_SPECS
++#define SUBTARGET_EXTRA_SPECS                                 \
++  DARWIN_EXTRA_SPECS                                          \
++  { "darwin_arch", DARWIN_ARCH_SPEC },                                \
++  { "darwin_crt2", "" },                                      \
++  { "darwin_subarch", DARWIN_ARCH_SPEC },
++
++#undef TARGET_ASM_FILE_END
++#define TARGET_ASM_FILE_END darwin_file_end
++
++/* Darwin binds locally for PIC code (the default) without which
++   we lose many in-lineing opportunities.  */
++#undef TARGET_BINDS_LOCAL_P
++#define TARGET_BINDS_LOCAL_P darwin_binds_local_p
++
++/* Define the syntax of pseudo-ops, labels and comments.  */
++
++#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
++/* Support for -falign-* switches.  Use .p2align to ensure that code
++   sections are padded with NOP instructions, rather than zeros.  */
++#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE, LOG, MAX_SKIP)                \
++  do                                                          \
++    {                                                         \
++      if ((LOG) != 0)                                         \
++      {                                                       \
++        if ((MAX_SKIP) == 0)                                  \
++          fprintf ((FILE), "\t.p2align %d\n", (int) (LOG));   \
++        else                                                  \
++          fprintf ((FILE), "\t.p2align %d,,%d\n",             \
++                   (int) (LOG), (int) (MAX_SKIP));            \
++      }                                                       \
++    } while (0)
++
++#endif /* HAVE_GAS_MAX_SKIP_P2ALIGN */
++
++/* String containing the assembler's comment-starter.  */
++
++#define ASM_COMMENT_START ";"
++
++/* Define the syntax of pseudo-ops, labels and comments.  */
++
++#define LPREFIX "L"
++
++/* Assembler pseudos to introduce constants of various size.  */
++
++#define ASM_BYTE "\t.byte\t"
++#define ASM_SHORT "\t.word\t"
++#define ASM_LONG "\t.long\t"
++#define ASM_QUAD "\t.quad\t"
++
++/* darwinpcs reserves X18.  */
++#undef FIXED_X18
++#define FIXED_X18 1
++#undef CALL_USED_X18
++#define CALL_USED_X18 0
++
++/* Assign a static chain regnum.  At the moment using R16 (IP0) is
++   available.  */
++#undef STATIC_CHAIN_REGNUM
++#define STATIC_CHAIN_REGNUM   R16_REGNUM
++
++/* Heap trampoline support in a CRT.  */
++#undef DARWIN_HEAP_T_LIB
++#define DARWIN_HEAP_T_LIB " -lheapt_w "
++
++#define SUBTARGET_ENCODE_SECTION_INFO  darwin_encode_section_info
++
++#undef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
++#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \
++  if (TARGET_64BIT)                                                   \
++    {                                                                 \
++      if ((SIZE) == 4 && ((ENCODING) & 0x70) == DW_EH_PE_pcrel)               \
++      {                                                               \
++        static unsigned got_pcr_count = 0;                            \
++        fprintf (FILE, "L_got_pcr%d:\n" ASM_LONG, got_pcr_count);     \
++        assemble_name (FILE, XSTR (ADDR, 0));                         \
++        fprintf (FILE, "@GOT-L_got_pcr%d", got_pcr_count++);          \
++        goto DONE;                                                    \
++      }                                                               \
++    }                                                                 \
++  else                                                                        \
++    {                                                                 \
++      if (ENCODING == ASM_PREFERRED_EH_DATA_FORMAT (2, 1))            \
++      {                                                               \
++        gcc_unreachable (); /* no 32b support yet.*/                  \
++        goto DONE;                                                    \
++      }                                                               \
++    }
++
++#undef ASM_DECLARE_FUNCTION_NAME
++#define ASM_DECLARE_FUNCTION_NAME(STR, NAME, DECL)    \
++  aarch64_darwin_declare_function_name (STR, NAME, DECL)
++
++/* Darwin assemblers support the .ident directive.  */
++
++#undef TARGET_ASM_OUTPUT_IDENT
++#define TARGET_ASM_OUTPUT_IDENT default_asm_output_ident_directive
++
++/* Darwin has experimental support for section anchors on aarch64*; it is
++   not enabled by default (the -fsection-anchors is required), see below.  */
++
++#undef TARGET_ASM_OUTPUT_ANCHOR
++#define TARGET_ASM_OUTPUT_ANCHOR darwin_asm_output_anchor
++
++#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
++#define TARGET_USE_ANCHORS_FOR_SYMBOL_P darwin_use_anchors_for_symbol_p
++
++#undef DARWIN_SECTION_ANCHORS
++#define DARWIN_SECTION_ANCHORS 1
++
++/* Executable stack is prohibited by the system security policy.  */
++#undef HAVE_ENABLE_EXECUTE_STACK
++
++/* Pull in the stuff common to all Darwin-based platforms.  */
++#define C_COMMON_OVERRIDE_OPTIONS                             \
++  do {                                                                \
++    SUBTARGET_C_COMMON_OVERRIDE_OPTIONS;                      \
++  } while (0)
++
++/* We do not have a definition for a tiny code model.
++   Section anchors are (probably) not useful with ld64 atom model so
++   default them off - this can be overridden by the user at present.
++   mdynamic-no-pic is silently ignored by clang (and not applicable
++   to this port).  */
++#undef SUBTARGET_OVERRIDE_OPTIONS
++#define SUBTARGET_OVERRIDE_OPTIONS                                    \
++  do {                                                                        \
++    if (global_options.x_aarch64_cmodel_var == AARCH64_CMODEL_TINY)   \
++      sorry ("code model %qs is not supported on Darwin platforms",   \
++           "tiny");                                                   \
++    if (!global_options_set.x_flag_section_anchors)                   \
++      flag_section_anchors = 0;                                               \
++    target_flags &= ~MASK_MACHO_DYNAMIC_NO_PIC;                               \
++  } while (0);                                                                \
++  SUBSUBTARGET_OVERRIDE_OPTIONS
++
++#undef  SUBTARGET_INIT_BUILTINS
++#define SUBTARGET_INIT_BUILTINS                                               \
++  do {                                                                        \
++    aarch64_builtin_decls[AARCH64_BUILTIN_CFSTRING]                   \
++      = darwin_init_cfstring_builtins ((AARCH64_BUILTIN_CFSTRING << AARCH64_BUILTIN_SHIFT) | AARCH64_BUILTIN_GENERAL); \
++  } while(0)
++
++/* Darwin on Arm64 uses dwarf-2.  */
++#ifndef DARWIN_PREFER_DWARF
++# undef PREFERRED_DEBUGGING_TYPE
++# define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
++#endif
++
++#undef REGISTER_SUBTARGET_PRAGMAS
++#define REGISTER_SUBTARGET_PRAGMAS() DARWIN_REGISTER_TARGET_PRAGMAS()
++
++#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
++#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES darwin_set_default_type_attributes
++
++/* FIXME:  CHECK Define the shadow offset for asan.  */
++#undef SUBTARGET_SHADOW_OFFSET
++#define SUBTARGET_SHADOW_OFFSET (HOST_WIDE_INT_1 << 44)
++
++/* First available SYMBOL flag bit for use by subtargets.  */
++#define SYMBOL_FLAG_SUBT_DEP (SYMBOL_FLAG_MACH_DEP)
++
++#undef ASM_OUTPUT_DEF_FROM_DECLS
++
++#undef CLEAR_INSN_CACHE
++#define CLEAR_INSN_CACHE(beg, end)                            \
++  extern void sys_icache_invalidate(void *start, size_t len); \
++  sys_icache_invalidate ((beg), (size_t)((end)-(beg)))
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_driver-aarch64.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_driver-aarch64.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_driver-aarch64.cc        Sun Jul 19 11:17:43 2026
@@ -0,0 +1,99 @@
+$NetBSD: patch-gcc_config_aarch64_driver-aarch64.cc,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/driver-aarch64.cc.orig  2026-06-12 06:09:06.122518264 +0000
++++ gcc/config/aarch64/driver-aarch64.cc
+@@ -28,6 +28,76 @@
+ #include "aarch64-protos.h"
+ #include "aarch64-feature-deps.h"
+
++
++/* Default architecture to use if -mcpu=native did not detect a known CPU.  */
++#if TARGET_MACHO
++#define DEFAULT_ARCH "apple-m1"
++#else
++#define DEFAULT_ARCH "8A"
++#define DEFAULT_CPU "generic-armv8-a"
++#endif
++
++
++#if defined(__APPLE__)
++/* macOS does not have /proc/cpuinfo and needs a different approach,
++   based on sysctl.  It is much simpler.  */
++#include <sys/types.h>
++#include <sys/sysctl.h>
++
++const char *
++host_detect_local_cpu (ATTRIBUTE_UNUSED int argc, ATTRIBUTE_UNUSED const char **argv)
++{
++  bool arch = false;
++  bool tune = false;
++  bool cpu = false;
++  const char *res = NULL;
++  uint32_t family;
++  size_t len = sizeof(family);
++
++  gcc_assert (argc);
++  if (!argv[0])
++    return NULL;
++
++  /* Are we processing -march, mtune or mcpu?  */
++  arch = strcmp (argv[0], "arch") == 0;
++  if (!arch)
++    tune = strcmp (argv[0], "tune") == 0;
++  if (!arch && !tune)
++    cpu = strcmp (argv[0], "cpu") == 0;
++  if (!arch && !tune && !cpu)
++    return NULL;
++
++  sysctlbyname("hw.cpufamily", &family, &len, NULL, 0);
++
++  switch (family)
++  {
++    case 0x07d34b9f: // Vortex, Tempest
++      res = "apple-a12";
++      break;
++    case 0x573b5eec:
++    case 0x1b588bb3: // Firestorm, Icestorm
++      res = "apple-m1";
++      break;
++    case 0xda33d83d: // Blizzard, Avalanche
++      res = "apple-m2";
++      break;
++    case 0xfa33415e: // Ibiza (M3)
++    case 0x5f4dea93: // Lobos (M3 Pro)
++    case 0x72015832: // Palma (M3 Max)
++      res = "apple-m3";
++      break;
++    default:
++      res = DEFAULT_ARCH;
++  }
++
++  if (res)
++    return concat ("-m", argv[0], "=", res, NULL);
++  else
++    return NULL;
++}
++
++#else
++
+ struct aarch64_arch_extension
+ {
+   const char *ext;
+@@ -58,9 +128,6 @@ struct aarch64_core_data
+ #define INVALID_IMP ((unsigned char) -1)
+ #define INVALID_CORE ((unsigned)-1)
+ #define ALL_VARIANTS ((unsigned)-1)
+-/* Default architecture to use if -mcpu=native did not detect a known CPU.  */
+-#define DEFAULT_ARCH "8A"
+-#define DEFAULT_CPU "generic-armv8-a"
+
+ #define AARCH64_CORE(CORE_NAME, CORE_IDENT, SCHED, ARCH, FLAGS, COSTS, IMP, PART, VARIANT) \
+   { CORE_NAME, #ARCH, IMP, PART, VARIANT, feature_deps::cpu_##CORE_IDENT },
+@@ -504,3 +571,4 @@ not_found:
+     return NULL;
+   }
+ }
++#endif
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_predicates.md
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_predicates.md:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_predicates.md    Sun Jul 19 11:17:43 2026
@@ -0,0 +1,32 @@
+$NetBSD: patch-gcc_config_aarch64_predicates.md,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/predicates.md.orig      2026-06-12 06:09:06.123518280 +0000
++++ gcc/config/aarch64/predicates.md
+@@ -355,9 +355,24 @@
+ (define_predicate "aarch64_prefetch_operand"
+   (match_test "aarch64_address_valid_for_prefetch_p (op, false)"))
+ 
++(define_predicate "aarch64_unscaled_prefetch_operand"
++  (match_test "aarch64_address_valid_for_unscaled_prefetch_p (op, false)"))
++
+ (define_predicate "aarch64_valid_symref"
+   (match_code "const, symbol_ref, label_ref")
+ {
++  if (TARGET_MACHO)
++    {
++      rtx x = op;
++      rtx offset;
++      split_const (x, &x, &offset);
++      if (GET_CODE (x) == CONST)
++      x = XEXP (x, 0);
++      if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SALT_ADDR)
++      x = XVECEXP (x, 0, 0);
++      if (SYMBOL_REF_P (x) && INTVAL (offset) < 0)
++        return false;
++    }
+   return (aarch64_classify_symbolic_expression (op)
+         != SYMBOL_FORCE_TO_MEM);
+ })
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_t-aarch64-darwin
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_t-aarch64-darwin:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_aarch64_t-aarch64-darwin Sun Jul 19 11:17:43 2026
@@ -0,0 +1,33 @@
+$NetBSD: patch-gcc_config_aarch64_t-aarch64-darwin,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/aarch64/t-aarch64-darwin.orig   2026-07-19 09:48:42.156048457 +0000
++++ gcc/config/aarch64/t-aarch64-darwin
+@@ -0,0 +1,25 @@
++# Machine description for AArch64 architecture.
++#  Copyright (C) 2020 Free Software Foundation, Inc.
++#
++#  This file is part of GCC.
++#
++#  GCC is free software; you can redistribute it and/or modify it
++#  under the terms of the GNU General Public License as published by
++#  the Free Software Foundation; either version 3, or (at your option)
++#  any later version.
++#
++#  GCC is distributed in the hope that it will be useful, but
++#  WITHOUT ANY WARRANTY; without even the implied warranty of
++#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++#  General Public License for more details.
++#
++#  You should have received a copy of the GNU General Public License
++#  along with GCC; see the file COPYING3.  If not see
++#  <http://www.gnu.org/licenses/>.
++
++LIB1ASMSRC   = aarch64/lib1funcs.asm
++LIB1ASMFUNCS = _aarch64_sync_cache_range
++
++# TODO - figure out what multilib provisions we should make for
++# a) arm64e
++# b) arm64_32
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-driver.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-driver.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-driver.cc Sun Jul 19 11:17:43 2026
@@ -0,0 +1,100 @@
+$NetBSD: patch-gcc_config_darwin-driver.cc,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/darwin-driver.cc.orig   2026-06-12 06:09:06.164518915 +0000
++++ gcc/config/darwin-driver.cc
+@@ -270,10 +270,13 @@ darwin_driver_init (unsigned int *decode
+   bool seenX86_64 = false;
+   bool seenPPC = false;
+   bool seenPPC64 = false;
++#if !DARWIN_ARM64
++  bool seenArm64 = false;
+   bool seenM32 = false;
+   bool seenM64 = false;
+   bool appendM32 = false;
+   bool appendM64 = false;
++#endif
+   const char *vers_string = NULL;
+   bool seen_version_min = false;
+   bool seen_sysroot_p = false;
+@@ -298,6 +301,12 @@ darwin_driver_init (unsigned int *decode
+           seenPPC = true;
+         else if (!strcmp ((*decoded_options)[i].arg, "ppc64"))
+           seenPPC64 = true;
++        else if (!strcmp ((*decoded_options)[i].arg, "arm64"))
++#if !DARWIN_ARM64
++          seenArm64 = true;
++#else
++          ; /* We accept the option, but don't need to act on it.  */
++#endif
+         else
+           error ("this compiler does not support %qs",
+                  (*decoded_options)[i].arg);
+@@ -311,7 +320,7 @@ darwin_driver_init (unsigned int *decode
+         --i;
+         --*decoded_options_count;
+         break;
+-
++#if !DARWIN_ARM64
+       case OPT_m32:
+         seenM32 = true;
+         break;
+@@ -319,6 +328,7 @@ darwin_driver_init (unsigned int *decode
+       case OPT_m64:
+         seenM64 = true;
+         break;
++#endif
+
+       case OPT_mmacosx_version_min_:
+         seen_version_min = true;
+@@ -378,6 +388,9 @@ darwin_driver_init (unsigned int *decode
+   if (seenPPC || seenPPC64)
+     warning (0, "this compiler does not support PowerPC"
+               " (%<-arch%> option ignored)");
++  else if (seenArm64)
++    warning (0, "this compiler does not support Arm64"
++              " (%<-arch%> option ignored)");
+   if (seenX86)
+     {
+       if (seenX86_64 || seenM64)
+@@ -401,6 +414,9 @@ darwin_driver_init (unsigned int *decode
+   if (seenX86 || seenX86_64)
+     warning (0, "this compiler does not support x86"
+               " (%<-arch%> option ignored)");
++  else if (seenArm64)
++    warning (0, "this compiler does not support Arm64"
++              " (%<-arch%> option ignored)");
+   if (seenPPC)
+     {
+       if (seenPPC64 || seenM64)
+@@ -420,12 +436,20 @@ darwin_driver_init (unsigned int *decode
+       if (! seenM64) /* Add -m64 if the User didn't. */
+       appendM64 = true;
+     }
++#elif DARWIN_ARM64
++  if (seenPPC || seenPPC64)
++    warning (0, "this compiler does not support PowerPC"
++              " (%<-arch%> option ignored)");
++  if (seenX86 || seenX86_64)
++    warning (0, "this compiler does not support x86"
++              " (%<-arch%> option ignored)");
+ #endif
+
+   /* If there is nothing else on the command line, do not add sysroot etc.  */
+   if (*decoded_options_count <= 1)
+     return;
+
++#if !DARWIN_ARM64
+   if (appendM32 || appendM64)
+     {
+       ++*decoded_options_count;
+@@ -435,6 +459,7 @@ darwin_driver_init (unsigned int *decode
+       generate_option (appendM32 ? OPT_m32 : OPT_m64, NULL, 1, CL_DRIVER,
+                      &(*decoded_options)[*decoded_options_count - 1]);
+     }
++#endif
+
+   if (!seen_sysroot_p)
+     {
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-protos.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-protos.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-protos.h  Sun Jul 19 11:17:43 2026
@@ -0,0 +1,31 @@
+$NetBSD: patch-gcc_config_darwin-protos.h,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/darwin-protos.h.orig    2026-06-12 06:09:06.164518915 +0000
++++ gcc/config/darwin-protos.h
+@@ -86,9 +86,12 @@ extern void darwin_asm_lto_end (void);
+ extern void darwin_mark_decl_preserved (const char *);
+
+ extern tree darwin_handle_kext_attribute (tree *, tree, tree, int, bool *);
+-extern tree darwin_handle_weak_import_attribute (tree *node, tree name,
+-                                               tree args, int flags,
+-                                               bool * no_add_attrs);
++extern tree darwin_handle_weak_import_attribute (tree *, tree, tree, int,
++                                               bool *);
++extern tree darwin_handle_availability_attribute (tree *, tree, tree,
++                                                int, bool *);
++extern bool darwin_attribute_takes_identifier_p (const_tree);
++
+ extern void machopic_output_stub (FILE *, const char *, const char *);
+ extern void darwin_globalize_label (FILE *, const char *);
+ extern void darwin_assemble_visibility (tree, int);
+@@ -124,6 +127,7 @@ extern void darwin_enter_string_into_cfs
+ extern void darwin_asm_output_anchor (rtx symbol);
+ extern bool darwin_use_anchors_for_symbol_p (const_rtx symbol);
+ extern bool darwin_kextabi_p (void);
++extern bool darwin_unreachable_traps_p (void);
+ extern void darwin_override_options (void);
+ extern void darwin_patch_builtins (void);
+ extern void darwin_rename_builtins (void);
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-sections.def
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-sections.def:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin-sections.def      Sun Jul 19 11:17:43 2026
@@ -0,0 +1,18 @@
+$NetBSD: patch-gcc_config_darwin-sections.def,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/darwin-sections.def.orig        2026-06-12 06:09:06.164518915 +0000
++++ gcc/config/darwin-sections.def
+@@ -215,3 +215,10 @@ DEF_SECTION (objc2_method_names_section,
+
+ DEF_SECTION (objc2_method_types_section, 0,
+            ".section __TEXT, __objc_methtype, cstring_literals", 1)
++
++/* ASAN sections.  */
++
++DEF_SECTION (asan_string_section, 0, ".section __TEXT, __asan_cstring", 0)
++DEF_SECTION (asan_globals_section, 0, ".section __DATA, __asan_globals", 0)
++DEF_SECTION (asan_liveness_section, 0,
++           ".section __DATA,__asan_liveness,regular,live_support", 0)
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.cc        Sun Jul 19 11:17:43 2026
@@ -0,0 +1,577 @@
+$NetBSD: patch-gcc_config_darwin.cc,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/darwin.cc.orig  2026-06-12 06:09:06.164518915 +0000
++++ gcc/config/darwin.cc
+@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.
+ #include "cfghooks.h"
+ #include "df.h"
+ #include "memmodel.h"
++#include "c-family/c-common.h"  /* enum rid.  */
+ #include "tm_p.h"
+ #include "stringpool.h"
+ #include "attribs.h"
+@@ -49,6 +50,8 @@ along with GCC; see the file COPYING3.
+ #include "optabs.h"
+ #include "flags.h"
+ #include "opts.h"
++#include "asan.h"
++#include "c-family/c-objc.h"    /* for objc_method_decl().  */
+
+ /* Fix and Continue.
+
+@@ -102,6 +105,7 @@ int darwin_running_cxx;
+
+ /* Some code-gen now depends on OS major version numbers (at least).  */
+ int generating_for_darwin_version ;
++unsigned long current_os_version = 0;
+
+ /* For older linkers we need to emit special sections (marked 'coalesced') for
+    for weak or single-definition items.  */
+@@ -131,7 +135,7 @@ struct {
+ section * darwin_sections[NUM_DARWIN_SECTIONS];
+
+ /* While we transition to using in-tests instead of ifdef'd code.  */
+-#if !HAVE_lo_sum
++#if !HAVE_lo_sum || DARWIN_ARM64
+ #define gen_macho_high(m,a,b) (a)
+ #define gen_macho_low(m,a,b,c) (a)
+ #endif
+@@ -1104,6 +1108,7 @@ machopic_legitimize_pic_address (rtx ori
+   return pic_ref;
+ }
+
++#if !DARWIN_ARM64
+ /* Callbacks to output the stub or non-lazy pointers.
+    Each works on the item in *SLOT,if it has been used.
+    DATA is the FILE* for assembly output.
+@@ -1259,6 +1264,7 @@ machopic_finish (FILE *out_file)
+   machopic_indirections->traverse_noresize
+     <FILE *, machopic_output_indirection> (out_file);
+ }
++#endif
+
+ int
+ machopic_operand_p (rtx op)
+@@ -1298,6 +1304,39 @@ darwin_encode_section_info (tree decl, r
+      SYMBOL_FLAG_EXTERNAL.  */
+   default_encode_section_info (decl, rtl, first);
+
++  if (CONSTANT_CLASS_P (decl))
++    {
++      bool is_str = TREE_CODE (decl) == STRING_CST;
++      rtx sym_ref = XEXP (rtl, 0);
++
++      /* Unless this is a string cst or we are in an anchored section we have
++       nothing more to do here.  */
++      if (!is_str && !SYMBOL_REF_HAS_BLOCK_INFO_P (sym_ref))
++      return;
++
++      tree sym_decl = SYMBOL_REF_DECL (sym_ref);
++      const char *name = XSTR (sym_ref, 0);
++      gcc_checking_assert (strncmp ("*lC", name, 3) == 0);
++
++      char *buf;
++      if (is_str)
++      {
++        bool for_asan = (flag_sanitize & SANITIZE_ADDRESS)
++                         && asan_protect_global (CONST_CAST_TREE (decl));
++        /* When we are generating code for sanitized strings, the string
++           internal symbols are made visible in the object.  */
++        buf = xasprintf ("*%c.str.%s", for_asan ? 'l' : 'L', &name[3]);
++      }
++      else
++      /* Lets identify anchored constants with a different prefix, for the
++         sake of inspection only.  */
++      buf = xasprintf ("*LaC%s", &name[3]);
++      if (sym_decl)
++      DECL_NAME (sym_decl) = get_identifier (buf);
++      XSTR (sym_ref, 0) = ggc_strdup (buf);
++      free (buf);
++    }
++
+   if (! VAR_OR_FUNCTION_DECL_P (decl))
+     return;
+
+@@ -1683,6 +1722,17 @@ machopic_select_section (tree decl,
+
+   ro = TREE_READONLY (decl) || TREE_CONSTANT (decl) ;
+
++  /* Trump categorize_decl_for_section () for ASAN stuff - the Darwin
++     categorisations are special.  */
++  if (flag_sanitize & SANITIZE_ADDRESS)
++    {
++      if (TREE_CODE (decl) == STRING_CST
++        && asan_protect_global (CONST_CAST_TREE (decl)))
++      {
++        return darwin_sections[asan_string_section];
++      }
++    }
++
+   switch (categorize_decl_for_section (decl, reloc))
+     {
+     case SECCAT_TEXT:
+@@ -1699,7 +1749,12 @@ machopic_select_section (tree decl,
+       break;
+
+     case SECCAT_RODATA_MERGE_STR_INIT:
+-      base_section = darwin_mergeable_string_section (DECL_INITIAL (decl), align);
++      if ((flag_sanitize & SANITIZE_ADDRESS)
++         && asan_protect_global (CONST_CAST_TREE (decl)))
++      /* or !flag_merge_constants */
++      return darwin_sections[asan_string_section];
++      else
++      return darwin_mergeable_string_section (DECL_INITIAL (decl), align);
+       break;
+
+     case SECCAT_RODATA_MERGE_CONST:
+@@ -2194,6 +2249,122 @@ darwin_handle_kext_attribute (tree *node
+   return NULL_TREE;
+ }
+
++enum version_components { MAJOR, MINOR, TINY };
++
++/* Parse a version number in x.y.z form and validate it as a macOS
++   version.  Ideally, we'd put this in a common place usable by the
++   Darwin backend.  */
++
++static bool
++parse_version (unsigned version_array[3], const char *version_str)
++{
++  size_t version_len;
++  char *end, last = '\0', delimiter = '.', alt_delim = '_';
++
++  if (!version_str)
++    return false;
++
++  /* Handle the odd situation in which we get STRING_CST which contain the
++     starting and ending quotes.  */
++  if (version_str[0] == '"')
++    {
++      version_str++;
++      version_len = strrchr (&version_str[1], '"') - version_str;
++      last = '"';
++   }
++  else
++    version_len = strlen (version_str);
++
++  if (version_len < 1)
++    return false;
++
++  /* Version string must consist of digits and periods only.  */
++  if (strspn (version_str, "0123456789._") != version_len)
++    return false;
++
++  if (!ISDIGIT (version_str[0]) || !ISDIGIT (version_str[version_len - 1]))
++    return false;
++
++  version_array[MAJOR] = strtoul (version_str, &end, 10);
++  if (*end == '_')
++    {
++      delimiter = '_';
++      alt_delim = '.';
++    }
++  version_str = end + ((*end == delimiter) ? 1 : 0);
++  if (version_array[MAJOR] == 100000)
++    return true;
++  if (version_array[MAJOR]  > 99)
++    return false;
++
++  /* Version string must not contain adjacent delimiters.  */
++  if (*version_str == delimiter || *version_str == alt_delim)
++    return false;
++
++  version_array[MINOR] = strtoul (version_str, &end, 10);
++  if (*end == alt_delim)
++    return false;
++  version_str = end + ((*end == delimiter) ? 1 : 0);
++  if (version_array[MINOR]  > 99)
++    return false;
++
++  version_array[TINY] = strtoul (version_str, &end, 10);
++  if (version_array[TINY]  > 99)
++    return false;
++
++  /* Version string must contain no more than three tokens.  */
++  if (*end != last)
++    return false;
++
++  return true;
++}
++
++/* Turn a version expressed as maj.min.tiny into an unsigned long
++   integer representing the value used in macOS availability macros.  */
++
++static unsigned long
++version_from_version_array (unsigned vers[3])
++{
++  unsigned long res = 0;
++  /* There seems to be a special "unknown" value.  */
++  if (vers[0] == 100000)
++    return 999999;
++
++  /* Here, we follow the 'modern' / 'legacy' numbering scheme for versions.  */
++  if (vers[0] > 10 || vers[1] >= 10)
++    res = vers[0] * 10000 + vers[1] * 100 + vers[2];
++  else
++    {
++      res = vers[0] * 100;
++      if (vers[1] > 9)
++      res += 90;
++      else
++      res += vers[1] * 10;
++      if (vers[2] > 9)
++      res += 9;
++      else
++      res += vers[1];
++    }
++  return res;
++}
++
++/* Extract a macOS version from an availability attribute argument.  */
++
++static unsigned long
++os_version_from_avail_value (tree value)
++{
++  unsigned long res = 0;
++  unsigned vers[3] = {0,0,0};
++  if (TREE_CODE (value) == STRING_CST)
++    {
++      if (parse_version (&vers[0], TREE_STRING_POINTER (value)))
++      res = version_from_version_array (&vers[0]);
++    }
++  else
++    gcc_unreachable ();
++  return res;
++}
++
+ /* Handle a "weak_import" attribute; arguments as in
+    struct attribute_spec.handler.  */
+
+@@ -2215,6 +2386,231 @@ darwin_handle_weak_import_attribute (tre
+   return NULL_TREE;
+ }
+
++#define NUM_AV_OSES 13
++const char *availability_os[NUM_AV_OSES]
++  = { "macos", "macosx", "ios", "tvos", "watchos", "driverkit", "swift",
++      "maccatalyst", "macCatalyst", "xros", "visionos", "android", "zos" };
++
++#define NUM_AV_CLAUSES 6
++const char *availability_clause[NUM_AV_CLAUSES]
++  = { "unavailable", "introduced", "deprecated", "obsoleted", "message",
++      "replacement" };
++
++/* Validate and act upon the arguments to an 'availability' attribute.  */
++
++tree
++darwin_handle_availability_attribute (tree *node, tree name, tree args,
++                                    int flags, bool * no_add_attrs)
++{
++  tree decl = *node;
++  *no_add_attrs = true;
++
++  if (!decl || (!TYPE_P (decl) && !DECL_P (decl)))
++    {
++      warning (OPT_Wattributes, "%qE attribute ignored", name);
++      return NULL_TREE;
++    }
++  else if (decl == error_mark_node)
++    return NULL_TREE;
++
++  location_t loc = DECL_SOURCE_LOCATION (decl);
++  if (args == NULL_TREE)
++    {
++      error_at (loc, "%qE attribute requires at least one argument",
++              name);
++      return NULL_TREE;
++    }
++  else if (args == error_mark_node)
++    return NULL_TREE;
++
++  /* The first argument must name a supported OS - although we could choose
++     to ignore any OS we don't recognise.  */
++  gcc_checking_assert (TREE_CODE (args) == TREE_LIST);
++  tree platform = TREE_VALUE (args);
++  if (platform == error_mark_node)
++    return NULL_TREE;
++
++  gcc_checking_assert (TREE_CODE (platform) == IDENTIFIER_NODE);
++  bool platform_ok = false;
++  unsigned plat_num = 0;
++  for (; plat_num < (unsigned) NUM_AV_OSES; plat_num++)
++    if (strcmp (availability_os[plat_num], IDENTIFIER_POINTER (platform)) == 0)
++      {
++      platform_ok = true;
++      break;
++      }
++  if (!platform_ok)
++    {
++      error_at (input_location,
++              "platform %qE is not recognised for the %<availability%> "
++              "attribute", platform);
++      return NULL_TREE;
++    }
++  else if (plat_num > 1) /* We only compile for macos so far.  */
++    return NULL_TREE;
++
++  /* We might be dealing with an object or type.  */
++  tree target_decl = NULL_TREE;
++  tree type = NULL_TREE;
++  bool warn = false;
++  if (DECL_P (*node))
++    {
++      type = TREE_TYPE (decl);
++
++      if (TREE_CODE (decl) == TYPE_DECL
++        || TREE_CODE (decl) == PARM_DECL
++        || VAR_OR_FUNCTION_DECL_P (decl)
++        || TREE_CODE (decl) == FIELD_DECL
++        || TREE_CODE (decl) == CONST_DECL
++        /*|| objc_method_decl (TREE_CODE (decl))*/)
++      target_decl = decl;
++      else
++      warn = true;
++    }
++  else if (TYPE_P (*node))
++    type = target_decl = *node;
++  else
++    warn = true;
++
++  tree what = NULL_TREE;
++  if (warn)
++    {
++      if (type && TYPE_NAME (type))
++      {
++        if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
++          what = TYPE_NAME (*node);
++        else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
++                 && DECL_NAME (TYPE_NAME (type)))
++          what = DECL_NAME (TYPE_NAME (type));
++      }
++      if (what)
++      warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what);
++      else
++      warning (OPT_Wattributes, "%qE attribute ignored", name);
++      return NULL_TREE;
++    }
++
++  /* Now we have to parse the availability clauses.  */
++  tree msg = NULL_TREE;
++  tree replacement = NULL_TREE;
++  bool unavailable = false;
++  unsigned introduced = 1000;
++  unsigned deprecated = current_os_version + 1;
++  unsigned obsoleted = current_os_version + 1;
++  for (tree arg = TREE_CHAIN (args); arg; arg = TREE_CHAIN (arg))
++    {
++      tree clause_name = TREE_VALUE (arg);
++      tree clause_value = TREE_PURPOSE (arg);
++      if (clause_name == error_mark_node
++        || clause_value == error_mark_node)
++      continue;
++      unsigned clause_num = 0;
++      for (; clause_num < (unsigned) NUM_AV_CLAUSES; clause_num++)
++      if (strcmp (availability_clause[clause_num],
++                  IDENTIFIER_POINTER (clause_name)) == 0)
++        break;
++      switch (clause_num)
++      {
++      default:
++        error_at (input_location,
++                  "clause %qE is not recognised for the %<availability%> "
++                  "attribute", clause_name);
++        break;
++      case 0:
++        unavailable = true;
++        break;
++      case 1:
++      case 2:
++      case 3:
++        if (!clause_value)
++          error_at (input_location, "%<%E=%> requires a value", clause_name);
++        else
++          {
++            unsigned version = os_version_from_avail_value (clause_value);
++            if (version == 0)
++              error_at (input_location, "the value %qE provided to %qE is "
++                      "not a valid OS version", clause_value, clause_name);
++            else if (clause_num == 1)
++              introduced = version;
++            else if (clause_num == 2)
++              deprecated = version;
++            else if (clause_num == 3)
++              obsoleted = version;
++          }
++        break;
++      case 4:
++      case 5:
++        if (!clause_value || TREE_CODE (clause_value) != STRING_CST)
++          error_at (input_location, "%<%E=%> requires a string", clause_name);
++        else if (clause_num == 4)
++          msg = clause_value;
++        else
++          replacement = clause_value;
++        break;
++      }
++    }
++  /* Now figure out what to do.  */
++  tree maybe_text = NULL_TREE;
++  if (replacement)
++    maybe_text = tree_cons (NULL_TREE, replacement, NULL_TREE);
++  else if (msg)
++    maybe_text = tree_cons (NULL_TREE, msg, NULL_TREE);
++
++  if (unavailable || current_os_version >= obsoleted)
++    {
++      TREE_UNAVAILABLE (*node) = true;
++      /* We do not handle the availability attribute at diagnostics-time, so
++       if we want the informational messages, then attach them to additional
++       attributes for the deprecation or unavailability.  TODO; maybe we can
++       fabricate the composite here.  */
++      if (maybe_text)
++      {
++        *no_add_attrs = false;
++        tree new_attr = tree_cons (get_identifier ("unavailable"),
++                                   maybe_text, NULL_TREE);
++        /* This is the actual consequence of the evaluation.  */
++        if (TYPE_P (target_decl) && !(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
++          {
++            *node = build_variant_type_copy (*node);
++            TYPE_ATTRIBUTES (*node) = chainon (TYPE_ATTRIBUTES (*node),
++                                               new_attr);
++          }
++        else
++          DECL_ATTRIBUTES (*node) = chainon (DECL_ATTRIBUTES (*node),
++                                             new_attr);
++      }
++    }
++   else if (current_os_version > deprecated)
++    {
++      TREE_DEPRECATED (*node) = true;
++      if (maybe_text)
++      {
++        *no_add_attrs = false;
++        tree new_attr = tree_cons (get_identifier ("deprecated"),
++                                   maybe_text, NULL_TREE);
++        /* This is the actual consequence of the evaluation.  */
++        if (TYPE_P (target_decl) && !(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
++          {
++            *node = build_variant_type_copy (*node);
++            TYPE_ATTRIBUTES (*node) = chainon (TYPE_ATTRIBUTES (*node),
++                                               new_attr);
++          }
++        else
++          DECL_ATTRIBUTES (*node) = chainon (DECL_ATTRIBUTES (*node),
++                                             new_attr);
++      }
++    }
++  else if (current_os_version < introduced)
++    *no_add_attrs = false;
++  return NULL_TREE;
++}
++
++bool
++darwin_attribute_takes_identifier_p (const_tree attr_id)
++{
++  return is_attribute_p ("availability", attr_id);
++}
++
+ /* Emit a label for an FDE, making it global and/or weak if appropriate.
+    The third parameter is nonzero if this is for exception handling.
+    The fourth parameter is nonzero if this is just a placeholder for an
+@@ -2306,6 +2702,8 @@ darwin_emit_except_table_label (FILE *fi
+ rtx
+ darwin_make_eh_symbol_indirect (rtx orig, bool ARG_UNUSED (pubvis))
+ {
++  if (DARWIN_ARM64)
++    return orig;
+   if (DARWIN_PPC == 0 && TARGET_64BIT)
+     return orig;
+
+@@ -3154,7 +3552,12 @@ darwin_file_end (void)
+       fprintf (asm_out_file, "\t.long\t0\n\t.long\t%u\n", flags);
+      }
+
++#if !DARWIN_ARM64
+   machopic_finish (asm_out_file);
++#else
++  gcc_checking_assert (!machopic_indirections);
++#endif
++
+   if (flag_apple_kext)
+     {
+       /* These sections are only used for kernel code.  */
+@@ -3297,11 +3700,16 @@ darwin_use_anchors_for_symbol_p (const_r
+ {
+   if (DARWIN_SECTION_ANCHORS && flag_section_anchors)
+     {
+-      section *sect;
+-      /* If the section contains a zero-sized object it's ineligible.  */
+-      sect = SYMBOL_REF_BLOCK (symbol)->sect;
+-      /* This should have the effect of disabling anchors for vars that follow
+-         any zero-sized one, in a given section.  */
++      tree decl = SYMBOL_REF_DECL (symbol);
++      /* If the symbol would be linker-visible, then it can split at that
++       so we must disallow.  This is more strict than the default impl.
++       TODO: add other cases.  */
++      if (decl && DECL_P (decl)
++        && (TREE_PUBLIC (decl) || !DECL_ARTIFICIAL (decl)))
++      return false;
++
++      /* We mark sections containing unsuitable entries.  */
++      section *sect = SYMBOL_REF_BLOCK (symbol)->sect;
+       if (sect->common.flags & SECTION_NO_ANCHOR)
+       return false;
+
+@@ -3330,6 +3738,13 @@ darwin_kextabi_p (void) {
+   return flag_apple_kext;
+ }
+
++/* True, iff we want to map __builtin_unreachable to a trap.  */
++
++bool
++darwin_unreachable_traps_p (void) {
++  return darwin_unreachable_traps;
++}
++
+ void
+ darwin_override_options (void)
+ {
+@@ -3350,7 +3765,14 @@ darwin_override_options (void)
+       generating_for_darwin_version = 8;
+
+       /* Earlier versions are not specifically accounted, until required.  */
++      unsigned vers[3] = {0,0,0};
++      if (!parse_version (vers, darwin_macosx_version_min))
++      error_at (UNKNOWN_LOCATION, "how did we get a bad OS version? (%s)",
++                darwin_macosx_version_min);
++      current_os_version = version_from_version_array (vers);
+     }
++  else
++    current_os_version = 1058;
+
+   /* Some codegen needs to account for the capabilities of the target
+      linker.  */
+@@ -3592,6 +4014,19 @@ darwin_override_options (void)
+
+   /* The c_dialect...() macros are not available to us here.  */
+   darwin_running_cxx = (strstr (lang_hooks.name, "C++") != 0);
++
++  /* Allow the clang extension to permit const vars used in array sizes.  */
++  if (!OPTION_SET_P (flag_allow_const_var_array_size))
++    flag_allow_const_var_array_size = true;
++
++  /* We need to consume attributes on function definitions from the the SDK
++     headers.  */
++  if (!OPTION_SET_P (flag_allow_ext_attr_placement))
++    flag_allow_ext_attr_placement = true;
++
++  /* We need to consume some C keywords in C++.  */
++  if (!OPTION_SET_P (flag_allow_extra_keywords))
++    flag_allow_extra_keywords = true;
+ }
+
+ #if DARWIN_PPC
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.h Sun Jul 19 11:17:43 2026
@@ -0,0 +1,69 @@
+$NetBSD: patch-gcc_config_darwin.h,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/darwin.h.orig   2026-06-12 06:09:06.165518930 +0000
++++ gcc/config/darwin.h
+@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTI
+
+ #define DARWIN_X86 0
+ #define DARWIN_PPC 0
++#define DARWIN_ARM64 0
+
+ #define OBJECT_FORMAT_MACHO 1
+
+@@ -381,7 +382,8 @@ extern GTY(()) int darwin_ms_struct;
+ */
+
+ #define DARWIN_NOCOMPACT_UNWIND \
+-" %:version-compare(>= 10.6 mmacosx-version-min= -no_compact_unwind) "
++"%{!fuse-ld=lld: \
++    %:version-compare(>= 10.6 mmacosx-version-min= -no_compact_unwind)}"
+
+ /* In Darwin linker specs we can put -lcrt0.o and ld will search the library
+    path for crt0.o or -lcrtx.a and it will search for libcrtx.a.  As for
+@@ -405,7 +407,8 @@ extern GTY(()) int darwin_ms_struct;
+     LINK_PLUGIN_SPEC \
+     "%{flto*:%<fcompare-debug*} \
+      %{flto} %{fno-lto} %{flto=*} \
+-    %l " \
++     %l \
++     %{fuse-ld=*:-fuse-ld=%*} " \
+     DARWIN_PLATFORM_ID \
+     LINK_COMPRESS_DEBUG_SPEC \
+    "%X %{s} %{t} %{Z} %{u*} \
+@@ -988,7 +991,12 @@ extern GTY(()) section * darwin_sections
+   { "apple_kext_compatibility", 0, 0, false, true, false, false,           \
+     darwin_handle_kext_attribute, NULL },                                  \
+   { "weak_import", 0, 0, true, false, false, false,                        \
+-    darwin_handle_weak_import_attribute, NULL }
++    darwin_handle_weak_import_attribute, NULL },                           \
++  { "availability", 0, -1, true, false, false, false,                      \
++    darwin_handle_availability_attribute, NULL }
++
++#undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
++#define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P darwin_attribute_takes_identifier_p
+
+ /* Make local constant labels linker-visible, so that if one follows a
+    weak_global constant, ld64 will be able to separate the atoms.  */
+@@ -1005,6 +1013,8 @@ extern GTY(()) section * darwin_sections
+       sprintf (LABEL, "*%s%ld", "lASAN", (long)(NUM));\
+     else if (strcmp ("LTRAMP", PREFIX) == 0)  \
+       sprintf (LABEL, "*%s%ld", "lTRAMP", (long)(NUM));\
++    else if (strncmp ("LANCHOR", PREFIX, 7) == 0)     \
++      sprintf (LABEL, "*%s%ld", "lANCHOR", (long)(NUM));\
+     else                                              \
+       sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM)); \
+   } while (0)
+@@ -1236,6 +1246,10 @@ void add_framework_path (char *);
+ #define TARGET_N_FORMAT_TYPES 1
+ #define TARGET_FORMAT_TYPES darwin_additional_format_types
+
++/* We want __builtin_unreachable to be expanded as a trap instruction.  */
++#undef TARGET_UNREACHABLE_SHOULD_TRAP
++#define TARGET_UNREACHABLE_SHOULD_TRAP darwin_unreachable_traps_p
++
+ #ifndef USED_FOR_TARGET
+ extern void darwin_driver_init (unsigned int *,struct cl_decoded_option **);
+ #define GCC_DRIVER_HOST_INITIALIZATION \
Index: pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.opt
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.opt:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_config_darwin.opt       Sun Jul 19 11:17:43 2026
@@ -0,0 +1,18 @@
+$NetBSD: patch-gcc_config_darwin.opt,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/config/darwin.opt.orig 2026-06-12 06:09:06.165518930 +0000
++++ gcc/config/darwin.opt
+@@ -91,6 +91,10 @@ mtarget-linker
+ Target RejectNegative Joined Separate Var(darwin_target_linker) Init(LD64_VERSION)
+ -mtarget-linker <version>     Specify that ld64 <version> is the toolchain linker for the current invocation.
+
++munreachable-traps
++Target Var(darwin_unreachable_traps) Init(1)
++When set (the default) this makes __builtin_unreachable render as a trap.
++
+ ; Driver options.
+
+ all_load
Index: pkgsrc/lang/gcc15/patches/patch-gcc_configure
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_configure:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_configure       Sun Jul 19 11:17:43 2026
@@ -0,0 +1,95 @@
+$NetBSD: patch-gcc_configure,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/configure.orig 2026-06-12 06:09:06.318521299 +0000
++++ gcc/configure
+@@ -743,6 +743,8 @@ ORIGINAL_NM_FOR_TARGET
+ gcc_cv_nm
+ ORIGINAL_LD_GOLD_FOR_TARGET
+ ORIGINAL_LD_BFD_FOR_TARGET
++ORIGINAL_CLASSIC_LD_FOR_TARGET
++ORIGINAL_LLD_FOR_TARGET
+ ORIGINAL_LD_FOR_TARGET
+ ORIGINAL_PLUGIN_LD_FOR_TARGET
+ gcc_cv_ld
+@@ -3811,20 +3813,19 @@ gcc_gxx_libcxx_include_dir=
+
+ # Check whether --with-gxx-libcxx-include-dir was given.
+ if test "${with_gxx_libcxx_include_dir+set}" = set; then :
+-  withval=$with_gxx_libcxx_include_dir; case "${withval}" in
+-yes)  as_fn_error $? "bad value ${withval} given for libc++ include directory" "$LINENO" 5 ;;
+-*)    gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir ;;
+-esac
++  withval=$with_gxx_libcxx_include_dir; gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir
+ fi
+
+
+ # --with-gxx-libcxx-include-dir controls the enabling of the -stdlib option.
+ # if --with-gxx-libcxx-include-dir is 'no' we disable the stdlib option.
++# if --with-gxx-libcxx-include-dir is 'yes' we enable the stdlib option and use
++# the default path within the installation.
+ # if --with-gxx-libcxx-include-dir is unset we enable the stdlib option
+-# based on the platform (to be available on platform versions where it is the
++# based on the platform (to be available on platform versions where it is the
+ # default for the system tools). We also use a default path within the compiler
+-# install tree.
+-# Otherwise, we use the path provided and enable the stdlib option.
++# install tree.
++# Otherwise, we use the path provided and enable the stdlib option.
+ # If both --with-sysroot and --with-gxx-libcxx-include-dir are passed, we
+ # check to see if the latter starts with the former and, upon success, compute
+ # gcc_gxx_libcxx_include_dir as relative to the sysroot.
+@@ -3832,16 +3833,20 @@ gcc_gxx_libcxx_include_dir_add_sysroot=0
+ gcc_enable_stdlib_opt=0
+ if test x${gcc_gxx_libcxx_include_dir} != x; then
+   if test x${gcc_gxx_libcxx_include_dir} = xno; then
+-    # set defaults for the dir, but the option is disabled anyway.
++    # set defaults for the dir, but the option is disabled anyway.
++    gcc_gxx_libcxx_include_dir=
++  elif test x${gcc_gxx_libcxx_include_dir} = xyes; then
++    # set defaults for the dir, and enable.
+     gcc_gxx_libcxx_include_dir=
++    gcc_enable_stdlib_opt=1
+   else
+     gcc_enable_stdlib_opt=1
+   fi
+ else
+   case $target in
+     *-darwin1[1-9]* | *-darwin2*)
+-       # Default this on for Darwin versions which default to libcxx,
+-       # and embed the path in the compiler install so that we get a
++       # Default this on for Darwin versions which default to libcxx,
++       # and embed the path in the compiler install so that we get a
+        # self-contained toolchain.
+        gcc_enable_stdlib_opt=1
+        ;;
+@@ -25251,6 +25256,14 @@ fi
+ $as_echo "$gold_non_default" >&6; }
+
+ ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld
++if test x"$ld64_flag" = x"yes"; then
++ORIGINAL_LLD_FOR_TARGET=${gcc_cv_ld}64.lld
++else
++ORIGINAL_LLD_FOR_TARGET=$gcc_cv_lld
++fi
++ORIGINAL_CLASSIC_LD_FOR_TARGET=$gcc_cv_ld-classic
++
++
+
+ case "$ORIGINAL_LD_FOR_TARGET" in
+   ./collect-ld | ./collect-ld$build_exeext) ;;
+@@ -26667,6 +26680,12 @@ else
+       esac
+     fi
+     ;;
++  x86_64-*-darwin* | i?86-*-darwin* | powerpc*-darwin-*)
++    # Darwin has assemblers that support .cfi_ instructions, but that then
++    # triggers emission of compact unwind which has incompatibilities with
++    # current GCC output.
++    gcc_cv_as_cfi_directive=no
++    ;;
+   *-*-*)
+     gcc_cv_as_cfi_directive=yes
+     ;;
Index: pkgsrc/lang/gcc15/patches/patch-gcc_configure.ac
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_configure.ac:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_configure.ac    Sun Jul 19 11:17:43 2026
@@ -0,0 +1,85 @@
+$NetBSD: patch-gcc_configure.ac,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/configure.ac.orig      2026-06-12 06:09:06.318521299 +0000
++++ gcc/configure.ac
+@@ -235,18 +235,17 @@ gcc_gxx_libcxx_include_dir=
+ AC_ARG_WITH(gxx-libcxx-include-dir,
+ [AS_HELP_STRING([--with-gxx-libcxx-include-dir=DIR],
+                 [specifies directory to find libc++ header files])],
+-[case "${withval}" in
+-yes)  AC_MSG_ERROR(bad value ${withval} given for libc++ include directory) ;;
+-*)    gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir ;;
+-esac])
++[gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir])
+
+ # --with-gxx-libcxx-include-dir controls the enabling of the -stdlib option.
+ # if --with-gxx-libcxx-include-dir is 'no' we disable the stdlib option.
++# if --with-gxx-libcxx-include-dir is 'yes' we enable the stdlib option and use
++# the default path within the installation.
+ # if --with-gxx-libcxx-include-dir is unset we enable the stdlib option
+-# based on the platform (to be available on platform versions where it is the
++# based on the platform (to be available on platform versions where it is the
+ # default for the system tools). We also use a default path within the compiler
+-# install tree.
+-# Otherwise, we use the path provided and enable the stdlib option.
++# install tree.
++# Otherwise, we use the path provided and enable the stdlib option.
+ # If both --with-sysroot and --with-gxx-libcxx-include-dir are passed, we
+ # check to see if the latter starts with the former and, upon success, compute
+ # gcc_gxx_libcxx_include_dir as relative to the sysroot.
+@@ -254,16 +253,20 @@ gcc_gxx_libcxx_include_dir_add_sysroot=0
+ gcc_enable_stdlib_opt=0
+ if test x${gcc_gxx_libcxx_include_dir} != x; then
+   if test x${gcc_gxx_libcxx_include_dir} = xno; then
+-    # set defaults for the dir, but the option is disabled anyway.
++    # set defaults for the dir, but the option is disabled anyway.
++    gcc_gxx_libcxx_include_dir=
++  elif test x${gcc_gxx_libcxx_include_dir} = xyes; then
++    # set defaults for the dir, and enable.
+     gcc_gxx_libcxx_include_dir=
++    gcc_enable_stdlib_opt=1
+   else
+     gcc_enable_stdlib_opt=1
+   fi
+ else
+   case $target in
+     *-darwin1[[1-9]]* | *-darwin2*)
+-       # Default this on for Darwin versions which default to libcxx,
+-       # and embed the path in the compiler install so that we get a
++       # Default this on for Darwin versions which default to libcxx,
++       # and embed the path in the compiler install so that we get a
+        # self-contained toolchain.
+        gcc_enable_stdlib_opt=1
+        ;;
+@@ -2853,7 +2856,15 @@ fi
+ AC_MSG_RESULT($gold_non_default)
+
+ ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld
++if test x"$ld64_flag" = x"yes"; then
++ORIGINAL_LLD_FOR_TARGET=${gcc_cv_ld}64.lld
++else
++ORIGINAL_LLD_FOR_TARGET=$gcc_cv_lld
++fi
++ORIGINAL_CLASSIC_LD_FOR_TARGET=$gcc_cv_ld-classic
+ AC_SUBST(ORIGINAL_LD_FOR_TARGET)
++AC_SUBST(ORIGINAL_LLD_FOR_TARGET)
++AC_SUBST(ORIGINAL_CLASSIC_LD_FOR_TARGET)
+ case "$ORIGINAL_LD_FOR_TARGET" in
+   ./collect-ld | ./collect-ld$build_exeext) ;;
+   *) AC_CONFIG_FILES(collect-ld:exec-tool.in, [chmod +x collect-ld]) ;;
+@@ -3427,6 +3438,12 @@ gcc_GAS_CHECK_FEATURE([cfi directives],
+       esac
+     fi
+     ;;
++  x86_64-*-darwin* | i?86-*-darwin* | powerpc*-darwin-*)
++    # Darwin has assemblers that support .cfi_ instructions, but that then
++    # triggers emission of compact unwind which has incompatibilities with
++    # current GCC output.
++    gcc_cv_as_cfi_directive=no
++    ;;
+   *-*-*)
+     gcc_cv_as_cfi_directive=yes
+     ;;
Index: pkgsrc/lang/gcc15/patches/patch-gcc_cp_decl2.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_cp_decl2.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_cp_decl2.cc     Sun Jul 19 11:17:43 2026
@@ -0,0 +1,125 @@
+$NetBSD: patch-gcc_cp_decl2.cc,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/cp/decl2.cc.orig       2026-06-12 06:09:06.350521794 +0000
++++ gcc/cp/decl2.cc
+@@ -4016,9 +4016,8 @@ get_tls_init_fn (tree var)
+   if (!flag_extern_tls_init && DECL_EXTERNAL (var))
+     return NULL_TREE;
+
+-  /* If the variable is internal, or if we can't generate aliases,
+-     call the local init function directly.  */
+-  if (!TREE_PUBLIC (var) || !TARGET_SUPPORTS_ALIASES)
++  /* If the variable is internal call the local init function directly.  */
++  if (!TREE_PUBLIC (var))
+     return get_local_tls_init_fn (DECL_SOURCE_LOCATION (var));
+
+   tree sname = mangle_tls_init_fn (var);
+@@ -4183,6 +4182,25 @@ generate_tls_wrapper (tree fn)
+   expand_or_defer_fn (finish_function (/*inline_p=*/false));
+ }
+
++/* A dummy init function to act as a weak placeholder for a (possibly non-
++   existent) dynamic init.  */
++static void
++generate_tls_dummy_init (tree fn)
++{
++  tree var = DECL_BEFRIENDING_CLASSES (fn);
++  tree init_fn = get_tls_init_fn (var);
++  /* If have no init fn, or it is non-weak, then we do not need to make a
++     dummy.  */
++  if (!init_fn || !lookup_attribute ("weak", DECL_ATTRIBUTES (init_fn)))
++    return;
++  start_preparsed_function (init_fn, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
++  tree body = begin_function_body ();
++  declare_weak (init_fn);
++  finish_return_stmt (NULL_TREE);
++  finish_function_body (body);
++  expand_or_defer_fn (finish_function (/*inline_p=*/false));
++}
++
+ /* Start a global constructor or destructor function.  */
+
+ static tree
+@@ -5239,6 +5257,7 @@ handle_tls_init (void)
+   tree sl = NULL_TREE;
+   int save_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
+   bool saw_nonbase = false;
++  auto_vec<tree> direct_calls;
+   for (; vars; vars = TREE_CHAIN (vars))
+     {
+       tree var = TREE_VALUE (vars);
+@@ -5248,16 +5267,17 @@ handle_tls_init (void)
+       one_static_initialization_or_destruction (/*initp=*/true, var, init,
+                                               false);
+
+-      /* Output init aliases even with -fno-extern-tls-init.  */
+-      if (TARGET_SUPPORTS_ALIASES && TREE_PUBLIC (var))
++      /* Output inits even with -fno-extern-tls-init.
++      We save the list here and output either an alias or a stub function
++      below.  */
++      if (TREE_PUBLIC (var))
+       {
+-          tree single_init_fn = get_tls_init_fn (var);
++        tree single_init_fn = get_tls_init_fn (var);
+         if (single_init_fn == NULL_TREE)
+           continue;
+-        cgraph_node *alias
+-          = cgraph_node::get_create (fn)->create_same_body_alias
+-              (single_init_fn, fn);
+-        gcc_assert (alias != NULL);
++        if (single_init_fn == fn)
++          continue;
++        direct_calls.safe_push (single_init_fn);
+       }
+     }
+   decomp_finalize_var_list (sl, save_stmts_are_full_exprs_p);
+@@ -5266,6 +5286,30 @@ handle_tls_init (void)
+   finish_if_stmt (if_stmt);
+   finish_function_body (body);
+   expand_or_defer_fn (finish_function (/*inline_p=*/false));
++
++  /* For each TLS var that we have an init function, we either emit an alias
++     between that and the tls_init, or a stub function that just calls the
++     tls_init.  */
++  while (!direct_calls.is_empty())
++    {
++      tree single_init_fn = direct_calls.pop ();
++      if (TARGET_SUPPORTS_ALIASES)
++      {
++        cgraph_node *alias
++           = cgraph_node::get_create (fn)->create_same_body_alias
++              (single_init_fn, fn);
++        gcc_assert (alias != NULL);
++      }
++      else
++      {
++        start_preparsed_function (single_init_fn, NULL_TREE, SF_PRE_PARSED);
++        tree body = begin_function_body ();
++        tree r = build_call_expr (fn, 0);
++        finish_expr_stmt (r);
++        finish_function_body (body);
++        expand_or_defer_fn (finish_function (/*inline_p=*/false));
++      }
++    }
+ }
+
+ /* We're at the end of compilation, so generate any mangling aliases that
+@@ -5709,7 +5753,14 @@ c_parse_final_cleanups (void)
+           }
+
+         if (!DECL_INITIAL (decl) && decl_tls_wrapper_p (decl))
+-          generate_tls_wrapper (decl);
++          {
++            generate_tls_wrapper (decl);
++            /* The wrapper might have a weak reference to an init, we provide
++               a dummy function to satisfy that here.  The linker/dynamic
++               loader will override this with the actual init, if one is
++               required.  */
++            generate_tls_dummy_init (decl);
++          }
+
+         if (!DECL_SAVED_TREE (decl))
+           continue;
Index: pkgsrc/lang/gcc15/patches/patch-gcc_cp_lex.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_cp_lex.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_cp_lex.cc       Sun Jul 19 11:17:43 2026
@@ -0,0 +1,17 @@
+$NetBSD: patch-gcc_cp_lex.cc,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/cp/lex.cc.orig 2026-06-12 06:09:06.352521825 +0000
++++ gcc/cp/lex.cc
+@@ -266,6 +266,9 @@ init_reswords (void)
+     {
+       if (c_common_reswords[i].disable & D_CONLY)
+       continue;
++      if (!flag_allow_extra_keywords
++        && c_common_reswords[i].disable & D_EXT_C_IN_CXX)
++      continue;
+       id = get_identifier (c_common_reswords[i].word);
+       C_SET_RID_CODE (id, c_common_reswords[i].rid);
+       ridpointers [(int) c_common_reswords[i].rid] = id;
Index: pkgsrc/lang/gcc15/patches/patch-gcc_cp_parser.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_cp_parser.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_cp_parser.cc    Sun Jul 19 11:17:43 2026
@@ -0,0 +1,275 @@
+$NetBSD: patch-gcc_cp_parser.cc,v 1.1 2026/07/19 11:17:43 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/cp/parser.cc.orig      2026-06-12 06:09:06.361521964 +0000
++++ gcc/cp/parser.cc
+@@ -708,6 +708,91 @@ cp_lexer_handle_early_pragma (cp_lexer *
+ static cp_parser *cp_parser_new (cp_lexer *);
+ static GTY (()) cp_parser *the_parser;
+
++/* Context-sensitive parse-checking for clang-style attributes.  */
++
++enum clang_attr_state {
++  CA_NONE = 0,
++  CA_ATTR,
++  CA_BR1, CA_BR2,
++  CA_LIST,
++  CA_LIST_ARGS,
++  CA_IS_CA,
++  CA_CA_ARGS,
++  CA_LIST_CONT
++};
++
++/* State machine tracking context of attribute lexing.  */
++
++static enum clang_attr_state
++cp_lexer_attribute_state (cp_token& token, enum clang_attr_state attr_state)
++{
++  /* Implement a context-sensitive parser for clang attributes.
++     We detect __attribute__((clang_style_attribute (ARGS))) and lex the
++     args ARGS with the following differences from GNU attributes:
++      (a) number-like values are lexed as strings [this allows lexing XX.YY.ZZ
++         version numbers].
++      (b) we concatenate strings, since clang attributes allow this too.  */
++  switch (attr_state)
++    {
++    case CA_NONE:
++      if (token.type == CPP_KEYWORD
++        && token.keyword == RID_ATTRIBUTE)
++      attr_state = CA_ATTR;
++      break;
++    case CA_ATTR:
++      if (token.type == CPP_OPEN_PAREN)
++      attr_state = CA_BR1;
++      else
++      attr_state = CA_NONE;
++      break;
++    case CA_BR1:
++      if (token.type == CPP_OPEN_PAREN)
++      attr_state = CA_BR2;
++      else
++      attr_state = CA_NONE;
++      break;
++    case CA_BR2:
++      if (token.type == CPP_NAME)
++      {
++        tree identifier = (token.type == CPP_KEYWORD)
++          /* For keywords, use the canonical spelling, not the
++             parsed identifier.  */
++          ? ridpointers[(int) token.keyword]
++          : token.u.value;
++        identifier = canonicalize_attr_name (identifier);
++        if (attribute_clang_form_p (identifier))
++          attr_state = CA_IS_CA;
++        else
++          attr_state = CA_LIST;
++      }
++      else
++      attr_state = CA_NONE;
++      break;
++    case CA_IS_CA:
++    case CA_LIST:
++      if (token.type == CPP_COMMA)
++      attr_state = CA_BR2; /* Back to the list outer.  */
++      else if (token.type == CPP_OPEN_PAREN)
++      attr_state = attr_state == CA_IS_CA ? CA_CA_ARGS
++                                          : CA_LIST_ARGS;
++      else
++      attr_state = CA_NONE;
++      break;
++    case CA_CA_ARGS: /* We will special-case args in this state.  */
++    case CA_LIST_ARGS:
++      if (token.type == CPP_CLOSE_PAREN)
++      attr_state = CA_LIST_CONT;
++      break;
++    case CA_LIST_CONT:
++      if (token.type == CPP_COMMA)
++      attr_state = CA_BR2; /* Back to the list outer.  */
++      else
++      attr_state = CA_NONE;
++      break;
++    }
++  return attr_state;
++}
++
+ /* Create a new main C++ lexer, the lexer that gets tokens from the
+    preprocessor, and also create the main parser.  */
+
+@@ -724,6 +809,8 @@ cp_lexer_new_main (void)
+   c_common_no_more_pch ();
+
+   cp_lexer *lexer = cp_lexer_alloc ();
++  enum clang_attr_state attr_state = CA_NONE;
++
+   /* Put the first token in the buffer.  */
+   cp_token *tok = lexer->buffer->quick_push (token);
+
+@@ -846,8 +933,14 @@ cp_lexer_new_main (void)
+       if (tok->type == CPP_PRAGMA_EOL)
+       cp_lexer_handle_early_pragma (lexer);
+
++      attr_state = cp_lexer_attribute_state (*tok, attr_state);
+       tok = vec_safe_push (lexer->buffer, cp_token ());
+-      cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, tok);
++      unsigned int flags = C_LEX_STRING_NO_JOIN;
++      /* If we are processing clang-style attribute args, lex numbers as
++         potential version strings; NN .. NN.MM .. NN.MM.OO */
++      if (attr_state == CA_CA_ARGS)
++      flags |= C_LEX_NUMBER_AS_STRING;
++      cp_lexer_get_preprocessor_token (flags, tok);
+     }
+
+   XDELETEVEC (raw_data_buf);
+@@ -1078,7 +1171,7 @@ cp_lexer_get_preprocessor_token (unsigne
+ {
+   static int is_extern_c = 0;
+
+-   /* Get a new token from the preprocessor.  */
++   /* Get a new token from the preprocessor. */
+   token->type
+     = c_lex_with_flags (&token->u.value, &token->location, &token->flags,
+                       flags);
+@@ -24000,9 +24093,16 @@ cp_parser_init_declarator (cp_parser* pa
+                     "an %<asm%> specification is not allowed "
+                     "on a function-definition");
+         if (attributes)
+-          error_at (attributes_start_token->location,
+-                    "attributes are not allowed "
+-                    "on a function-definition");
++          {
++            /* When we are allowing attributes in this position, then add
++               them to the prefix ones.  */
++            if (flag_allow_ext_attr_placement)
++              prefix_attributes = chainon (prefix_attributes, attributes);
++            else
++              error_at (attributes_start_token->location,
++                        "attributes are not allowed "
++                        "on a function-definition");
++          }
+         /* This is a function-definition.  */
+         *function_definition_p = true;
+
+@@ -30674,6 +30774,91 @@ cp_parser_gnu_attributes_opt (cp_parser*
+   return attributes;
+ }
+
++/* Parse the arguments list for a clang attribute.   */
++static tree
++cp_parser_clang_attribute (cp_parser *parser, tree/*attr_id*/)
++{
++  /* Each entry can be :
++     identifier
++     identifier=N.MM.Z
++     identifier="string"
++     followed by ',' or ) for the last entry*/
++
++  matching_parens parens;
++  if (!parens.require_open (parser))
++    return NULL;
++
++  bool save_translate_strings_p = parser->translate_strings_p;
++  parser->translate_strings_p = false;
++  tree attr_args = NULL_TREE;
++  cp_token *token;
++  do
++    {
++      tree name = NULL_TREE;
++      tree value = NULL_TREE;
++
++      token = cp_lexer_peek_token (parser->lexer);
++      if (token->type == CPP_NAME)
++      name = token->u.value;
++      else if (token->type == CPP_KEYWORD)
++      name = ridpointers[(int) token->keyword];
++      else if (token->flags & NAMED_OP)
++      name = get_identifier (cpp_type2name (token->type, token->flags));
++      else
++      {
++        /* FIXME: context-sensitive for that attrib.  */
++        error_at (token->location, "expected an attribute keyword");
++        cp_parser_skip_to_closing_parenthesis (parser,
++                                               /*recovering=*/true,
++                                               /*or_comma=*/false,
++                                               /*consume_paren=*/false);
++        attr_args = error_mark_node;
++        break;
++      }
++      cp_lexer_consume_token (parser->lexer);
++
++      if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
++      {
++        cp_lexer_consume_token (parser->lexer); /* eat the '=' */
++        if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
++            && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
++          {
++            token = cp_lexer_peek_token (parser->lexer);
++            if (token->type == CPP_STRING)
++              value = cp_parser_string_literal (parser, /*translate=*/false,
++                                          /*wide_ok=*/false);
++            else
++              {
++                value = token->u.value;
++                cp_lexer_consume_token (parser->lexer);
++              }
++          }
++        /* else value is missing.  */
++      }
++      else if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
++             && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
++      {
++        error_at (token->location, "expected %<,%>, %<=%> or %<)%>");
++        cp_parser_skip_to_closing_parenthesis (parser,
++                                               /*recovering=*/true,
++                                               /*or_comma=*/false,
++                                               /*consume_paren=*/false);
++        attr_args = error_mark_node;
++        break;
++      }
++    if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
++      cp_lexer_consume_token (parser->lexer);
++    tree t = tree_cons (value, name, NULL_TREE);
++    attr_args = chainon (attr_args, t);
++  } while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN));
++
++  parser->translate_strings_p = save_translate_strings_p;
++  if (!parens.require_close (parser))
++    return error_mark_node;
++
++  return attr_args;
++}
++
+ /* Parse a GNU attribute-list.
+
+    attribute-list:
+@@ -30733,9 +30918,12 @@ cp_parser_gnu_attribute_list (cp_parser*
+
+         /* Peek at the next token.  */
+         token = cp_lexer_peek_token (parser->lexer);
+-        /* If it's an `(', then parse the attribute arguments.  */
+-        if (token->type == CPP_OPEN_PAREN)
++        if (token->type == CPP_OPEN_PAREN
++            && attribute_clang_form_p (identifier))
++          arguments = cp_parser_clang_attribute (parser, identifier);
++        else if (token->type == CPP_OPEN_PAREN)
+           {
++            /* If it's an `(', then parse the attribute arguments.  */
+             vec<tree, va_gc> *vec;
+             int attr_flag = (attribute_takes_identifier_p (identifier)
+                              ? id_attr : normal_attr);
+@@ -30752,12 +30940,12 @@ cp_parser_gnu_attribute_list (cp_parser*
+                 arguments = build_tree_list_vec (vec);
+                 release_tree_vector (vec);
+               }
+-            /* Save the arguments away.  */
+-            TREE_VALUE (attribute) = arguments;
+           }
+
+         if (arguments != error_mark_node)
+           {
++            /* Save the arguments away.  */
++            TREE_VALUE (attribute) = arguments;
+             /* Add this attribute to the list.  */
+             TREE_CHAIN (attribute) = attribute_list;
+             attribute_list = attribute;
Index: pkgsrc/lang/gcc15/patches/patch-gcc_cumulative-args.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_cumulative-args.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_cumulative-args.h       Sun Jul 19 11:17:44 2026
@@ -0,0 +1,28 @@
+$NetBSD: patch-gcc_cumulative-args.h,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/cumulative-args.h.orig 2026-07-19 09:48:42.226913605 +0000
++++ gcc/cumulative-args.h
+@@ -0,0 +1,20 @@
++#ifndef GCC_CUMULATIVE_ARGS_H
++#define GCC_CUMULATIVE_ARGS_H
++
++#if CHECKING_P
++
++struct cumulative_args_t { void *magic; void *p; };
++
++#else /* !CHECKING_P */
++
++/* When using a GCC build compiler, we could use
++   __attribute__((transparent_union)) to get cumulative_args_t function
++   arguments passed like scalars where the ABI would mandate a less
++   efficient way of argument passing otherwise.  However, that would come
++   at the cost of less type-safe !CHECKING_P compilation.  */
++
++union cumulative_args_t { void *p; };
++
++#endif /* !CHECKING_P */
++
++#endif /* GCC_CUMULATIVE_ARGS_H */
Index: pkgsrc/lang/gcc15/patches/patch-gcc_doc_invoke.texi
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_doc_invoke.texi:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_doc_invoke.texi Sun Jul 19 11:17:44 2026
@@ -0,0 +1,73 @@
+$NetBSD: patch-gcc_doc_invoke.texi,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/doc/invoke.texi.orig   2026-06-12 06:09:06.426522970 +0000
++++ gcc/doc/invoke.texi
+@@ -757,7 +757,7 @@ Objective-C and Objective-C++ Dialects}.
+ -freg-struct-return  -fshort-enums  -fshort-wchar
+ -fverbose-asm  -fpack-struct[=@var{n}]
+ -fleading-underscore  -ftls-model=@var{model}
+--fstack-reuse=@var{reuse_level}
++-fstack-reuse=@var{reuse_level} -fstack-use-cumulative-args
+ -ftrampolines -ftrampoline-impl=@r{[}stack@r{|}heap@r{]}
+ -ftrapv  -fwrapv
+ -fvisibility=@r{[}default@r{|}internal@r{|}hidden@r{|}protected@r{]}
+@@ -986,7 +986,7 @@ Objective-C and Objective-C++ Dialects}.
+ -twolevel_namespace  -umbrella  -undefined
+ -unexported_symbols_list  -weak_reference_mismatches
+ -whatsloaded  -F  -gused  -gfull  -mmacosx-version-min=@var{version}
+--mkernel  -mone-byte-bool}
++-mkernel  -mone-byte-bool -munreachable-traps}
+
+ @emph{DEC Alpha Options} (@ref{DEC Alpha Options})
+ @gccoptlist{-mno-fp-regs  -msoft-float
+@@ -19680,6 +19680,17 @@ the behavior of older compilers in which
+ not reused, the aggressive stack reuse can lead to runtime errors. This
+ option is used to control the temporary stack reuse optimization.
+
++@opindex fstack_use_cumulative_args
++@item -fstack-use-cumulative-args
++This option instructs the compiler to use the
++@code{cumulative_args_t}-based stack layout target hooks,
++@code{TARGET_FUNCTION_ARG_BOUNDARY_CA} and
++@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA}. If a given target does
++not define these hooks, the default behaviour is to fallback to using
++the standard non-@code{_CA} variants instead. Certain targets (such as
++AArch64 Darwin) require using the more advanced @code{_CA}-based
++hooks: For these targets this option should be enabled by default.
++
+ @opindex ftrapv
+ @item -ftrapv
+ This option generates traps for signed overflow on addition, subtraction,
+@@ -22026,7 +22037,7 @@ performance of the code.  Permissible va
+ @samp{cortex-a520}, @samp{cortex-a520ae}, @samp{cortex-a710}, @samp{cortex-a715},
+ @samp{cortex-a720}, @samp{cortex-a720ae}, @samp{ampere1}, @samp{ampere1a},
+ @samp{ampere1b}, @samp{cobalt-100}, @samp{apple-m1}, @samp{apple-m2},
+-@samp{apple-m3} and @samp{native}.
++@samp{apple-m3}, @samp{apple-m4} and @samp{native}.
+
+ The values @samp{cortex-a57.cortex-a53}, @samp{cortex-a72.cortex-a53},
+ @samp{cortex-a73.cortex-a35}, @samp{cortex-a73.cortex-a53},
+@@ -24107,7 +24118,7 @@ Permissible names are: @samp{arm7tdmi},
+ @samp{neoverse-n1}, @samp{neoverse-n2}, @samp{neoverse-v1}, @samp{xscale},
+ @samp{iwmmxt}, @samp{iwmmxt2}, @samp{ep9312}, @samp{fa526}, @samp{fa626},
+ @samp{fa606te}, @samp{fa626te}, @samp{fmp626}, @samp{fa726te}, @samp{star-mc1},
+-@samp{xgene1}.
++@samp{xgene1}, @samp{apple-m1}, @samp{apple-m2}, @samp{apple-m3}.
+
+ Additionally, this option can specify that GCC should tune the performance
+ of the code for a big.LITTLE system.  Permissible names are:
+@@ -26171,6 +26182,11 @@ without that switch.  Using this switch
+ other modules in a program, including system libraries.  Use this
+ switch to conform to a non-default data model.
+
++@opindex munreachable-traps
++@item -munreachable-traps
++Causes @code{__builtin_unreachable} to be rendered as a trap.  This is the
++default for all Darwin architectures.
++
+ @opindex mfix-and-continue
+ @opindex ffix-and-continue
+ @opindex findirect-data
Index: pkgsrc/lang/gcc15/patches/patch-gcc_doc_tm.texi
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_doc_tm.texi:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_doc_tm.texi     Sun Jul 19 11:17:44 2026
@@ -0,0 +1,64 @@
+$NetBSD: patch-gcc_doc_tm.texi,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/doc/tm.texi.orig       2026-06-12 06:09:06.433523079 +0000
++++ gcc/doc/tm.texi
+@@ -1074,6 +1074,10 @@ also define the hook to @code{default_pr
+ if you would like to apply the same rules given by @code{PROMOTE_MODE}.
+ @end deftypefn
+
++@deftypefn {Target Hook} machine_mode TARGET_PROMOTE_FUNCTION_MODE_CA (cumulative_args_t, @var{function_arg_info}, @var{const_tree}, int *@var{}, @var{int})
++Like @code{promote_function_mode}, but takes a cumulative_args pointer   and a current arg to supply the input.
++@end deftypefn
++
+ @defmac PARM_BOUNDARY
+ Normal alignment required for function parameters on the stack, in
+ bits.  All stack parameters receive at least this much alignment
+@@ -4471,6 +4475,16 @@ with the specified mode and type.  The d
+ @code{PARM_BOUNDARY} for all arguments.
+ @end deftypefn
+
++@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_BOUNDARY_CA (machine_mode @var{mode}, const_tree @var{type}, cumulative_args_t @var{ca})
++This is the @code{cumulative_args_t}-based version of
++@code{TARGET_FUNCTION_ARG_BOUNDARY}. Define this hook if you need more
++fine-grained control over argument alignment, e.g. depending on whether
++it is a named argument or not, or any other criteria that you choose to
++place in the @var{ca} structure.
++
++The default hook will call @code{TARGET_FUNCTION_ARG_BOUNDARY}.
++@end deftypefn
++
+ @deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY (machine_mode @var{mode}, const_tree @var{type})
+ Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY},
+ which is the default value for this hook.  You can define this hook to
+@@ -4478,6 +4492,16 @@ return a different value if an argument
+ value.
+ @end deftypefn
+
++@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA (machine_mode @var{mode}, const_tree @var{type}, cumulative_args_t @var{ca})
++This is the @code{cumulative_args_t}-based version of
++@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. Define this hook if you need more
++fine-grained control over argument size rounding, e.g. depending on whether
++it is a named argument or not, or any other criteria that you choose to
++place in the @var{ca} structure.
++
++The default hook will call @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}.
++@end deftypefn
++
+ @defmac FUNCTION_ARG_REGNO_P (@var{regno})
+ A C expression that is nonzero if @var{regno} is the number of a hard
+ register in which function arguments are sometimes passed.  This does
+@@ -12855,6 +12879,11 @@ This target hook can be used to generate
+ If selftests are enabled, run any selftests for this target.
+ @end deftypefn
+
++@deftypefn {Target Hook} bool TARGET_UNREACHABLE_SHOULD_TRAP (void)
++This hook should return @code{true} if the target wants   @code{__builtin_unreachable} to expand to a trap or @code{abort ()}.
++  The default value is false.
++@end deftypefn
++
+ @deftypefn {Target Hook} bool TARGET_MEMTAG_CAN_TAG_ADDRESSES ()
+ True if the backend architecture naturally supports ignoring some region
+ of pointers.  This feature means that @option{-fsanitize=hwaddress} can
Index: pkgsrc/lang/gcc15/patches/patch-gcc_doc_tm.texi.in
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_doc_tm.texi.in:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_doc_tm.texi.in  Sun Jul 19 11:17:44 2026
@@ -0,0 +1,38 @@
+$NetBSD: patch-gcc_doc_tm.texi.in,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/doc/tm.texi.in.orig    2026-06-12 06:09:06.435523110 +0000
++++ gcc/doc/tm.texi.in
+@@ -951,6 +951,8 @@ applied.
+
+ @hook TARGET_PROMOTE_FUNCTION_MODE
+
++@hook TARGET_PROMOTE_FUNCTION_MODE_CA
++
+ @defmac PARM_BOUNDARY
+ Normal alignment required for function parameters on the stack, in
+ bits.  All stack parameters receive at least this much alignment
+@@ -3435,8 +3437,12 @@ required.
+
+ @hook TARGET_FUNCTION_ARG_BOUNDARY
+
++@hook TARGET_FUNCTION_ARG_BOUNDARY_CA
++
+ @hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY
+
++@hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA
++
+ @defmac FUNCTION_ARG_REGNO_P (@var{regno})
+ A C expression that is nonzero if @var{regno} is the number of a hard
+ register in which function arguments are sometimes passed.  This does
+@@ -8122,6 +8128,8 @@ maintainer is familiar with.
+
+ @hook TARGET_RUN_TARGET_SELFTESTS
+
++@hook TARGET_UNREACHABLE_SHOULD_TRAP
++
+ @hook TARGET_MEMTAG_CAN_TAG_ADDRESSES
+
+ @hook TARGET_MEMTAG_TAG_SIZE
Index: pkgsrc/lang/gcc15/patches/patch-gcc_exec-tool.in
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_exec-tool.in:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_exec-tool.in    Sun Jul 19 11:17:44 2026
@@ -0,0 +1,76 @@
+$NetBSD: patch-gcc_exec-tool.in,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/exec-tool.in.orig      2026-06-12 06:09:06.444523249 +0000
++++ gcc/exec-tool.in
+@@ -23,6 +23,8 @@ ORIGINAL_AS_FOR_TARGET="@ORIGINAL_AS_FOR
+ ORIGINAL_LD_FOR_TARGET="@ORIGINAL_LD_FOR_TARGET@"
+ ORIGINAL_LD_BFD_FOR_TARGET="@ORIGINAL_LD_BFD_FOR_TARGET@"
+ ORIGINAL_LD_GOLD_FOR_TARGET="@ORIGINAL_LD_GOLD_FOR_TARGET@"
++ORIGINAL_LLD_FOR_TARGET="@ORIGINAL_LLD_FOR_TARGET@"
++ORIGINAL_CLASSIC_LD_FOR_TARGET="@ORIGINAL_CLASSIC_LD_FOR_TARGET@"
+ ORIGINAL_PLUGIN_LD_FOR_TARGET="@ORIGINAL_PLUGIN_LD_FOR_TARGET@"
+ ORIGINAL_NM_FOR_TARGET="@ORIGINAL_NM_FOR_TARGET@"
+ ORIGINAL_DSYMUTIL_FOR_TARGET="@ORIGINAL_DSYMUTIL_FOR_TARGET@"
+@@ -39,24 +41,41 @@ case "$invoked" in
+     dir=gas
+     ;;
+   collect-ld)
+-    # Check -fuse-ld=bfd and -fuse-ld=gold
+-    case " $* " in
+-      *\ -fuse-ld=bfd\ *)
+-      original=$ORIGINAL_LD_BFD_FOR_TARGET
+-      ;;
+-      *\ -fuse-ld=gold\ *)
+-      original=$ORIGINAL_LD_GOLD_FOR_TARGET
+-      ;;
+-      *)
+-      # when using a linker plugin, gcc will always pass '-plugin' as the
+-      # first or second option to the linker.
+-      if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then
+-        original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
+-      else
+-        original=$ORIGINAL_LD_FOR_TARGET
+-      fi
+-      ;;
+-    esac
++    # when using a linker plugin, gcc will always pass '-plugin' as the
++    # first or second option to the linker.
++    if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then
++      original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
++    else
++      original=$ORIGINAL_LD_FOR_TARGET
++    fi
++    # Check -fuse-ld=bfd, -fuse-ld=gold and -fuse-ld=classic
++    # Remove -fuse-ld=classic from the command line
++    for arg do
++        # temporarily, remove the arg.
++        shift
++        case $arg in
++          -fuse-ld=bfd)
++            original=$ORIGINAL_LD_BFD_FOR_TARGET
++            ;;
++          -fuse-ld=gold)
++            original=$ORIGINAL_LD_GOLD_FOR_TARGET
++            ;;
++          -fuse-ld=lld)
++            original=$ORIGINAL_LLD_FOR_TARGET
++            # We want to remove this from the command line; by the slightly
++            # obtuse mechanism of not putting it back.
++            continue
++            ;;
++          -fuse-ld=classic)
++            original=$ORIGINAL_CLASSIC_LD_FOR_TARGET
++            # As for lld.
++            continue
++            ;;
++          *) ;;
++        esac
++        # if we want to keep the arg, put it back.
++        set -- "$@" "$arg"
++    done
+     prog=ld-new$exeext
+     if test "$original" = ../gold/ld-new$exeext; then
+       dir=gold
Index: pkgsrc/lang/gcc15/patches/patch-gcc_explow.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_explow.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_explow.cc       Sun Jul 19 11:17:44 2026
@@ -0,0 +1,32 @@
+$NetBSD: patch-gcc_explow.cc,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/explow.cc.orig 2026-06-12 06:09:06.444523249 +0000
++++ gcc/explow.cc
+@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.
+ #include "langhooks.h"
+ #include "except.h"
+ #include "dojump.h"
++#include "calls.h"
+ #include "explow.h"
+ #include "expr.h"
+ #include "stringpool.h"
+@@ -864,6 +865,16 @@ promote_function_mode (const_tree type,
+       return mode;
+     }
+ }
++
++machine_mode
++promote_function_mode (cumulative_args_t args_so_far, function_arg_info arg,
++                     const_tree funtype, int *punsignedp , int for_return)
++{
++  return targetm.calls.promote_function_mode_ca (args_so_far, arg, funtype,
++                                               punsignedp, for_return);
++//  return promote_function_mode (arg.type, arg.mode, punsignedp, funtype, for_return);
++}
++
+ /* Return the mode to use to store a scalar of TYPE and MODE.
+    PUNSIGNEDP points to the signedness of the type and may be adjusted
+    to show what signedness to use on extension operations.  */
Index: pkgsrc/lang/gcc15/patches/patch-gcc_explow.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_explow.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_explow.h        Sun Jul 19 11:17:44 2026
@@ -0,0 +1,32 @@
+$NetBSD: patch-gcc_explow.h,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/explow.h.orig  2026-06-12 06:09:06.444523249 +0000
++++ gcc/explow.h
+@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.
+ #ifndef GCC_EXPLOW_H
+ #define GCC_EXPLOW_H
+
++#include "calls.h" /* for cummulative args stuff.  */
++
+ /* Return a memory reference like MEMREF, but which is known to have a
+    valid address.  */
+ extern rtx validize_mem (rtx);
+@@ -51,8 +53,13 @@ extern rtx force_not_mem (rtx);
+
+ /* Return mode and signedness to use when an argument or result in the
+    given mode is promoted.  */
+-extern machine_mode promote_function_mode (const_tree, machine_mode, int *,
+-                                              const_tree, int);
++machine_mode promote_function_mode (const_tree, machine_mode, int *,
++                                  const_tree, int);
++
++/* Return mode and signedness to use when an argument or result in the
++   given mode is promoted.  */
++machine_mode promote_function_mode (cumulative_args_t, function_arg_info,
++                                  const_tree, int *, int);
+
+ /* Return mode and signedness to use when an object in the given mode
+    is promoted.  */
Index: pkgsrc/lang/gcc15/patches/patch-gcc_function.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_function.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_function.cc     Sun Jul 19 11:17:44 2026
@@ -0,0 +1,109 @@
+$NetBSD: patch-gcc_function.cc,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/function.cc.orig       2026-06-12 06:09:06.484523868 +0000
++++ gcc/function.cc
+@@ -58,8 +58,8 @@ along with GCC; see the file COPYING3.
+ #include "varasm.h"
+ #include "except.h"
+ #include "dojump.h"
+-#include "explow.h"
+ #include "calls.h"
++#include "explow.h"
+ #include "expr.h"
+ #include "optabs-tree.h"
+ #include "output.h"
+@@ -2450,7 +2450,10 @@ assign_parm_find_data_types (struct assi
+   else if (DECL_CHAIN (parm))
+     data->arg.named = 1;  /* Not the last non-variadic parm. */
+   else if (targetm.calls.strict_argument_naming (all->args_so_far))
+-    data->arg.named = 1;  /* Only variadic ones are unnamed.  */
++    {
++      data->arg.named = 1;  /* Only variadic ones are unnamed.  */
++      data->arg.last_named = 1;
++    }
+   else
+     data->arg.named = 0;  /* Treat as variadic.  */
+
+@@ -2492,9 +2495,12 @@ assign_parm_find_data_types (struct assi
+
+   /* Find mode as it is passed by the ABI.  */
+   unsignedp = TYPE_UNSIGNED (data->arg.type);
+-  data->arg.mode
+-    = promote_function_mode (data->arg.type, data->arg.mode, &unsignedp,
+-                           TREE_TYPE (current_function_decl), 0);
++//  data->arg.mode
++//    = promote_function_mode (data->arg.type, data->arg.mode, &unsignedp,
++//                         TREE_TYPE (current_function_decl), 0);
++  data->arg.mode = promote_function_mode (all->args_so_far, data->arg,
++                                        TREE_TYPE (current_function_decl),
++                                        &unsignedp, 0);
+ }
+
+ /* A subroutine of assign_parms.  Invoke setup_incoming_varargs.  */
+@@ -2507,6 +2513,7 @@ assign_parms_setup_varargs (struct assig
+
+   function_arg_info last_named_arg = data->arg;
+   last_named_arg.named = true;
++  last_named_arg.last_named = true;
+   targetm.calls.setup_incoming_varargs (all->args_so_far, last_named_arg,
+                                       &varargs_pretend_bytes, no_rtl);
+
+@@ -2615,7 +2622,9 @@ assign_parm_find_entry_rtl (struct assig
+
+   locate_and_pad_parm (data->arg.mode, data->arg.type, in_regs,
+                      all->reg_parm_stack_space,
+-                     entry_parm ? data->partial : 0, current_function_decl,
++                     entry_parm ? data->partial : 0,
++                     all->args_so_far,
++                     current_function_decl,
+                      &all->stack_args_size, &data->locate);
+
+   /* Update parm_stack_boundary if this parameter is passed in the
+@@ -3924,7 +3933,8 @@ gimplify_parameters (gimple_seq *cleanup
+       if (data.arg.pass_by_reference)
+       {
+         tree type = TREE_TYPE (data.arg.type);
+-        function_arg_info orig_arg (type, data.arg.named);
++        function_arg_info orig_arg (type, data.arg.named,
++                                    data.arg.last_named);
+         if (reference_callee_copied (&all.args_so_far_v, orig_arg))
+           {
+             tree local, t;
+@@ -4027,6 +4037,7 @@ gimplify_parameters (gimple_seq *cleanup
+ void
+ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
+                    int reg_parm_stack_space, int partial,
++                   cumulative_args_t ca,
+                    tree fndecl ATTRIBUTE_UNUSED,
+                    struct args_size *initial_offset_ptr,
+                    struct locate_and_pad_arg_data *locate)
+@@ -4064,9 +4075,23 @@ locate_and_pad_parm (machine_mode passed
+             ? arg_size_in_bytes (type)
+             : size_int (GET_MODE_SIZE (passed_mode)));
+   where_pad = targetm.calls.function_arg_padding (passed_mode, type);
+-  boundary = targetm.calls.function_arg_boundary (passed_mode, type);
+-  round_boundary = targetm.calls.function_arg_round_boundary (passed_mode,
+-                                                            type);
++
++  if (flag_stack_use_cumulative_args)
++    {
++      boundary = targetm.calls.function_arg_boundary_ca (passed_mode,
++                                                       type,
++                                                       ca);
++      round_boundary = targetm.calls.function_arg_round_boundary_ca
++      (passed_mode, type, ca);
++    }
++  else
++    {
++      boundary = targetm.calls.function_arg_boundary (passed_mode,
++                                                    type);
++      round_boundary = targetm.calls.function_arg_round_boundary
++      (passed_mode, type);
++    }
++
+   locate->where_pad = where_pad;
+
+   /* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT.  */
Index: pkgsrc/lang/gcc15/patches/patch-gcc_function.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_function.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_function.h      Sun Jul 19 11:17:44 2026
@@ -0,0 +1,23 @@
+$NetBSD: patch-gcc_function.h,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/function.h.orig        2026-06-12 06:09:06.484523868 +0000
++++ gcc/function.h
+@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.
+ #ifndef GCC_FUNCTION_H
+ #define GCC_FUNCTION_H
+
++#include "cumulative-args.h"
+
+ /* Stack of pending (incomplete) sequences saved by `start_sequence'.
+    Each element describes one pending sequence.
+@@ -686,6 +687,7 @@ extern bool aggregate_value_p (const_tre
+ extern bool use_register_for_decl (const_tree);
+ extern gimple_seq gimplify_parameters (gimple_seq *);
+ extern void locate_and_pad_parm (machine_mode, tree, int, int, int,
++                               cumulative_args_t,
+                                tree, struct args_size *,
+                                struct locate_and_pad_arg_data *);
+ extern void generate_setjmp_warnings (void);
Index: pkgsrc/lang/gcc15/patches/patch-gcc_ginclude_stddef.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_ginclude_stddef.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_ginclude_stddef.h       Sun Jul 19 11:17:44 2026
@@ -0,0 +1,19 @@
+$NetBSD: patch-gcc_ginclude_stddef.h,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/ginclude/stddef.h.orig 2026-06-12 06:09:06.509664884 +0000
++++ gcc/ginclude/stddef.h
+@@ -443,9 +443,8 @@ typedef struct {
+   /* _Float128 is defined as a basic type, so max_align_t must be
+      sufficiently aligned for it.  This code must work in C++, so we
+      use __float128 here; that is only available on some
+-     architectures, but only on i386 is extra alignment needed for
+-     __float128.  */
+-#ifdef __i386__
++     architectures.  */
++#if defined(__i386__) || (__APPLE__ && __aarch64__)
+   __float128 __max_align_f128 __attribute__((__aligned__(__alignof(__float128))));
+ #endif
+ } max_align_t;
Index: pkgsrc/lang/gcc15/patches/patch-gcc_opts.cc
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_opts.cc:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_opts.cc Sun Jul 19 11:17:44 2026
@@ -0,0 +1,15 @@
+$NetBSD: patch-gcc_opts.cc,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/opts.cc.orig   2026-06-12 06:09:06.638526252 +0000
++++ gcc/opts.cc
+@@ -3347,6 +3347,7 @@ common_handle_option (struct gcc_options
+       break;
+
+     case OPT_fuse_ld_bfd:
++    case OPT_fuse_ld_classic:
+     case OPT_fuse_ld_gold:
+     case OPT_fuse_ld_lld:
+     case OPT_fuse_ld_mold:
Index: pkgsrc/lang/gcc15/patches/patch-gcc_target.def
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_target.def:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_target.def      Sun Jul 19 11:17:44 2026
@@ -0,0 +1,75 @@
+$NetBSD: patch-gcc_target.def,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/target.def.orig        2026-06-12 06:09:06.827529177 +0000
++++ gcc/target.def
+@@ -4830,6 +4830,13 @@ if you would like to apply the same rule
+  default_promote_function_mode)
+
+ DEFHOOK
++(promote_function_mode_ca,
++ "Like @code{promote_function_mode}, but takes a cumulative_args pointer \
++  and a current arg to supply the input.",
++ machine_mode, (cumulative_args_t, function_arg_info, const_tree, int *, int),
++ default_promote_function_mode_ca)
++
++DEFHOOK
+ (promote_prototypes,
+  "This target hook returns @code{true} if an argument declared in a\n\
+ prototype as an integral type smaller than @code{int} should actually be\n\
+@@ -5292,6 +5299,18 @@ with the specified mode and type.  The d
+  default_function_arg_boundary)
+
+ DEFHOOK
++(function_arg_boundary_ca,
++ "This is the @code{cumulative_args_t}-based version of\n\
++@code{TARGET_FUNCTION_ARG_BOUNDARY}. Define this hook if you need more\n\
++fine-grained control over argument alignment, e.g. depending on whether\n\
++it is a named argument or not, or any other criteria that you choose to\n\
++place in the @var{ca} structure.\n\
++\n\
++The default hook will call @code{TARGET_FUNCTION_ARG_BOUNDARY}.",
++ unsigned int, (machine_mode mode, const_tree type, cumulative_args_t ca),
++ default_function_arg_boundary_ca)
++
++DEFHOOK
+ (function_arg_round_boundary,
+  "Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY},\n\
+ which is the default value for this hook.  You can define this hook to\n\
+@@ -5300,6 +5319,18 @@ value.",
+  unsigned int, (machine_mode mode, const_tree type),
+  default_function_arg_round_boundary)
+
++DEFHOOK
++(function_arg_round_boundary_ca,
++ "This is the @code{cumulative_args_t}-based version of\n\
++@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. Define this hook if you need more\n\
++fine-grained control over argument size rounding, e.g. depending on whether\n\
++it is a named argument or not, or any other criteria that you choose to\n\
++place in the @var{ca} structure.\n\
++\n\
++The default hook will call @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}.",
++ unsigned int, (machine_mode mode, const_tree type, cumulative_args_t ca),
++ default_function_arg_round_boundary_ca)
++
+ /* Return the diagnostic message string if function without a prototype
+    is not allowed for this 'val' argument; NULL otherwise. */
+ DEFHOOK
+@@ -7575,6 +7606,16 @@ DEFHOOKPOD
+ The default value is NULL.",
+  const char *, NULL)
+
++/* This value represents whether __builtin_unreachable should be expanded
++   as a trap instruction (or an abort() if the trap is not available).  */
++DEFHOOK
++(unreachable_should_trap,
++ "This hook should return @code{true} if the target wants \
++  @code{__builtin_unreachable} to expand to a trap or @code{abort ()}.\n\
++  The default value is false.",
++ bool, (void),
++ hook_bool_void_false)
++
+ /* Close the 'struct gcc_target' definition.  */
+ HOOK_VECTOR_END (C90_EMPTY_HACK)
Index: pkgsrc/lang/gcc15/patches/patch-gcc_target.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_target.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_target.h        Sun Jul 19 11:17:44 2026
@@ -0,0 +1,32 @@
+$NetBSD: patch-gcc_target.h,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/target.h.orig  2026-06-12 06:09:06.827529177 +0000
++++ gcc/target.h
+@@ -51,22 +51,8 @@
+ #include "insn-codes.h"
+ #include "tm.h"
+ #include "hard-reg-set.h"
+-
+-#if CHECKING_P
+-
+-struct cumulative_args_t { void *magic; void *p; };
+-
+-#else /* !CHECKING_P */
+-
+-/* When using a GCC build compiler, we could use
+-   __attribute__((transparent_union)) to get cumulative_args_t function
+-   arguments passed like scalars where the ABI would mandate a less
+-   efficient way of argument passing otherwise.  However, that would come
+-   at the cost of less type-safe !CHECKING_P compilation.  */
+-
+-union cumulative_args_t { void *p; };
+-
+-#endif /* !CHECKING_P */
++#include "tree-core.h"
++#include "cumulative-args.h"
+
+ /* Target properties of _BitInt(N) type.  _BitInt(N) is to be represented
+    as series of abi_limb_mode CEIL (N, GET_MODE_PRECISION (abi_limb_mode))
Index: pkgsrc/lang/gcc15/patches/patch-gcc_targhooks.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-gcc_targhooks.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-gcc_targhooks.h     Sun Jul 19 11:17:44 2026
@@ -0,0 +1,30 @@
+$NetBSD: patch-gcc_targhooks.h,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- gcc/targhooks.h.orig       2026-06-12 06:09:06.828529193 +0000
++++ gcc/targhooks.h
+@@ -34,6 +34,9 @@ extern machine_mode default_promote_func
+ extern machine_mode default_promote_function_mode_always_promote
+                       (const_tree, machine_mode, int *, const_tree, int);
+
++extern machine_mode default_promote_function_mode_ca
++  (cumulative_args_t, function_arg_info, const_tree, int *, int);
++
+ extern machine_mode default_cc_modes_compatible (machine_mode,
+                                                     machine_mode);
+
+@@ -161,6 +164,12 @@ extern unsigned int default_function_arg
+                                                  const_tree);
+ extern unsigned int default_function_arg_round_boundary (machine_mode,
+                                                        const_tree);
++extern unsigned int default_function_arg_boundary_ca (machine_mode,
++                                                    const_tree,
++                                                    cumulative_args_t ca);
++extern unsigned int default_function_arg_round_boundary_ca (machine_mode,
++                                                          const_tree,
++                                                          cumulative_args_t ca);
+ extern bool hook_bool_const_rtx_commutative_p (const_rtx, int);
+ extern rtx default_function_value (const_tree, const_tree, bool);
+ extern HARD_REG_SET default_zero_call_used_regs (HARD_REG_SET);
Index: pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__sme__state.S
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__sme__state.S:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__sme__state.S Sun Jul 19 11:17:44 2026
@@ -0,0 +1,38 @@
+$NetBSD: patch-libgcc_config_aarch64_____arm__sme__state.S,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libgcc/config/aarch64/__arm_sme_state.S.orig       2026-06-12 06:09:09.988305985 +0000
++++ libgcc/config/aarch64/__arm_sme_state.S
+@@ -30,14 +30,19 @@
+    - Takes no argument.
+    - Returns SME state in x0 and TPIDR2_EL0 in x1.  */
+
+-HIDDEN (__aarch64_have_sme)
++HIDDEN (ASMNAME (__aarch64_have_sme))
+
+-variant_pcs (__arm_sme_state)
++variant_pcs (ASMNAME (__arm_sme_state))
+
+-ENTRY (__arm_sme_state)
++ENTRY (ASMNAME (__arm_sme_state))
+       /* Check if SME is available.  */
+-      adrp    x1, __aarch64_have_sme
+-      ldrb    w1, [x1, :lo12:__aarch64_have_sme]
++#ifdef __APPLE__
++      adrp    x1, ASMNAME (__aarch64_have_sme)@PAGE
++      ldrb    w1, [x1, ASMNAME (__aarch64_have_sme)@PAGEOFF]
++#else
++      adrp    x1, ASMNAME (__aarch64_have_sme)
++      ldrb    w1, [x1, :lo12:ASMNAME (__aarch64_have_sme)]
++#endif
+       cbz     w1, L(nosme)
+
+       /* Expose the bottom 2 bits of svcr (SM, ZA) in x0 and set the
+@@ -52,4 +57,4 @@ L(nosme):
+       mov     x0, 0
+       mov     x1, 0
+       ret
+-END (__arm_sme_state)
++ENDm ASMNAME(__arm_sme_state)
Index: pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__tpidr2__restore.S
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__tpidr2__restore.S:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__tpidr2__restore.S    Sun Jul 19 11:17:44 2026
@@ -0,0 +1,27 @@
+$NetBSD: patch-libgcc_config_aarch64_____arm__tpidr2__restore.S,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libgcc/config/aarch64/__arm_tpidr2_restore.S.orig  2026-06-12 06:09:09.988305985 +0000
++++ libgcc/config/aarch64/__arm_tpidr2_restore.S
+@@ -31,9 +31,9 @@
+    - Does not return a value.
+    - Can abort on failure (then registers are not preserved).  */
+
+-variant_pcs (__arm_tpidr2_restore)
++variant_pcs (ASMNAME (__arm_tpidr2_restore))
+
+-ENTRY (__arm_tpidr2_restore)
++ENTRY (ASMNAME (__arm_tpidr2_restore))
+       .inst   0xd53bd0ae  /* mrs      x14, tpidr2_el0  */
+       cbnz    x14, L(fail)
+
+@@ -85,5 +85,5 @@ L(fail):
+       str     x16, [sp, 16]
+       .cfi_rel_offset 46, 16
+       .inst   0xd503467f  /* smstop  */
+-      bl      abort
+-END (__arm_tpidr2_restore)
++      bl      ASMNAME (abort)
++ENDm ASMNAME (__arm_tpidr2_restore)
Index: pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__tpidr2__save.S
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__tpidr2__save.S:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__tpidr2__save.S       Sun Jul 19 11:17:44 2026
@@ -0,0 +1,50 @@
+$NetBSD: patch-libgcc_config_aarch64_____arm__tpidr2__save.S,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libgcc/config/aarch64/__arm_tpidr2_save.S.orig     2026-06-12 06:09:09.988305985 +0000
++++ libgcc/config/aarch64/__arm_tpidr2_save.S
+@@ -35,10 +35,15 @@ HIDDEN (__aarch64_have_sme)
+
+ variant_pcs (__arm_tpidr2_save)
+
+-ENTRY (__arm_tpidr2_save)
++ENTRY (ASMNAME (__arm_tpidr2_save))
+       /* Check if SME is available.  */
+-      adrp    x14, __aarch64_have_sme
+-      ldrb    w14, [x14, :lo12:__aarch64_have_sme]
++#if __APPLE__
++      adrp    x14, ASMNAME (__aarch64_have_sme)@PAGE
++      ldrb    w14, [x14, ASMNAME (__aarch64_have_sme)@PAGEOFF]
++#else
++      adrp    x14, ASMNAME (__aarch64_have_sme)
++      ldrb    w14, [x14, :lo12:ASMNAME (__aarch64_have_sme)]
++#endif
+       cbz     w14, L(end)
+
+       .inst   0xd53bd0ae  /* mrs      x14, tpidr2_el0  */
+@@ -92,10 +97,18 @@ L(fail):
+       str     x16, [sp, 16]
+       .cfi_rel_offset 46, 16
+       .inst   0xd503467f  /* smstop  */
+-      bl      abort
+-END (__arm_tpidr2_save)
++      bl      ASMNAME (abort)
++ENDm ASMNAME (__arm_tpidr2_save)
+
++      GLOBAL(ASMNAME (__libgcc_arm_tpidr2_save))
++      HIDDEN (ASMNAME (__libgcc_arm_tpidr2_save))
++#if __APPLE__
++      .text
++      .p2align 4
++ASMNAME (__libgcc_arm_tpidr2_save):
++      b ASMNAME (__arm_tpidr2_save)
++#else
+ /* Hidden alias used by __arm_za_disable.  */
+-.global __libgcc_arm_tpidr2_save
+-HIDDEN (__libgcc_arm_tpidr2_save)
+-.set __libgcc_arm_tpidr2_save, __arm_tpidr2_save
++.set ASMNAME (__libgcc_arm_tpidr2_save), ASMNAME (__arm_tpidr2_save)
++#endif
++
Index: pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__za__disable.S
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__za__disable.S:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_____arm__za__disable.S        Sun Jul 19 11:17:44 2026
@@ -0,0 +1,67 @@
+$NetBSD: patch-libgcc_config_aarch64_____arm__za__disable.S,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libgcc/config/aarch64/__arm_za_disable.S.orig      2026-06-12 06:09:09.988305985 +0000
++++ libgcc/config/aarch64/__arm_za_disable.S
+@@ -31,16 +31,33 @@
+    - Does not return a value.
+    - Can abort on failure (then registers are not preserved).  */
+
+-HIDDEN (__aarch64_have_sme)
++HIDDEN (ASMNAME(__aarch64_have_sme))
+
+-HIDDEN (__libgcc_arm_tpidr2_save)
++HIDDEN (ASMNAME(__libgcc_arm_tpidr2_save))
+
+-variant_pcs (__arm_za_disable)
++variant_pcs (ASMNAME(__arm_za_disable))
+
+-ENTRY (__arm_za_disable)
++GLOBAL (ASMNAME (__libgcc_arm_za_disable))
++HIDDEN (ASMNAME (__libgcc_arm_za_disable))
++#if __APPLE__
++      .text
++      .p2align 4
++ASMNAME (__libgcc_arm_za_disable):
++      b ASMNAME (__arm_za_disable)
++#else
++/* Hidden alias used by the unwinder.  */
++.set ASMNAME (__libgcc_arm_za_disable), ASMNAME (__arm_za_disable)
++#endif
++
++ENTRY (ASMNAME (__arm_za_disable))
+       /* Check if SME is available.  */
+-      adrp    x14, __aarch64_have_sme
+-      ldrb    w14, [x14, :lo12:__aarch64_have_sme]
++#if __APPLE__
++      adrp    x14, ASMNAME (__aarch64_have_sme)@PAGE
++      ldrb    w14, [x14, ASMNAME (__aarch64_have_sme)@PAGEOFF]
++#else
++      adrp    x14, ASMNAME (__aarch64_have_sme)
++      ldrb    w14, [x14, :lo12:ASMNAME (__aarch64_have_sme)]
++#endif
+       cbz     w14, L(end)
+
+       .inst   0xd53bd0ae  /* mrs      x14, tpidr2_el0  */
+@@ -52,7 +69,7 @@ ENTRY (__arm_za_disable)
+       .cfi_rel_offset x29, 0
+       .cfi_rel_offset x30, 8
+       mov     x29, sp
+-      bl      __libgcc_arm_tpidr2_save
++      bl      ASMNAME (__libgcc_arm_tpidr2_save)
+       .inst   0xd51bd0bf  /* msr      tpidr2_el0, xzr  */
+       .inst   0xd503447f  /* smstop   za  */
+       ldp     x29, x30, [sp], 16
+@@ -62,9 +79,5 @@ ENTRY (__arm_za_disable)
+       AUTIASP
+ L(end):
+       ret
+-END (__arm_za_disable)
++ENDm ASMNAME(__arm_za_disable)
+
+-/* Hidden alias used by the unwinder.  */
+-.global __libgcc_arm_za_disable
+-HIDDEN (__libgcc_arm_za_disable)
+-.set __libgcc_arm_za_disable, __arm_za_disable
Index: pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_aarch64-asm.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_aarch64-asm.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_aarch64-asm.h Sun Jul 19 11:17:44 2026
@@ -0,0 +1,81 @@
+$NetBSD: patch-libgcc_config_aarch64_aarch64-asm.h,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libgcc/config/aarch64/aarch64-asm.h.orig   2026-06-12 06:09:09.988305985 +0000
++++ libgcc/config/aarch64/aarch64-asm.h
+@@ -27,8 +27,6 @@
+
+ #include "auto-target.h"
+
+-#define L(label) .L ## label
+-
+ /* Marking variant PCS symbol references is important for PLT calls
+    otherwise it is for documenting the PCS in the symbol table.  */
+ #ifdef HAVE_AS_VARIANT_PCS
+@@ -68,12 +66,31 @@
+ # define GCS_FLAG 0
+ #endif
+
++#define PASTE2(a, b) PASTE2a(a, b)
++#define PASTE2a(a, b) a ## b
++
++#ifdef __USER_LABEL_PREFIX__
++# define ASMNAME(name) PASTE2(__USER_LABEL_PREFIX__, name)
++#else
++# define ASMNAME(name) name
++#endif
++
+ #ifdef __ELF__
++#define L(label) .L ## label
+ #define HIDDEN(name) .hidden name
++#define GLOBAL(name) .global name
+ #define SYMBOL_SIZE(name) .size name, .-name
+ #define SYMBOL_TYPE(name, _type) .type name, _type
++#elif __APPLE__
++#define L(label) L ## label
++#define HIDDEN(name) .private_extern name
++#define GLOBAL(name) .globl name
++#define SYMBOL_SIZE(name)
++#define SYMBOL_TYPE(name, _type)
+ #else
++#define L(label) .L ## label
+ #define HIDDEN(name)
++#define GLOBAL(name) .global name
+ #define SYMBOL_SIZE(name)
+ #define SYMBOL_TYPE(name, _type)
+ #endif
+@@ -103,18 +120,24 @@ GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PA
+ # endif
+ #endif
+
+-#define ENTRY_ALIGN(name, align) \
+-  .global name;               \
+-  SYMBOL_TYPE(name, %function);               \
+-  .balign align;      \
+-  name:                       \
+-  .cfi_startproc;     \
+-  BTI_C
++.macro        ENTRY_ALIGNP2m, name, align
++      .text
++      .p2align \align
++      GLOBAL (\name)
++      SYMBOL_TYPE(\name, %function)
++\name:
++      .cfi_startproc
++      BTI_C
++.endm
+
+-#define ENTRY(name) ENTRY_ALIGN(name, 16)
++#define ENTRY(name) ENTRY_ALIGNP2m name, 4
+
+ #define END(name) \
+   .cfi_endproc;               \
+   SYMBOL_SIZE(name)
+
++.macro        ENDm, name
++      .cfi_endproc
++      SYMBOL_SIZE (\name)
++.endm
+ #endif
Index: pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_lse.S
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_lse.S:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_lse.S Sun Jul 19 11:17:44 2026
@@ -0,0 +1,108 @@
+$NetBSD: patch-libgcc_config_aarch64_lse.S,v 1.1 2026/07/19 11:17:44 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libgcc/config/aarch64/lse.S.orig   2026-06-12 06:09:09.988578105 +0000
++++ libgcc/config/aarch64/lse.S
+@@ -66,7 +66,7 @@ see the files COPYING3 and COPYING.RUNTI
+ #endif
+
+ /* Declare the symbol gating the LSE implementations.  */
+-      HIDDEN(__aarch64_have_lse_atomics)
++      HIDDEN (ASMNAME (__aarch64_have_lse_atomics))
+
+ /* Turn size and memory model defines into mnemonic fragments.  */
+ #if SIZE == 1
+@@ -89,6 +89,7 @@ see the files COPYING3 and COPYING.RUNTI
+ # error
+ #endif
+
++#undef L
+ #if MODEL == 1
+ # define SUFF  _relax
+ # define A
+@@ -171,32 +172,21 @@ see the files COPYING3 and COPYING.RUNTI
+ #define tmp3  14
+ #define tmp4  13
+
+-/* Start and end a function.  */
+-.macro        STARTFN name
+-      .text
+-      .balign 16
+-      .globl  \name
+-      HIDDEN(\name)
+-      SYMBOL_TYPE(\name, %function)
+-      .cfi_startproc
+-\name:
+-.endm
+-
+-.macro        ENDFN name
+-      .cfi_endproc
+-      SYMBOL_SIZE(\name)
+-.endm
+-
+ /* Branch to LABEL if LSE is disabled.  */
+ .macro        JUMP_IF_NOT_LSE label
+-      adrp    x(tmp0), __aarch64_have_lse_atomics
+-      ldrb    w(tmp0), [x(tmp0), :lo12:__aarch64_have_lse_atomics]
++#if __APPLE__
++      adrp    x(tmp0), ASMNAME (__aarch64_have_lse_atomics)@PAGE
++      ldrb    w(tmp0), [x(tmp0), ASMNAME (__aarch64_have_lse_atomics)@PAGEOFF]
++#else
++      adrp    x(tmp0), ASMNAME (__aarch64_have_lse_atomics)
++      ldrb    w(tmp0), [x(tmp0), :lo12:ASMNAME (__aarch64_have_lse_atomics)]
++#endif
+       cbz     w(tmp0), \label
+ .endm
+
+ #ifdef L_cas
+
+-STARTFN       NAME(cas)
++ENTRY (ASMNAME (NAME(cas)))
+       JUMP_IF_NOT_LSE 8f
+
+ #if SIZE < 16
+@@ -249,7 +239,7 @@ STARTFN    NAME(cas)
+
+ #endif
+
+-ENDFN NAME(cas)
++ENDm ASMNAME (NAME(cas))
+ #endif
+
+ #ifdef L_swp
+@@ -259,7 +249,7 @@ ENDFN      NAME(cas)
+ # define SWP  .inst 0x38208020 + B + N
+ #endif
+
+-STARTFN       NAME(swp)
++ENTRY (ASMNAME (NAME (swp)))
+       JUMP_IF_NOT_LSE 8f
+
+       SWP             /* s(0), s(0), [x1] */
+@@ -272,7 +262,7 @@ STARTFN    NAME(swp)
+       BARRIER
+       ret
+
+-ENDFN NAME(swp)
++ENDm ASMNAME (NAME (swp))
+ #endif
+
+ #if defined(L_ldadd) || defined(L_ldclr) \
+@@ -303,7 +293,7 @@ ENDFN      NAME(swp)
+ # define LDOP .inst 0x38200020 + OPN + B + N
+ #endif
+
+-STARTFN       NAME(LDNM)
++ENTRY (ASMNAME (NAME (LDNM)))
+       JUMP_IF_NOT_LSE 8f
+
+       LDOP            /* s(0), s(0), [x1] */
+@@ -317,5 +307,5 @@ STARTFN    NAME(LDNM)
+       BARRIER
+       ret
+
+-ENDFN NAME(LDNM)
++ENDm ASMNAME (NAME (LDNM))
+ #endif
Index: pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_sfp-machine.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_sfp-machine.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_sfp-machine.h Sun Jul 19 11:17:45 2026
@@ -0,0 +1,35 @@
+$NetBSD: patch-libgcc_config_aarch64_sfp-machine.h,v 1.1 2026/07/19 11:17:45 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libgcc/config/aarch64/sfp-machine.h.orig   2026-06-12 06:09:09.988578105 +0000
++++ libgcc/config/aarch64/sfp-machine.h
+@@ -124,6 +124,27 @@ void __sfp_handle_exceptions (int);
+
+
+ /* Define ALIASNAME as a strong alias for NAME.  */
++#if defined __APPLE__
++/* Mach-O doesn't support aliasing, so we build a secondary function for
++   the alias - we need to do a bit of a dance to find out what the type of
++   the arguments is and then apply that to the secondary function.
++   If these functions ever return anything but CMPtype we need to revisit
++   this... */
++typedef float alias_HFtype __attribute__ ((mode (HF)));
++typedef float alias_SFtype __attribute__ ((mode (SF)));
++typedef float alias_DFtype __attribute__ ((mode (DF)));
++typedef float alias_TFtype __attribute__ ((mode (TF)));
++#define ALIAS_SELECTOR \
++  CMPtype (*) (alias_HFtype, alias_HFtype): (alias_HFtype) 0, \
++  CMPtype (*) (alias_SFtype, alias_SFtype): (alias_SFtype) 0, \
++  CMPtype (*) (alias_DFtype, alias_DFtype): (alias_DFtype) 0, \
++  CMPtype (*) (alias_TFtype, alias_TFtype): (alias_TFtype) 0
++#define strong_alias(name, aliasname) \
++  CMPtype aliasname (__typeof (_Generic (name, ALIAS_SELECTOR)) a, \
++                   __typeof (_Generic (name, ALIAS_SELECTOR)) b) \
++                  { return name (a, b); }
++#else
+ # define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+ # define _strong_alias(name, aliasname) \
+   extern __typeof (name) aliasname __attribute__ ((alias (#name)));
++#endif
Index: pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_t-darwin
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_t-darwin:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libgcc_config_aarch64_t-darwin      Sun Jul 19 11:17:45 2026
@@ -0,0 +1,13 @@
+$NetBSD: patch-libgcc_config_aarch64_t-darwin,v 1.1 2026/07/19 11:17:45 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libgcc/config/aarch64/t-darwin.orig        2026-07-19 09:48:42.303097912 +0000
++++ libgcc/config/aarch64/t-darwin
+@@ -0,0 +1,5 @@
++# Ensure we have a suitable minimum OS version.
++
++HOST_LIBGCC2_CFLAGS += -mmacosx-version-min=11.0
++
++LIB2_SIDITI_CONV_FUNCS = yes
Index: pkgsrc/lang/gcc15/patches/patch-libgcc_config_libbid_bid__binarydecimal.c
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libgcc_config_libbid_bid__binarydecimal.c:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libgcc_config_libbid_bid__binarydecimal.c   Sun Jul 19 11:17:45 2026
@@ -0,0 +1,16 @@
+$NetBSD: patch-libgcc_config_libbid_bid__binarydecimal.c,v 1.1 2026/07/19 11:17:45 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libgcc/config/libbid/bid_binarydecimal.c.orig      2026-06-12 06:09:10.034578818 +0000
++++ libgcc/config/libbid/bid_binarydecimal.c
+@@ -412,7 +412,7 @@ BID_BINARY80LDOUBLE;
+ }
+
+ #define unpack_binary80(x,s,e,c,t,zero,inf,nan)                             \
+-{ BID_BINARY80LDOUBLE x_in;                                                 \
++{ BID_BINARY80LDOUBLE x_in = {0};                                                 \
+   x_in.f = x;                                                               \
+   c = x_in.i.lo4 + ((UINT64)x_in.i.lo3 << 16) +                             \
+       ((UINT64)x_in.i.lo2 << 32) + ((UINT64)x_in.i.lo1 << 48);              \
Index: pkgsrc/lang/gcc15/patches/patch-libitm_config_aarch64_sjlj.S
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libitm_config_aarch64_sjlj.S:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libitm_config_aarch64_sjlj.S        Sun Jul 19 11:17:45 2026
@@ -0,0 +1,73 @@
+$NetBSD: patch-libitm_config_aarch64_sjlj.S,v 1.1 2026/07/19 11:17:45 adam Exp $
+
+--- libitm/config/aarch64/sjlj.S.orig  2026-06-12 06:09:10.542381833 +0000
++++ libitm/config/aarch64/sjlj.S
+@@ -57,10 +57,19 @@
+ 
+       .text
+       .align  2
++#if __ELF__
+       .global _ITM_beginTransaction
+       .type   _ITM_beginTransaction, %function
+ 
+ _ITM_beginTransaction:
++
++#elif __MACH__
++      .global __ITM_beginTransaction
++
++__ITM_beginTransaction:
++
++#endif
++
+       cfi_startproc
+       CFI_PAC_KEY
+       PAC_AND_BTI
+@@ -84,8 +93,13 @@ _ITM_beginTransaction:
+ 
+       /* Invoke GTM_begin_transaction with the struct we just built.  */
+       mov     x1, sp
++#if __ELF__
+       bl      GTM_begin_transaction
+-
++#elif __MACH__
++      bl      _GTM_begin_transaction
++#else
++#error "unexpected object format"
++#endif
+       /* Return; we don't need to restore any of the call-saved regs.  */
+       ldp     x29, x30, [sp], 11*16
+       cfi_adjust_cfa_offset(-11*16)
+@@ -95,14 +109,23 @@ _ITM_beginTransaction:
+       CFI_PAC_TOGGLE
+       ret
+       cfi_endproc
++#if __ELF__
+       .size   _ITM_beginTransaction, . - _ITM_beginTransaction
++#endif
+ 
+       .align  2
++#if __ELF__
+       .global GTM_longjmp
+       .hidden GTM_longjmp
+       .type   GTM_longjmp, %function
+ 
+ GTM_longjmp:
++
++#elif __MACH__
++      .private_extern _GTM_longjmp
++
++_GTM_longjmp:
++#endif
+       /* The first parameter becomes the return value (x0).
+          The third parameter is ignored for now.  */
+       cfi_startproc
+@@ -126,7 +149,9 @@ GTM_longjmp:
+       CFI_PAC_TOGGLE
+       br      x30
+       cfi_endproc
++#if __ELF__
+       .size   GTM_longjmp, . - GTM_longjmp
++#endif
+ 
+ /* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code.  */
+ #define FEATURE_1_AND 0xc0000000
Index: pkgsrc/lang/gcc15/patches/patch-libitm_configure.tgt
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libitm_configure.tgt:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libitm_configure.tgt        Sun Jul 19 11:17:45 2026
@@ -0,0 +1,16 @@
+$NetBSD: patch-libitm_configure.tgt,v 1.1 2026/07/19 11:17:45 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libitm/configure.tgt.orig  2026-06-12 06:09:10.544586712 +0000
++++ libitm/configure.tgt
+@@ -50,7 +50,7 @@ fi
+ # Map the target cpu to an ARCH sub-directory.  At the same time,
+ # work out any special compilation flags as necessary.
+ case "${target_cpu}" in
+-  aarch64*)           ARCH=aarch64 ;;
++  aarch64* | arm64*)  ARCH=aarch64 ;;
+   alpha*)             ARCH=alpha ;;
+   rs6000 | powerpc*)
+       XCFLAGS="${XCFLAGS} -mhtm"
Index: pkgsrc/lang/gcc15/patches/patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d       Sun Jul 19 11:17:45 2026
@@ -0,0 +1,23 @@
+$NetBSD: patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d,v 1.1 2026/07/19 11:17:45 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d.orig 2026-06-12 06:09:10.558026783 +0000
++++ libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
+@@ -30,8 +30,13 @@ module core.internal.gc.impl.conservativ
+
+ /***************************************************/
+ version = COLLECT_PARALLEL;  // parallel scanning
+-version (Posix)
+-    version = COLLECT_FORK;
++version (GNU)
++{
++  version (linux)
++    version = COLLECT_FORK;  // uses clone(), battle tested and reliable
++}
++else version (Posix)
++  version = COLLECT_FORK;
+
+ import core.internal.gc.bits;
+ import core.internal.gc.os;
Index: pkgsrc/lang/gcc15/patches/patch-libsanitizer_configure.tgt
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libsanitizer_configure.tgt:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libsanitizer_configure.tgt  Sun Jul 19 11:17:45 2026
@@ -0,0 +1,21 @@
+$NetBSD: patch-libsanitizer_configure.tgt,v 1.1 2026/07/19 11:17:45 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libsanitizer/configure.tgt.orig    2026-06-12 06:09:10.653588399 +0000
++++ libsanitizer/configure.tgt
+@@ -65,7 +65,12 @@ case "${target}" in
+               HWASAN_SUPPORTED=yes
+       fi
+       ;;
+-  x86_64-*-darwin2[01]* | x86_64-*-darwin1[6-9]* | i?86-*-darwin1[6-8]*)
++  aarch64-*-darwin2*)
++      TSAN_SUPPORTED=no
++      LSAN_SUPPORTED=no
++      EXTRA_CXXFLAGS="${EXTRA_CXXFLAGS} -Wl,-undefined,dynamic_lookup "
++      ;;
++  x86_64-*-darwin2* | x86_64-*-darwin1[6-9]* | i?86-*-darwin1[6-8]*)
+       TSAN_SUPPORTED=no
+       EXTRA_CXXFLAGS="${EXTRA_CXXFLAGS} -Wl,-undefined,dynamic_lookup"
+       ;;
Index: pkgsrc/lang/gcc15/patches/patch-libsanitizer_sanitizer__common_sanitizer__common.h
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libsanitizer_sanitizer__common_sanitizer__common.h:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libsanitizer_sanitizer__common_sanitizer__common.h  Sun Jul 19 11:17:45 2026
@@ -0,0 +1,24 @@
+$NetBSD: patch-libsanitizer_sanitizer__common_sanitizer__common.h,v 1.1 2026/07/19 11:17:45 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libsanitizer/sanitizer_common/sanitizer_common.h.orig      2026-06-12 06:09:10.661588523 +0000
++++ libsanitizer/sanitizer_common/sanitizer_common.h
+@@ -734,6 +734,7 @@ enum ModuleArch {
+   kModuleArchARMV7S,
+   kModuleArchARMV7K,
+   kModuleArchARM64,
++  kModuleArchARM64E,
+   kModuleArchLoongArch64,
+   kModuleArchRISCV64,
+   kModuleArchHexagon
+@@ -807,6 +808,8 @@ inline const char *ModuleArchToString(Mo
+       return "armv7k";
+     case kModuleArchARM64:
+       return "arm64";
++    case kModuleArchARM64E:
++      return "arm64e";
+     case kModuleArchLoongArch64:
+       return "loongarch64";
+     case kModuleArchRISCV64:
Index: pkgsrc/lang/gcc15/patches/patch-libsanitizer_sanitizer__common_sanitizer__procmaps__mac.cpp
diff -u /dev/null pkgsrc/lang/gcc15/patches/patch-libsanitizer_sanitizer__common_sanitizer__procmaps__mac.cpp:1.1
--- /dev/null   Sun Jul 19 11:17:45 2026
+++ pkgsrc/lang/gcc15/patches/patch-libsanitizer_sanitizer__common_sanitizer__procmaps__mac.cpp Sun Jul 19 11:17:45 2026
@@ -0,0 +1,262 @@
+$NetBSD: patch-libsanitizer_sanitizer__common_sanitizer__procmaps__mac.cpp,v 1.1 2026/07/19 11:17:45 adam Exp $
+
+Support Darwin/aarch64.
+https://github.com/Homebrew/homebrew-core/blob/main/Patches/gcc/gcc-15.3.0.diff
+
+--- libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp.orig      2026-06-12 06:09:10.669588646 +0000
++++ libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
+@@ -20,18 +20,21 @@
+ #include <mach/mach.h>
+
+ // These are not available in older macOS SDKs.
+-#ifndef CPU_SUBTYPE_X86_64_H
+-#define CPU_SUBTYPE_X86_64_H  ((cpu_subtype_t)8)   /* Haswell */
+-#endif
+-#ifndef CPU_SUBTYPE_ARM_V7S
+-#define CPU_SUBTYPE_ARM_V7S   ((cpu_subtype_t)11)  /* Swift */
+-#endif
+-#ifndef CPU_SUBTYPE_ARM_V7K
+-#define CPU_SUBTYPE_ARM_V7K   ((cpu_subtype_t)12)
+-#endif
+-#ifndef CPU_TYPE_ARM64
+-#define CPU_TYPE_ARM64        (CPU_TYPE_ARM | CPU_ARCH_ABI64)
+-#endif
++#  ifndef CPU_SUBTYPE_X86_64_H
++#    define CPU_SUBTYPE_X86_64_H ((cpu_subtype_t)8) /* Haswell */
++#  endif
++#  ifndef CPU_SUBTYPE_ARM_V7S
++#    define CPU_SUBTYPE_ARM_V7S ((cpu_subtype_t)11) /* Swift */
++#  endif
++#  ifndef CPU_SUBTYPE_ARM_V7K
++#    define CPU_SUBTYPE_ARM_V7K ((cpu_subtype_t)12)
++#  endif
++#  ifndef CPU_TYPE_ARM64
++#    define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
++#  endif
++#  ifndef CPU_SUBTYPE_ARM64E
++#    define CPU_SUBTYPE_ARM64E ((cpu_subtype_t)2)
++#  endif
+
+ namespace __sanitizer {
+
+@@ -146,13 +149,8 @@ static bool IsDyldHdr(const mach_header
+ // until we hit a Mach header matching dyld instead. These recurse
+ // calls are expensive, but the first memory map generation occurs
+ // early in the process, when dyld is one of the only images loaded,
+-// so it will be hit after only a few iterations.  These assumptions don't
+-// hold on macOS 13+ anymore (dyld itself has moved into the shared cache).
+-
+-// FIXME: Unfortunately, the upstream revised version to deal with macOS 13+
+-// is incompatible with GCC and also uses APIs not available on earlier
+-// systems which we support; backed out for now.
+-
++// so it will be hit after only a few iterations.  These assumptions don't hold
++// on macOS 13+ anymore (dyld itself has moved into the shared cache).
+ static mach_header *GetDyldImageHeaderViaVMRegion() {
+   vm_address_t address = 0;
+
+@@ -176,17 +174,178 @@ static mach_header *GetDyldImageHeaderVi
+   }
+ }
+
++extern "C" {
++struct dyld_shared_cache_dylib_text_info {
++  uint64_t version;  // current version 2
++  // following fields all exist in version 1
++  uint64_t loadAddressUnslid;
++  uint64_t textSegmentSize;
++  uuid_t dylibUuid;
++  const char *path;  // pointer invalid at end of iterations
++  // following fields all exist in version 2
++  uint64_t textSegmentOffset;  // offset from start of cache
++};
++typedef struct dyld_shared_cache_dylib_text_info
++    dyld_shared_cache_dylib_text_info;
++
++extern bool _dyld_get_shared_cache_uuid(uuid_t uuid);
++extern const void *_dyld_get_shared_cache_range(size_t *length);
++extern intptr_t _dyld_get_image_slide(const struct mach_header* mh);
++} // extern "C"
++
++#ifdef __BLOCKS__
++extern "C" {
++extern int dyld_shared_cache_iterate_text(
++    const uuid_t cacheUuid,
++    void (^callback)(const dyld_shared_cache_dylib_text_info *info));
++}  // extern "C"
++
++static mach_header *GetDyldImageHeaderViaSharedCache(uuid_t uuid) {
++  size_t cacheLength;
++  const uptr cacheStart = (uptr)_dyld_get_shared_cache_range(&cacheLength);
++  CHECK(cacheStart && cacheLength);
++
++  __block mach_header *dyldHdr = nullptr;
++  int res = dyld_shared_cache_iterate_text(
++      uuid, ^(const dyld_shared_cache_dylib_text_info *info) {
++        CHECK_GE(info->version, 2);
++        mach_header *hdr =
++            (mach_header *)(cacheStart + info->textSegmentOffset);
++        if (IsDyldHdr(hdr))
++          dyldHdr = hdr;
++      });
++  CHECK_EQ(res, 0);
++
++  return dyldHdr;
++}
++
++#else
++
++/* Here we implement a manual emulation of the Blocks closure and callback
++   that is needed by dyld_shared_cache_iterate_text ().  In the compiler-
++   generated code, the [local] names are mangled differently, but that
++   should not matter to the function (since all the entities are TU-local).  */
++
++extern "C" {
++/* Some descriptions of the blocks interfaces/runtime that we need.  */
++extern void *_NSConcreteStackBlock;
++extern void _Block_object_assign(void *, void *, int);
++extern void _Block_object_dispose(void *, int);
++enum {
++  BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)), block, ... */
++  BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
++  BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the __block variable */
++  BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy helpers */
++  BLOCK_BYREF_CALLER      = 128  /* called from __block (byref) copy/dispose support routines. */
++};
++
++/* 1. __block mach_header *dyldHdr; Uses this on-stack object.  */
++typedef struct __block_byref_dyldHdr {
++    void *__isa;
++    struct __block_byref_dyldHdr *forwarding;
++    int flags;   // 1<<25 iff we need copy helper;
++    int size;
++    mach_header *dyldHdr_cp;
++} dyldHdr_type;
++
++/* The closure, support functions and the actuall callback code.  */
++/* 1. closure descriptor.  A constant instance of this will be created.  */
++struct Block_descriptor_cb {
++  unsigned long int reserved;     // NULL
++  unsigned long int size;         // sizeof(struct Block_literal_cb)
++  // optional helper functions
++  void (*copy_helper)(struct Block_literal_cb *dst, struct Block_literal_cb *src);     // IFF (1<<25)
++  void (*dispose_helper)(struct Block_literal_cb *src);             // IFF (1<<25)
++  // required ABI.2010.3.16
++  const char *signature;                         // IFF (1<<30)
++  void *no_idea; // not documented in the current ABI
++};
++
++/* 2. This is the closure object.  In this case, it will be allocated on the
++      stack and does not need to be moved (since the closure never escapes
++      from its enclosing scope).  However, the infrastructure still provides
++      support for moving it to the heap if required.  */
++typedef struct Block_literal_cb {
++  void *__isa;
++  int flags;
++  int reserved;
++  void (*invoke) (Block_literal_cb*, const dyld_shared_cache_dylib_text_info *info);
++  const struct Block_descriptor_cb *descriptor;
++  dyldHdr_type *h_holder;
++  uptr cache_start;
++} CallbackBlk;
++
++/* 3. Supporting functions to allow for the closure to be copied to the heap on
++   demand.  */
++static void
++__block_copy_cb (struct Block_literal_cb *dst, struct Block_literal_cb *src)
++{
++  //_Block_byref_assign_copy(&dst->captured_i, src->captured_i);
++  _Block_object_assign(&dst->h_holder, src->h_holder, BLOCK_FIELD_IS_BYREF);
++}
++
++static void
++__block_dispose_cb (struct Block_literal_cb *src) {
++   //_Block_byref_release(src->captured_i);
++  _Block_object_dispose(src->h_holder, BLOCK_FIELD_IS_BYREF);
++}
++
++/* 4. Here is the actual code implementing the callback.  */
++static void
++__block_invoke_cb (struct Block_literal_cb *_block,
++                 const dyld_shared_cache_dylib_text_info *info)
++{
++  mach_header *hdr = (mach_header *)(_block->cache_start + info->textSegmentOffset);
++  if (IsDyldHdr(hdr))
++    _block->h_holder->forwarding->dyldHdr_cp = hdr;
++}
++
++/* 6. The constant instance of the descriptor mentioned in 1 above.  */
++static const struct Block_descriptor_cb cb_descr = {
++    0, sizeof (struct Block_literal_cb), __block_copy_cb, __block_dispose_cb,
++    "v16@?0r^{dyld_shared_cache_dylib_text_info=QQQ[16C]*Q}8", nullptr
++};
++
++/* Declare dyld_shared_cache_iterate_text () as taking a regular pointer to
++   the closure; we cannot use the ^ syntax yet in GCC.  */
++extern int dyld_shared_cache_iterate_text(const uuid_t cacheUuid, CallbackBlk*);
++}  // extern "C"
++
++/* The non-blocks version of GetDyldImageHeaderViaSharedCache ().  */
++static mach_header *GetDyldImageHeaderViaSharedCache(uuid_t uuid) {
++  size_t cacheLength;
++  const uptr cacheStart = (uptr)_dyld_get_shared_cache_range(&cacheLength);
++  CHECK(cacheStart && cacheLength);
++  /* __block mach_header *dyldHdr = nullptr; */
++  dyldHdr_type dyldHdr
++    = { nullptr, &dyldHdr, 0, sizeof (struct __block_byref_dyldHdr), nullptr };
++  /* Callback cb = ^(const dyld_shared_cache_dylib_text_info *info... */
++  CallbackBlk cb
++    = { _NSConcreteStackBlock, 0x42000000, 0, __block_invoke_cb,
++        &cb_descr, &dyldHdr, cacheStart };
++  int res = dyld_shared_cache_iterate_text ( uuid, &cb );
++  CHECK_EQ(res, 0);
++  return dyldHdr.forwarding->dyldHdr_cp;
++}
++#endif
++
+ const mach_header *get_dyld_hdr() {
+   if (!dyld_hdr) {
+     // On macOS 13+, dyld itself has moved into the shared cache.  Looking it up
+     // via vm_region_recurse_64() causes spins/hangs/crashes.
+-    // FIXME: find a way to do this compatible with GCC.
+     if (GetMacosAlignedVersion() >= MacosVersion(13, 0)) {
++      uuid_t uuid;
++      if (!_dyld_get_shared_cache_uuid(uuid))
++        VReport(1, "Failed get the shared cache on macOS 13+\n");
++      else
++        dyld_hdr = GetDyldImageHeaderViaSharedCache(uuid);
++      if (!dyld_hdr) {
+         VReport(1,
+-                "looking up the dyld image header in the shared cache on "
+-                "macOS 13+ is not yet supported.  Falling back to "
++                "Failed to lookup the dyld image header in the shared cache on "
++                "macOS 13+ (or no shared cache in use).  Falling back to "
+                 "lookup via vm_region_recurse_64().\n");
+         dyld_hdr = GetDyldImageHeaderViaVMRegion();
++      }
+     } else {
+       dyld_hdr = GetDyldImageHeaderViaVMRegion();
+     }
+@@ -213,6 +372,13 @@ static bool NextSegmentLoad(MemoryMapped
+   layout_data->current_load_cmd_count--;
+   if (((const load_command *)lc)->cmd == kLCSegment) {
+     const SegmentCommand* sc = (const SegmentCommand *)lc;
++    if (internal_strcmp(sc->segname, "__LINKEDIT") == 0) {
++      // The LINKEDIT sections are for internal linker use, and may alias
++      // with the LINKEDIT section for other modules. (If we included them,
++      // our memory map would contain overlappping sections.)
++      return false;
++    }
++
+     uptr base_virt_addr, addr_mask;
+     if (layout_data->current_image == kDyldImageIdx) {
+       base_virt_addr = (uptr)get_dyld_hdr();
+@@ -281,6 +447,8 @@ ModuleArch ModuleArchFromCpuType(cpu_typ
+       CHECK(0 && "Invalid subtype of ARM");
+       return kModuleArchUnknown;
+     case CPU_TYPE_ARM64:
++      if (cpusubtype == CPU_SUBTYPE_ARM64E)
++        return kModuleArchARM64E;
+       return kModuleArchARM64;
+     default:
+       CHECK(0 && "Invalid CPU type");



Home | Main Index | Thread Index | Old Index