pkgsrc-Changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
CVS commit: pkgsrc/lang/gcc15-gnat
Module Name: pkgsrc
Committed By: dkazankov
Date: Sat Jun 6 06:15:50 UTC 2026
Modified Files:
pkgsrc/lang/gcc15-gnat: Makefile buildlink3.mk distinfo
pkgsrc/lang/gcc15-gnat/patches: patch-gcc_ada_Makefile.rtl
patch-gcc_ada_libgnarl_s-osinte____netbsd.ads
Added Files:
pkgsrc/lang/gcc15-gnat/patches:
patch-gcc_ada_libgnarl_s-taprop____netbsd.adb
patch-gcc_ada_libgnat_g-socthi____bsd.adb
patch-gcc_ada_libgnat_g-socthi____bsd.ads patch-gcc_config.gcc
patch-gcc_config_netbsd.h patch-libgcc_config.host
patch-libgcc_enable-execute-stack-mprotect.c
Removed Files:
pkgsrc/lang/gcc15-gnat/patches:
patch-gcc_ada_libgnarl_s-taprop____posix.adb
Log Message:
gcc15-gnat: update to 15.2.0nb2
* Update common patches from upstream gcc15 package
* Update libgnat BSD socket implementation
* Improve using builtin binutils version on NetBSD 11
* Fix tasking implementation on NetBSD
- now GNAT does not use alternate stack for tasking
on NetBSD: see pthread CAVEATS
- add affinity/ceiling support
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 pkgsrc/lang/gcc15-gnat/Makefile
cvs rdiff -u -r1.4 -r1.5 pkgsrc/lang/gcc15-gnat/buildlink3.mk
cvs rdiff -u -r1.3 -r1.4 pkgsrc/lang/gcc15-gnat/distinfo
cvs rdiff -u -r1.1 -r1.2 \
pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_Makefile.rtl \
pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnarl_s-osinte____netbsd.ads
cvs rdiff -u -r0 -r1.1 \
pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnarl_s-taprop____netbsd.adb \
pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnat_g-socthi____bsd.adb \
pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnat_g-socthi____bsd.ads \
pkgsrc/lang/gcc15-gnat/patches/patch-gcc_config.gcc \
pkgsrc/lang/gcc15-gnat/patches/patch-gcc_config_netbsd.h \
pkgsrc/lang/gcc15-gnat/patches/patch-libgcc_config.host \
pkgsrc/lang/gcc15-gnat/patches/patch-libgcc_enable-execute-stack-mprotect.c
cvs rdiff -u -r1.1 -r0 \
pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnarl_s-taprop____posix.adb
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-gnat/Makefile
diff -u pkgsrc/lang/gcc15-gnat/Makefile:1.6 pkgsrc/lang/gcc15-gnat/Makefile:1.7
--- pkgsrc/lang/gcc15-gnat/Makefile:1.6 Mon Oct 20 14:26:20 2025
+++ pkgsrc/lang/gcc15-gnat/Makefile Sat Jun 6 06:15:50 2026
@@ -1,8 +1,8 @@
-# $NetBSD: Makefile,v 1.6 2025/10/20 14:26:20 dkazankov Exp $
+# $NetBSD: Makefile,v 1.7 2026/06/06 06:15:50 dkazankov Exp $
DISTNAME= gcc-${PKGVERSION_NOREV}
PKGNAME= gcc15-gnat-15.2.0
-PKGREVISION= 1
+PKGREVISION= 2
CATEGORIES= lang
MASTER_SITES= ${MASTER_SITE_GNU:=gcc/${DISTNAME}/}
EXTRACT_SUFX= .tar.xz
@@ -93,24 +93,39 @@ BUILD_DEFS+= GCC_TARGET_MACHINE
# Use C preprocessed symbols on NetBSD
.if ${OPSYS} == "NetBSD"
-SUBST_CLASSES+= patch1
-SUBST_MESSAGE.patch1= Replace nanosleep, gettimeofday in ${SUBST_FILES.patch1}
-SUBST_STAGE.patch1= pre-configure
-SUBST_FILES.patch1= gcc/ada/libgnat/s-osprim__posix.adb
-SUBST_SED.patch1= -e "s,\"nanosleep\",\"__gnat_nanosleep\","
-SUBST_SED.patch1+= -e "s,\"gettimeofday\",\"__gnat_gettimeofday\","
+#SUBST_CLASSES+= patch1
+#SUBST_MESSAGE.patch1= Replace nanosleep, gettimeofday in ${SUBST_FILES.patch1}
+#SUBST_STAGE.patch1= pre-configure
+#SUBST_FILES.patch1= gcc/ada/libgnat/s-osprim__posix.adb
+#SUBST_SED.patch1= -e "s,\"nanosleep\",\"__gnat_nanosleep\","
+#SUBST_SED.patch1+= -e "s,\"gettimeofday\",\"__gnat_gettimeofday\","
SUBST_CLASSES+= patch2
SUBST_MESSAGE.patch2= Replace select with __gnat_select in ${SUBST_FILES.patch2}
SUBST_STAGE.patch2= pre-configure
-SUBST_FILES.patch2= gcc/ada/libgnat/g-socthi.ads
+SUBST_FILES.patch2= gcc/ada/libgnat/g-socthi__bsd.ads
SUBST_SED.patch2= -e "s,\"select\",\"__gnat_select\","
SUBST_CLASSES+= patch3
SUBST_MESSAGE.patch3= Replace socket with __gnat_socket in ${SUBST_FILES.patch3}
SUBST_STAGE.patch3= pre-configure
-SUBST_FILES.patch3= gcc/ada/libgnat/g-socthi.adb
+SUBST_FILES.patch3= gcc/ada/libgnat/g-socthi__bsd.adb
SUBST_SED.patch3= -e "s,\"socket\",\"__gnat_socket\","
+
+SUBST_CLASSES+= patch4
+SUBST_MESSAGE.patch4= Replace nanosleep, clock_gettime in ${SUBST_FILES.patch4}
+SUBST_STAGE.patch4= pre-configure
+SUBST_FILES.patch4+= gcc/ada/libgnat/s-osprim__posix2008.adb
+SUBST_SED.patch4= -e "s,\"nanosleep\",\"__gnat_nanosleep\","
+SUBST_SED.patch4+= -e "s,\"clock_gettime\",\"__gnat_clock_gettime\","
+
+.if ${OPSYS_VERSION} > 109999
+SUBST_CLASSES+= patch5
+SUBST_MESSAGE.patch5= Lower default stack size in ${SUBST_FILES.patch5}
+SUBST_STAGE.patch5= pre-configure
+SUBST_FILES.patch5+= gcc/ada/libgnat/s-parame__posix2008.ads
+SUBST_SED.patch5= -e "s,8_192_000,4_096_000,"
+.endif
.endif
.if ${OS_VARIANT} == "SmartOS"
@@ -226,11 +241,29 @@ MAKE_ENV+= ac_cv_path_SED=${TOOLS_SED}
MAKE_ENV+= lt_cv_path_SED=${TOOLS_SED}
# GCC 15 requires latest binutils
+.if ${OPSYS} == "NetBSD"
+# NetBSD >= 11.0 has it
+.if ${OPSYS_VERSION} > 109999
+CONFIGURE_ARGS+= --with-gnu-ld --with-ld=/usr/bin/ld
+CONFIGURE_ARGS+= --with-gnu-as --with-as=/usr/bin/as
+.else
+BUILDLINK_API_DEPENDS.binutils+= binutils>=2.35
+.include "../../devel/binutils/buildlink3.mk"
+.endif
+.else
+CHECK_BUILTIN.binutils:= yes
+.include "../../devel/binutils/builtin.mk"
+CHECK_BUILTIN.binutils:= no
+.if ${USE_BUILTIN.binutils:tl} == yes
+CONFIGURE_ARGS+= --with-ld=/usr/bin/ld
+CONFIGURE_ARGS+= --with-as=/usr/bin/as
+.else
BUILDLINK_API_DEPENDS.binutils+= binutils>=2.35
.include "../../devel/binutils/buildlink3.mk"
-
CONFIGURE_ARGS+= --with-gnu-ld --with-ld=${PREFIX}/bin/gld
CONFIGURE_ARGS+= --with-gnu-as --with-as=${PREFIX}/bin/gas
+.endif
+.endif
.if ${OPSYS} == "Linux"
# glibc limitations, needs at least -O1
Index: pkgsrc/lang/gcc15-gnat/buildlink3.mk
diff -u pkgsrc/lang/gcc15-gnat/buildlink3.mk:1.4 pkgsrc/lang/gcc15-gnat/buildlink3.mk:1.5
--- pkgsrc/lang/gcc15-gnat/buildlink3.mk:1.4 Sun Oct 19 03:53:33 2025
+++ pkgsrc/lang/gcc15-gnat/buildlink3.mk Sat Jun 6 06:15:50 2026
@@ -1,11 +1,11 @@
-# $NetBSD: buildlink3.mk,v 1.4 2025/10/19 03:53:33 dkazankov Exp $
+# $NetBSD: buildlink3.mk,v 1.5 2026/06/06 06:15:50 dkazankov Exp $
BUILDLINK_TREE+= gcc15-gnat
.if !defined(GCC15_GNAT_BUILDLINK3_MK)
GCC15_GNAT_BUILDLINK3_MK:=
-BUILDLINK_API_DEPENDS.gcc15-gnat+= gcc15-gnat>=15.1.0
+BUILDLINK_API_DEPENDS.gcc15-gnat+= gcc15-gnat>=${_GCC_REQD}
BUILDLINK_ABI_DEPENDS.gcc15-gnat+= gcc15-gnat>=15.2.0
BUILDLINK_PKGSRCDIR.gcc15-gnat?= ../../lang/gcc15-gnat
BUILDLINK_DEPMETHOD.gcc15-gnat?= build
Index: pkgsrc/lang/gcc15-gnat/distinfo
diff -u pkgsrc/lang/gcc15-gnat/distinfo:1.3 pkgsrc/lang/gcc15-gnat/distinfo:1.4
--- pkgsrc/lang/gcc15-gnat/distinfo:1.3 Sun Oct 19 03:53:33 2025
+++ pkgsrc/lang/gcc15-gnat/distinfo Sat Jun 6 06:15:50 2026
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.3 2025/10/19 03:53:33 dkazankov Exp $
+$NetBSD: distinfo,v 1.4 2026/06/06 06:15:50 dkazankov Exp $
BLAKE2s (gcc-15.2.0.tar.xz) = ee9b2705b03ef8e6b5a41cf523dad26dcdaa8047be3743121b1673ce2fcc8832
SHA512 (gcc-15.2.0.tar.xz) = 89047a2e07bd9da265b507b516ed3635adb17491c7f4f67cf090f0bd5b3fc7f2ee6e4cc4008beef7ca884b6b71dffe2bb652b21f01a702e17b468cca2d10b2de
@@ -10,17 +10,20 @@ BLAKE2s (isl-0.24.tar.xz) = a3013b0d39b7
SHA512 (isl-0.24.tar.xz) = ff6bdcff839e1cd473f2a0c1e4dd4a3612ec6fee4544ccbc62b530a7248db2cf93b4b99bf493a86ddf2aba00e768927265d5d411f92061ea85fd7929073428e8
Size (isl-0.24.tar.xz) = 1930956 bytes
SHA1 (patch-gcc_Makefile.in) = a3976de1679978fb7598fd5777ea1ab4bb596896
-SHA1 (patch-gcc_ada_Makefile.rtl) = 376acf3e0b26bf07d0e83c54437403945de604f0
+SHA1 (patch-gcc_ada_Makefile.rtl) = be9ee48d3466eb9c64fdef05f717c4e3614fd43e
SHA1 (patch-gcc_ada_adaint.c) = 62411073bac71aa96d12c69a0b02a4206401f852
SHA1 (patch-gcc_ada_adaint.h) = cc0f2733b97d92c5fbaa21b70e413f7bb5dc9b82
SHA1 (patch-gcc_ada_cstreams.c) = 10b181c24c73cb2523deed6bb6d9c6b41404e9e0
SHA1 (patch-gcc_ada_libgnarl_s-osinte____netbsd.adb) = 66bafa4b027e810f78b67eeee5510fa8bc897359
-SHA1 (patch-gcc_ada_libgnarl_s-osinte____netbsd.ads) = 81dfcba01ba4c4931b974cb00af27f5c7853a0d9
-SHA1 (patch-gcc_ada_libgnarl_s-taprop____posix.adb) = 492d40ef2406500f5913687bfe5c9a6e081459f5
+SHA1 (patch-gcc_ada_libgnarl_s-osinte____netbsd.ads) = 6289d3871f588e96b58826d0dd710f6012e0480c
+SHA1 (patch-gcc_ada_libgnarl_s-taprop____netbsd.adb) = 7cc1536eab6c95fa6a21b40588af17e96c507875
+SHA1 (patch-gcc_ada_libgnat_g-socthi____bsd.adb) = 993778f3baf95b894249661ec7312dba249c36cf
+SHA1 (patch-gcc_ada_libgnat_g-socthi____bsd.ads) = 05c875a6e475102c3ff969008682e7d89bd49f17
SHA1 (patch-gcc_ada_s-oscons-tmplt.c) = baecf8c28e267b2d2e7e1e7943eabd96bf87f411
SHA1 (patch-gcc_ada_sysdep.c) = f227b82e81b551f80858be26563173949b2f4c85
SHA1 (patch-gcc_ada_terminals.c) = b603d018fabb843cc68fa13caee307d48b0e9b62
SHA1 (patch-gcc_ada_tracebak.c) = 4c80984e086debe6131030a8fed28f9d302bffe4
+SHA1 (patch-gcc_config.gcc) = 65126c56f0cd9027f66b5f677773dfa9973b451c
SHA1 (patch-gcc_config.host) = bf95dd21bfdf79d173e745fbd35c9bb99fdf4087
SHA1 (patch-gcc_config_aarch64_aarch64-netbsd.h) = abf19e2445bce1773162bddef16cd7f41eb36827
SHA1 (patch-gcc_config_arm_arm.h) = abf73b91e91f791cf13b915c9613473ae6411a14
@@ -29,6 +32,7 @@ SHA1 (patch-gcc_config_arm_elf.h) = 46b8
SHA1 (patch-gcc_config_arm_netbsd-eabi.h) = ae9b0523165e512f2b1644ec63dd7cab41294d4f
SHA1 (patch-gcc_config_arm_netbsd-elf.h) = 107a79e40d42be0fa1e21e8ee50de66f30e42bfe
SHA1 (patch-gcc_config_i386_t-netbsd64) = 914b4d2fd65f5e46681aa2ea592d0bc75299f09a
+SHA1 (patch-gcc_config_netbsd.h) = ada05409eacb33bc1e7a659f3090f2f43551a35d
SHA1 (patch-gcc_configure) = 72983cd72129a920ec8123ab52f66026df909782
SHA1 (patch-gcc_tree.h) = 402c23ae02a6d50d0899baa7e32205e3292f1eca
SHA1 (patch-gnattools_configure) = ca592eb0ff40d7103ed69370b34a55de43ba6b09
@@ -36,7 +40,9 @@ SHA1 (patch-isl_configure) = a6295c509bd
SHA1 (patch-libcody_configure) = 361fa471f6afb578782322586395faa8f4e9a40c
SHA1 (patch-libffi_configure) = b7e3ac7febb98e789d7b662bd2e80edae61345a1
SHA1 (patch-libffi_testsuite_libffi.call_float2.c) = 89e2dd6aaf2c1f75726f02362d8a8bf7178694ea
+SHA1 (patch-libgcc_config.host) = c9ea8bda0e6a1a8c4c39e4b8320a34b86e1da278
SHA1 (patch-libgcc_crtstuff.c) = c5b079a2bc84b3b2e85a73a6631569d84aca9e2c
+SHA1 (patch-libgcc_enable-execute-stack-mprotect.c) = 9cec951183f5092d14d7736f73f50523cdba7592
SHA1 (patch-libgomp_configure.tgt) = ba20fd420b682ccf558832eab38a5f2acce5d176
SHA1 (patch-libquadmath_printf_quadmath-printf.c) = 78e09f1e6d61ee57cee83275093cf46b2335d204
SHA1 (patch-libquadmath_strtod_strtod__l.c) = 6142c10d34174174cce7f06c37eab04dc431b2dc
Index: pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_Makefile.rtl
diff -u pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_Makefile.rtl:1.1 pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_Makefile.rtl:1.2
--- pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_Makefile.rtl:1.1 Thu Jul 17 05:00:17 2025
+++ pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_Makefile.rtl Sat Jun 6 06:15:50 2026
@@ -1,151 +1,88 @@
-$NetBSD: patch-gcc_ada_Makefile.rtl,v 1.1 2025/07/17 05:00:17 dkazankov Exp $
+$NetBSD: patch-gcc_ada_Makefile.rtl,v 1.2 2026/06/06 06:15:50 dkazankov Exp $
Add NetBSD as a target and generate the required files correctly.
+Do not use alternate stack due to limitations in the current pthread
+implementation https://man.netbsd.org/pthread.3 (CAVEATS)
---- gcc/ada/Makefile.rtl.orig 2025-04-25 08:18:00.000000000 +0000
+--- gcc/ada/Makefile.rtl.orig 2025-08-08 09:51:40.100341900 +0300
+++ gcc/ada/Makefile.rtl
-@@ -1991,6 +1991,151 @@
+@@ -1992,6 +1992,86 @@
endif
endif
-+# x86 NetBSD
++# NetBSD
+ifeq ($(SELECTED_PAIRS),PAIRS_NONE)
-+ifeq ($(strip $(filter-out %86 netbsd%,$(target_cpu) $(target_os))),)
-+
-+ SELECTED_PAIRS=x86-netbsd
-+
-+ LIBGNAT_TARGET_PAIRS = \
-+ a-intnam.ads<libgnarl/a-intnam__bsd.ads \
-+ s-inmaop.adb<libgnarl/s-inmaop__posix.adb \
-+ s-intman.adb<libgnarl/s-intman__posix.adb \
-+ s-mudido.adb<libgnarl/s-mudido__affinity.adb \
-+ s-osinte.adb<libgnarl/s-osinte__netbsd.adb \
-+ s-osinte.ads<libgnarl/s-osinte__netbsd.ads \
-+ s-oslock.ads<libgnat/s-oslock__posix.ads \
-+ s-osprim.adb<libgnat/s-osprim__posix.adb \
-+ s-taprop.adb<libgnarl/s-taprop__posix.adb \
-+ s-taspri.ads<libgnarl/s-taspri__posix.ads \
-+ s-tpopsp.adb<libgnarl/s-tpopsp__posix.adb \
-+ $(TRASYM_DWARF_UNIX_PAIRS) \
-+ $(ATOMICS_TARGET_PAIRS) \
-+ $(X86_TARGET_PAIRS) \
-+ system.ads<libgnat/system-freebsd.ads
-+
-+ GNATLIB_SHARED = gnatlib-shared-dual
-+
-+ EXTRA_GNATRTL_NONTASKING_OBJS += g-sse.o g-ssvety.o
-+ EXTRA_GNATRTL_NONTASKING_OBJS += $(TRASYM_DWARF_UNIX_OBJS)
-+
-+ EH_MECHANISM=-gcc
-+ THREADSLIB= -lpthread -lrt
-+ GMEM_LIB = gmemlib
-+ LIBRARY_VERSION := $(LIB_VERSION)
-+ MISCLIB = -lutil
-+endif
-+endif
-+
-+# x86-64 NetBSD
-+ifeq ($(SELECTED_PAIRS),PAIRS_NONE)
-+ifeq ($(strip $(filter-out %86_64 netbsd%,$(target_cpu) $(target_os))),)
-+
-+ SELECTED_PAIRS=x86_64-netbsd
-+
-+ LIBGNAT_TARGET_PAIRS = \
-+ a-intnam.ads<libgnarl/a-intnam__bsd.ads \
-+ s-inmaop.adb<libgnarl/s-inmaop__posix.adb \
-+ s-intman.adb<libgnarl/s-intman__posix.adb \
-+ s-mudido.adb<libgnarl/s-mudido__affinity.adb \
-+ s-osinte.adb<libgnarl/s-osinte__netbsd.adb \
-+ s-osinte.ads<libgnarl/s-osinte__netbsd.ads \
-+ s-oslock.ads<libgnat/s-oslock__posix.ads \
-+ s-osprim.adb<libgnat/s-osprim__posix.adb \
-+ s-taprop.adb<libgnarl/s-taprop__posix.adb \
-+ s-taspri.ads<libgnarl/s-taspri__posix.ads \
-+ s-tpopsp.adb<libgnarl/s-tpopsp__posix.adb \
-+ $(TRASYM_DWARF_UNIX_PAIRS) \
-+ $(ATOMICS_TARGET_PAIRS) \
-+ $(X86_64_TARGET_PAIRS) \
-+ $(GNATRTL_128BIT_PAIRS) \
-+ system.ads<libgnat/system-freebsd.ads
-+
-+ GNATLIB_SHARED = gnatlib-shared-dual
-+
-+ EXTRA_GNATRTL_NONTASKING_OBJS += g-sse.o g-ssvety.o
-+ EXTRA_GNATRTL_NONTASKING_OBJS += $(TRASYM_DWARF_UNIX_OBJS)
-+ EXTRA_GNATRTL_NONTASKING_OBJS += $(GNATRTL_128BIT_OBJS)
-+
-+ EH_MECHANISM=-gcc
-+ THREADSLIB= -lpthread -lrt
-+ GMEM_LIB = gmemlib
-+ LIBRARY_VERSION := $(LIB_VERSION)
-+ MISCLIB = -lutil
-+endif
-+endif
-+
-+# arm NetBSD
-+ifeq ($(SELECTED_PAIRS),PAIRS_NONE)
-+ifeq ($(strip $(filter-out %arm netbsd%,$(target_cpu) $(target_os))),)
-+
-+ SELECTED_PAIRS=arm-netbsd
-+
-+ LIBGNAT_TARGET_PAIRS = \
-+ a-intnam.ads<libgnarl/a-intnam__bsd.ads \
-+ s-inmaop.adb<libgnarl/s-inmaop__posix.adb \
-+ s-intman.adb<libgnarl/s-intman__posix.adb \
-+ s-mudido.adb<libgnarl/s-mudido__affinity.adb \
-+ s-osinte.adb<libgnarl/s-osinte__netbsd.adb \
-+ s-osinte.ads<libgnarl/s-osinte__netbsd.ads \
-+ s-oslock.ads<libgnat/s-oslock__posix.ads \
-+ s-osprim.adb<libgnat/s-osprim__posix.adb \
-+ s-taprop.adb<libgnarl/s-taprop__posix.adb \
-+ s-taspri.ads<libgnarl/s-taspri__posix.ads \
-+ s-tpopsp.adb<libgnarl/s-tpopsp__posix.adb \
-+ $(ATOMICS_TARGET_PAIRS) \
-+ $(ATOMICS_BUILTINS_TARGET_PAIRS) \
-+ system.ads<libgnat/system-freebsd.ads
-+
-+ GNATLIB_SHARED = gnatlib-shared-dual
-+
-+ EH_MECHANISM=-arm
-+ THREADSLIB= -lpthread -lrt
-+ GMEM_LIB = gmemlib
-+ LIBRARY_VERSION := $(LIB_VERSION)
-+ MISCLIB = -lutil
-+endif
-+endif
-+
-+# aarch64 NetBSD
-+ifeq ($(SELECTED_PAIRS),PAIRS_NONE)
-+ifeq ($(strip $(filter-out %aarch64 netbsd%,$(target_cpu) $(target_os))),)
-+
-+ SELECTED_PAIRS=aarch64-netbsd
++ifeq ($(strip $(filter-out netbsd%,$(target_os))),)
+
++ SELECTED_PAIRS=netbsd
++
+ LIBGNAT_TARGET_PAIRS = \
+ a-intnam.ads<libgnarl/a-intnam__bsd.ads \
-+ a-nallfl.ads<libgnat/a-nallfl__wraplf.ads \
-+ s-dorepr.adb<libgnat/s-dorepr__fma.adb \
+ s-inmaop.adb<libgnarl/s-inmaop__posix.adb \
+ s-intman.adb<libgnarl/s-intman__posix.adb \
+ s-mudido.adb<libgnarl/s-mudido__affinity.adb \
+ s-osinte.adb<libgnarl/s-osinte__netbsd.adb \
+ s-osinte.ads<libgnarl/s-osinte__netbsd.ads \
+ s-oslock.ads<libgnat/s-oslock__posix.ads \
-+ s-osprim.adb<libgnat/s-osprim__posix.adb \
-+ s-taprop.adb<libgnarl/s-taprop__posix.adb \
-+ s-taspri.ads<libgnarl/s-taspri__posix.ads \
-+ s-tpopsp.adb<libgnarl/s-tpopsp__posix.adb \
-+ $(TRASYM_DWARF_UNIX_PAIRS) \
++ s-parame.ads<libgnat/s-parame__posix2008.ads \
++ s-osprim.adb<libgnat/s-osprim__posix2008.adb \
++ s-taprop.adb<libgnarl/s-taprop__netbsd.adb \
++ s-taspri.ads<libgnarl/s-taspri__posix-noaltstack.ads \
++ s-tpopsp.adb<libgnarl/s-tpopsp__posix-foreign.adb \
++ g-socthi.ads<libgnat/g-socthi__bsd.ads \
++ g-socthi.adb<libgnat/g-socthi__bsd.adb \
+ $(ATOMICS_TARGET_PAIRS) \
-+ $(ATOMICS_BUILTINS_TARGET_PAIRS) \
-+ $(GNATRTL_128BIT_PAIRS) \
+ system.ads<libgnat/system-freebsd.ads
+
-+ EXTRA_GNATRTL_NONTASKING_OBJS = $(GNATRTL_128BIT_OBJS)
-+ EXTRA_GNATRTL_NONTASKING_OBJS += $(TRASYM_DWARF_UNIX_OBJS)
++ ifeq ($(strip $(filter-out %86, $(target_cpu))),)
++ SELECTED_PAIRS=x86-netbsd
++
++ LIBGNAT_TARGET_PAIRS += \
++ $(TRASYM_DWARF_UNIX_PAIRS) \
++ $(X86_TARGET_PAIRS)
++
++ EXTRA_GNATRTL_NONTASKING_OBJS += g-sse.o g-ssvety.o
++ EXTRA_GNATRTL_NONTASKING_OBJS += $(TRASYM_DWARF_UNIX_OBJS)
++ endif
++ ifeq ($(strip $(filter-out %86_64, $(target_cpu))),)
++ SELECTED_PAIRS=x86_64-netbsd
++
++ LIBGNAT_TARGET_PAIRS += \
++ $(TRASYM_DWARF_UNIX_PAIRS) \
++ $(X86_64_TARGET_PAIRS) \
++ $(GNATRTL_128BIT_PAIRS)
++
++ EXTRA_GNATRTL_NONTASKING_OBJS += g-sse.o g-ssvety.o
++ EXTRA_GNATRTL_NONTASKING_OBJS += $(TRASYM_DWARF_UNIX_OBJS)
++ EXTRA_GNATRTL_NONTASKING_OBJS += $(GNATRTL_128BIT_OBJS)
++ endif
++ ifeq ($(strip $(filter-out %arm, $(target_cpu))),)
++ SELECTED_PAIRS=arm-netbsd
++
++ LIBGNAT_TARGET_PAIRS += \
++ $(ATOMICS_BUILTINS_TARGET_PAIRS)
++ endif
++ ifeq ($(strip $(filter-out %aarch64, $(target_cpu))),)
++ SELECTED_PAIRS=aarch64-netbsd
++
++ LIBGNAT_TARGET_PAIRS += \
++ a-nallfl.ads<libgnat/a-nallfl__wraplf.ads \
++ s-dorepr.adb<libgnat/s-dorepr__fma.adb \
++ $(TRASYM_DWARF_UNIX_PAIRS) \
++ $(ATOMICS_BUILTINS_TARGET_PAIRS) \
++ $(GNATRTL_128BIT_PAIRS)
++
++ EXTRA_GNATRTL_NONTASKING_OBJS += $(GNATRTL_128BIT_OBJS)
++ EXTRA_GNATRTL_NONTASKING_OBJS += $(TRASYM_DWARF_UNIX_OBJS)
++ endif
+
+ GNATLIB_SHARED = gnatlib-shared-dual
+
-+ EH_MECHANISM=-gcc
++ ifeq ($(strip $(filter-out %arm, $(target_cpu))),)
++ EH_MECHANISM=-arm
++ else
++ EH_MECHANISM=-gcc
++ endif
+ THREADSLIB= -lpthread -lrt
+ GMEM_LIB = gmemlib
+ LIBRARY_VERSION := $(LIB_VERSION)
Index: pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnarl_s-osinte____netbsd.ads
diff -u pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnarl_s-osinte____netbsd.ads:1.1 pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnarl_s-osinte____netbsd.ads:1.2
--- pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnarl_s-osinte____netbsd.ads:1.1 Thu Jul 17 05:00:17 2025
+++ pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnarl_s-osinte____netbsd.ads Sat Jun 6 06:15:50 2026
@@ -1,10 +1,10 @@
-$NetBSD: patch-gcc_ada_libgnarl_s-osinte____netbsd.ads,v 1.1 2025/07/17 05:00:17 dkazankov Exp $
+$NetBSD: patch-gcc_ada_libgnarl_s-osinte____netbsd.ads,v 1.2 2026/06/06 06:15:50 dkazankov Exp $
Add NetBSD interface
--- /dev/null
+++ gcc/ada/libgnarl/s-osinte__netbsd.ads
-@@ -0,0 +1,640 @@
+@@ -0,0 +1,753 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
@@ -49,6 +49,7 @@ Add NetBSD interface
+with Ada.Unchecked_Conversion;
+
+with Interfaces.C;
++with System.OS_Constants;
+with System.OS_Locks;
+with System.Parameters;
+
@@ -65,8 +66,8 @@ Add NetBSD interface
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
-+ subtype size_t is Interfaces.C.size_t;
+ subtype char_array is Interfaces.C.char_array;
++ subtype size_t is Interfaces.C.size_t;
+ subtype int64 is Interfaces.Integer_64;
+
+ -----------
@@ -86,7 +87,7 @@ Add NetBSD interface
+ -- Signals --
+ -------------
+
-+ Max_Interrupt : constant := 31;
++ Max_Interrupt : constant := 32;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
@@ -123,6 +124,7 @@ Add NetBSD interface
+ SIGINFO : constant := 29; -- information request (NetBSD/FreeBSD)
+ SIGUSR1 : constant := 30; -- user defined signal 1
+ SIGUSR2 : constant := 31; -- user defined signal 2
++ SIGPWR : constant := 32; -- Power fail/restart
+
+ SIGADAABORT : constant := SIGABRT;
+ -- Change this if you want to use another signal for task abort.
@@ -206,7 +208,7 @@ Add NetBSD interface
+ function nanosleep (rqtp, rmtp : access timespec) return int;
+ pragma Import (C, nanosleep, "__gnat_nanosleep");
+
-+ type clockid_t is new unsigned;
++ type clockid_t is new int;
+
+ function clock_getres
+ (clock_id : clockid_t;
@@ -285,9 +287,11 @@ Add NetBSD interface
+ subtype Thread_Id is pthread_t;
+
+ subtype pthread_mutex_t is System.OS_Locks.pthread_mutex_t;
++ type pthread_rwlock_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
++ type pthread_rwlockattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
@@ -297,9 +301,6 @@ Add NetBSD interface
+ PTHREAD_SCOPE_PROCESS : constant := 0;
+ PTHREAD_SCOPE_SYSTEM : constant := 1;
+
-+ subtype pthread_rwlock_t is pthread_mutex_t;
-+ subtype pthread_rwlockattr_t is pthread_mutexattr_t;
-+
+ -----------
+ -- Stack --
+ -----------
@@ -334,7 +335,7 @@ Add NetBSD interface
+ -- when Stack_Base_Available is True.
+
+ function Get_Page_Size return int;
-+ pragma Import (C, Get_Page_Size, "_getpagesize");
++ pragma Import (C, Get_Page_Size, "getpagesize");
+ -- Returns the size of a page
+
+ PROT_NONE : constant := 0;
@@ -405,6 +406,32 @@ Add NetBSD interface
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
++ function pthread_rwlockattr_init
++ (attr : access pthread_rwlockattr_t) return int;
++ pragma Import (C, pthread_rwlockattr_init, "pthread_rwlockattr_init");
++
++ function pthread_rwlockattr_destroy
++ (attr : access pthread_rwlockattr_t) return int;
++ pragma Import (C, pthread_rwlockattr_destroy, "pthread_rwlockattr_destroy");
++
++ function pthread_rwlock_init
++ (mutex : access pthread_rwlock_t;
++ attr : access pthread_rwlockattr_t) return int;
++ pragma Import (C, pthread_rwlock_init, "pthread_rwlock_init");
++
++ function pthread_rwlock_destroy
++ (mutex : access pthread_rwlock_t) return int;
++ pragma Import (C, pthread_rwlock_destroy, "pthread_rwlock_destroy");
++
++ function pthread_rwlock_rdlock (mutex : access pthread_rwlock_t) return int;
++ pragma Import (C, pthread_rwlock_rdlock, "pthread_rwlock_rdlock");
++
++ function pthread_rwlock_wrlock (mutex : access pthread_rwlock_t) return int;
++ pragma Import (C, pthread_rwlock_wrlock, "pthread_rwlock_wrlock");
++
++ function pthread_rwlock_unlock (mutex : access pthread_rwlock_t) return int;
++ pragma Import (C, pthread_rwlock_unlock, "pthread_rwlock_unlock");
++
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
@@ -607,6 +634,45 @@ Add NetBSD interface
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
++ ----------------
++ -- Extensions --
++ ----------------
++
++ type cpuset_t is private;
++
++ function pthread_setaffinity_np
++ (thread : pthread_t;
++ cpusetsize : size_t;
++ cpuset : access cpuset_t) return int;
++ pragma Import (C, pthread_setaffinity_np, "pthread_setaffinity_np");
++
++ ----------------
++ -- CPU sets --
++ ----------------
++
++ subtype cpuid_t is unsigned_long;
++
++ function cpuset_create return access cpuset_t;
++ pragma Import (C, cpuset_create, "_cpuset_create");
++
++ procedure cpuset_destroy (set : access cpuset_t);
++ pragma Import (C, cpuset_destroy, "_cpuset_destroy");
++
++ procedure cpuset_zero (set : access cpuset_t);
++ pragma Import (C, cpuset_zero, "_cpuset_zero");
++
++ function cpuset_set (cpu : cpuid_t; set : access cpuset_t) return int;
++ pragma Import (C, cpuset_set, "_cpuset_set");
++
++ function cpuset_clr (cpu : cpuid_t; set : access cpuset_t) return int;
++ pragma Import (C, cpuset_clr, "_cpuset_clr");
++
++ function cpuset_isset (cpu : cpuid_t; set : access cpuset_t) return int;
++ pragma Import (C, cpuset_isset, "_cpuset_isset");
++
++ function cpuset_size (set : access cpuset_t) return size_t;
++ pragma Import (C, cpuset_size, "_cpuset_size");
++
+private
+
+ type sigset_t is array (1 .. 4) of unsigned;
@@ -638,10 +704,57 @@ Add NetBSD interface
+ pragma Convention (C, timespec);
+
+ type pthread_t is new System.Address;
-+ type pthread_attr_t is new System.Address;
-+ type pthread_mutexattr_t is new System.Address;
-+ type pthread_cond_t is new System.Address;
-+ type pthread_condattr_t is new System.Address;
+ type pthread_key_t is new int;
+
++ type pthread_attr_t is record
++ Data : char_array (1 .. OS_Constants.PTHREAD_ATTR_SIZE);
++ end record;
++ pragma Convention (C, pthread_attr_t);
++ for pthread_attr_t'Alignment use
++ Integer'Max (Interfaces.C.unsigned'Alignment,
++ System.Address'Alignment);
++
++ type pthread_condattr_t is record
++ Data : char_array (1 .. OS_Constants.PTHREAD_CONDATTR_SIZE);
++ end record;
++ pragma Convention (C, pthread_condattr_t);
++ for pthread_condattr_t'Alignment use
++ Integer'Max (Interfaces.C.unsigned'Alignment,
++ System.Address'Alignment);
++
++ type pthread_mutexattr_t is record
++ Data : char_array (1 .. OS_Constants.PTHREAD_MUTEXATTR_SIZE);
++ end record;
++ pragma Convention (C, pthread_mutexattr_t);
++ for pthread_mutexattr_t'Alignment use
++ Integer'Max (Interfaces.C.unsigned'Alignment,
++ System.Address'Alignment);
++
++ type pthread_rwlockattr_t is record
++ Data : char_array (1 .. OS_Constants.PTHREAD_RWLOCKATTR_SIZE);
++ end record;
++ pragma Convention (C, pthread_rwlockattr_t);
++ for pthread_rwlockattr_t'Alignment use
++ Integer'Max (Interfaces.C.unsigned'Alignment,
++ System.Address'Alignment);
++
++ type pthread_rwlock_t is record
++ Data : char_array (1 .. OS_Constants.PTHREAD_RWLOCK_SIZE);
++ end record;
++ pragma Convention (C, pthread_rwlock_t);
++ for pthread_rwlock_t'Alignment use
++ Integer'Max (Interfaces.C.unsigned'Alignment,
++ System.Address'Alignment);
++
++ type pthread_cond_t is record
++ Data : char_array (1 .. OS_Constants.PTHREAD_COND_SIZE);
++ end record;
++ pragma Convention (C, pthread_cond_t);
++ for pthread_cond_t'Alignment use
++ Integer'Max (Interfaces.C.unsigned'Alignment,
++ System.Address'Alignment);
++
++ type cpuset_t is null record;
++ pragma Convention (C, cpuset_t);
++
+end System.OS_Interface;
Added files:
Index: pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnarl_s-taprop____netbsd.adb
diff -u /dev/null pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnarl_s-taprop____netbsd.adb:1.1
--- /dev/null Sat Jun 6 06:15:50 2026
+++ pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnarl_s-taprop____netbsd.adb Sat Jun 6 06:15:50 2026
@@ -0,0 +1,1506 @@
+$NetBSD: patch-gcc_ada_libgnarl_s-taprop____netbsd.adb,v 1.1 2026/06/06 06:15:50 dkazankov Exp $
+
+Add NetBSD interface
+This is mostly a POSIX version with some imrovements taken from the Linux
+version
+
+--- /dev/null
++++ gcc/ada/libgnarl/s-taprop__netbsd.adb
+@@ -0,0 +1,1497 @@
++------------------------------------------------------------------------------
++-- --
++-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
++-- --
++-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
++-- --
++-- B o d y --
++-- --
++-- Copyright (C) 1992-2025, Free Software Foundation, Inc. --
++-- --
++-- GNARL is free software; you can redistribute it and/or modify it under --
++-- terms of the GNU General Public License as published by the Free Soft- --
++-- ware Foundation; either version 3, or (at your option) any later ver- --
++-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
++-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
++-- or FITNESS FOR A PARTICULAR PURPOSE. --
++-- --
++-- As a special exception under Section 7 of GPL version 3, you are granted --
++-- additional permissions described in the GCC Runtime Library Exception, --
++-- version 3.1, as published by the Free Software Foundation. --
++-- --
++-- You should have received a copy of the GNU General Public License and --
++-- a copy of the GCC Runtime Library Exception along with this program; --
++-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
++-- <http://www.gnu.org/licenses/>. --
++-- --
++-- GNARL was developed by the GNARL team at Florida State University. --
++-- Extensive contributions were provided by Ada Core Technologies, Inc. --
++-- --
++------------------------------------------------------------------------------
++
++-- This is a POSIX-like version of this package
++
++-- This package contains all the GNULL primitives that interface directly with
++-- the underlying OS.
++
++-- Note: this file can only be used for POSIX compliant systems that implement
++-- SCHED_FIFO and Ceiling Locking correctly.
++
++-- For configurations where SCHED_FIFO and priority ceiling are not a
++-- requirement, this file can also be used (e.g AiX threads)
++
++with Ada.Unchecked_Conversion;
++
++with Interfaces.C;
++
++with System.Interrupt_Management;
++with System.Multiprocessors;
++with System.OS_Constants;
++with System.OS_Primitives;
++with System.Task_Info;
++with System.Tasking.Debug;
++
++with System.Soft_Links;
++-- We use System.Soft_Links instead of System.Tasking.Initialization
++-- because the later is a higher level package that we shouldn't depend on.
++-- For example when using the restricted run time, it is replaced by
++-- System.Tasking.Restricted.Stages.
++
++package body System.Task_Primitives.Operations is
++
++ package OSC renames System.OS_Constants;
++ package SSL renames System.Soft_Links;
++
++ use System.OS_Interface;
++ use System.OS_Locks;
++ use System.OS_Primitives;
++ use System.Parameters;
++ use System.Tasking;
++ use System.Tasking.Debug;
++
++ use type Interfaces.C.int;
++ use type Interfaces.C.size_t;
++
++ ----------------
++ -- Local Data --
++ ----------------
++
++ -- The followings are logically constants, but need to be initialized
++ -- at run time.
++
++ Single_RTS_Lock : aliased RTS_Lock;
++ -- This is a lock to allow only one thread of control in the RTS at
++ -- a time; it is used to execute in mutual exclusion from all other tasks.
++ -- Used to protect All_Tasks_List
++
++ Environment_Task_Id : Task_Id;
++ -- A variable to hold Task_Id for the environment task
++
++ Locking_Policy : constant Character;
++ pragma Import (C, Locking_Policy, "__gl_locking_policy");
++ -- Value of the pragma Locking_Policy:
++ -- 'C' for Ceiling_Locking
++ -- 'I' for Inherit_Locking
++ -- ' ' for none.
++
++ Unblocked_Signal_Mask : aliased sigset_t;
++ -- The set of signals that should unblocked in all tasks
++
++ -- The followings are internal configuration constants needed
++
++ Next_Serial_Number : Task_Serial_Number := 100;
++ -- We start at 100, to reserve some special values for
++ -- using in error checking.
++
++ Time_Slice_Val : constant Integer;
++ pragma Import (C, Time_Slice_Val, "__gl_time_slice_val");
++
++ Dispatching_Policy : constant Character;
++ pragma Import (C, Dispatching_Policy, "__gl_task_dispatching_policy");
++
++ Foreign_Task_Elaborated : aliased Boolean := True;
++ -- Used to identified fake tasks (i.e., non-Ada Threads)
++
++ Use_Alternate_Stack : Boolean := Alternate_Stack_Size /= 0;
++ -- Whether to use an alternate signal stack for stack overflows
++
++ Abort_Handler_Installed : Boolean := False;
++ -- True if a handler for the abort signal is installed
++
++ --------------------
++ -- Local Packages --
++ --------------------
++
++ package Specific is
++
++ procedure Initialize (Environment_Task : Task_Id);
++ pragma Inline (Initialize);
++ -- Initialize various data needed by this package
++
++ function Is_Valid_Task return Boolean;
++ pragma Inline (Is_Valid_Task);
++ -- Does executing thread have a TCB?
++
++ procedure Set (Self_Id : Task_Id);
++ pragma Inline (Set);
++ -- Set the self id for the current task
++
++ function Self return Task_Id;
++ pragma Inline (Self);
++ -- Return a pointer to the Ada Task Control Block of the calling task
++
++ end Specific;
++
++ package body Specific is separate;
++ -- The body of this package is target specific
++
++ package Monotonic is
++
++ function Monotonic_Clock return Duration;
++ pragma Inline (Monotonic_Clock);
++ -- Returns an absolute time, represented as an offset relative to some
++ -- unspecified starting point, typically system boot time. This clock
++ -- is not affected by discontinuous jumps in the system time.
++
++ function RT_Resolution return Duration;
++ pragma Inline (RT_Resolution);
++ -- Returns resolution of the underlying clock used to implement RT_Clock
++
++ procedure Timed_Sleep
++ (Self_ID : ST.Task_Id;
++ Time : Duration;
++ Mode : ST.Delay_Modes;
++ Reason : System.Tasking.Task_States;
++ Timedout : out Boolean;
++ Yielded : out Boolean);
++ -- Combination of Sleep (above) and Timed_Delay
++
++ procedure Timed_Delay
++ (Self_ID : ST.Task_Id;
++ Time : Duration;
++ Mode : ST.Delay_Modes);
++ -- Implement the semantics of the delay statement.
++ -- The caller should be abort-deferred and should not hold any locks.
++
++ end Monotonic;
++
++ package body Monotonic is separate;
++
++ ----------------------------------
++ -- ATCB allocation/deallocation --
++ ----------------------------------
++
++ package body ATCB_Allocation is separate;
++ -- The body of this package is shared across several targets
++
++ ---------------------------------
++ -- Support for foreign threads --
++ ---------------------------------
++
++ function Register_Foreign_Thread
++ (Thread : Thread_Id;
++ Sec_Stack_Size : Size_Type := Unspecified_Size) return Task_Id;
++ -- Allocate and initialize a new ATCB for the current Thread. The size of
++ -- the secondary stack can be optionally specified.
++
++ function Register_Foreign_Thread
++ (Thread : Thread_Id;
++ Sec_Stack_Size : Size_Type := Unspecified_Size)
++ return Task_Id is separate;
++
++ -----------------------
++ -- Local Subprograms --
++ -----------------------
++
++ procedure Abort_Handler (Sig : Signal);
++ -- Signal handler used to implement asynchronous abort.
++ -- See also comment before body, below.
++
++ function To_Address is
++ new Ada.Unchecked_Conversion (Task_Id, System.Address);
++
++ function GNAT_pthread_condattr_setup
++ (attr : access pthread_condattr_t) return int;
++ pragma Import (C,
++ GNAT_pthread_condattr_setup, "__gnat_pthread_condattr_setup");
++
++ function Get_Ceiling_Support return Boolean;
++ -- Get the value of the Ceiling_Support constant (see below).
++ -- Note well: If this function or related code is modified, it should be
++ -- tested by hand, because automated testing doesn't exercise it.
++
++ -------------------------
++ -- Get_Ceiling_Support --
++ -------------------------
++
++ function Get_Ceiling_Support return Boolean is
++ Ceiling_Support : Boolean := False;
++ begin
++ if Locking_Policy = 'C' then
++ declare
++ function geteuid return int;
++ pragma Import (C, geteuid, "geteuid");
++ Superuser : constant Boolean := geteuid = 0;
++ begin
++ Ceiling_Support := Superuser;
++ if not Ceiling_Support then
++ declare
++ function sysctlbyname (sname : char_array;
++ oldp : access int;
++ oldlenp : access size_t;
++ newp : access int;
++ newlen : size_t) return int;
++ pragma Import (C, sysctlbyname, "sysctlbyname");
++
++ SName : constant char_array :=
++ Interfaces.C.To_C (
++ "security.models.extensions.user_set_cpu_affinity");
++ pragma Convention (C, SName);
++ Result : int;
++ User_Set_Cpu_Affinity : aliased int;
++ pragma Convention (C, User_Set_Cpu_Affinity);
++ Len : aliased size_t :=
++ User_Set_Cpu_Affinity'Size / System.Storage_Unit;
++ pragma Convention (C, Len);
++ begin
++ Result := sysctlbyname (
++ SName,
++ User_Set_Cpu_Affinity'Unchecked_Access,
++ Len'Unchecked_Access, null, 0);
++ pragma Assert (Result = 0 or else Result = -1);
++ if Result = 0 then
++ Ceiling_Support := User_Set_Cpu_Affinity /= 0;
++ end if;
++ end;
++ end if;
++ end;
++ end if;
++ return Ceiling_Support;
++ end Get_Ceiling_Support;
++
++ pragma Warnings (Off, "non-preelaborable call not allowed*");
++ Ceiling_Support : constant Boolean := Get_Ceiling_Support;
++ pragma Warnings (On, "non-preelaborable call not allowed*");
++ -- True if the locking policy is Ceiling_Locking, and the current process
++ -- has permission to use this policy. The process has permission if it is
++ -- running as 'root', or if the capability was set by the setcap command,
++ -- as in "sudo /sbin/setcap cap_sys_nice=ep exe_file". If it doesn't have
++ -- permission, then a request for Ceiling_Locking is ignored.
++
++ function Initialize_Lock
++ (L : not null access RTS_Lock;
++ Prio : System.Any_Priority) return int;
++ -- Initialize an RTS_Lock with the specified priority
++
++ function Requires_Affinity_Change
++ (Domain : Dispatching_Domain_Access) return Boolean;
++ -- Returns whether a call to pthread_setaffinity_np is required to assign a
++ -- task to Domain.
++
++ -------------------
++ -- Abort_Handler --
++ -------------------
++
++ -- Target-dependent binding of inter-thread Abort signal to the raising of
++ -- the Abort_Signal exception.
++
++ -- The technical issues and alternatives here are essentially the
++ -- same as for raising exceptions in response to other signals
++ -- (e.g. Storage_Error). See code and comments in the package body
++ -- System.Interrupt_Management.
++
++ -- Some implementations may not allow an exception to be propagated out of
++ -- a handler, and others might leave the signal or interrupt that invoked
++ -- this handler masked after the exceptional return to the application
++ -- code.
++
++ -- GNAT exceptions are originally implemented using setjmp()/longjmp(). On
++ -- most UNIX systems, this will allow transfer out of a signal handler,
++ -- which is usually the only mechanism available for implementing
++ -- asynchronous handlers of this kind. However, some systems do not
++ -- restore the signal mask on longjmp(), leaving the abort signal masked.
++
++ procedure Abort_Handler (Sig : Signal) is
++ pragma Unreferenced (Sig);
++
++ T : constant Task_Id := Self;
++ Old_Set : aliased sigset_t;
++
++ Result : int;
++ pragma Warnings (Off, Result);
++
++ begin
++ -- It's not safe to raise an exception when using GCC ZCX mechanism.
++ -- Note that we still need to install a signal handler, since in some
++ -- cases (e.g. shutdown of the Server_Task in System.Interrupts) we
++ -- need to send the Abort signal to a task.
++
++ if ZCX_By_Default then
++ return;
++ end if;
++
++ if T.Deferral_Level = 0
++ and then T.Pending_ATC_Level < T.ATC_Nesting_Level and then
++ not T.Aborting
++ then
++ T.Aborting := True;
++
++ -- Make sure signals used for RTS internal purpose are unmasked
++
++ Result := pthread_sigmask (SIG_UNBLOCK,
++ Unblocked_Signal_Mask'Access, Old_Set'Access);
++ pragma Assert (Result = 0);
++
++ raise Standard'Abort_Signal;
++ end if;
++ end Abort_Handler;
++
++ -----------------
++ -- Stack_Guard --
++ -----------------
++
++ procedure Stack_Guard (T : ST.Task_Id; On : Boolean) is
++ Stack_Base : constant Address := Get_Stack_Base (T.Common.LL.Thread);
++ Page_Size : Address;
++ Res : int;
++
++ begin
++ if Stack_Base_Available then
++
++ -- Compute the guard page address
++
++ Page_Size := Address (Get_Page_Size);
++ Res :=
++ mprotect
++ (Stack_Base - (Stack_Base mod Page_Size) + Page_Size,
++ size_t (Page_Size),
++ prot => (if On then PROT_ON else PROT_OFF));
++ pragma Assert (Res = 0);
++ end if;
++ end Stack_Guard;
++
++ --------------------
++ -- Get_Thread_Id --
++ --------------------
++
++ function Get_Thread_Id (T : ST.Task_Id) return OSI.Thread_Id is
++ begin
++ return T.Common.LL.Thread;
++ end Get_Thread_Id;
++
++ ----------
++ -- Self --
++ ----------
++
++ function Self return Task_Id renames Specific.Self;
++
++ ---------------------
++ -- Initialize_Lock --
++ ---------------------
++
++ -- Note: mutexes and cond_variables needed per-task basis are initialized
++ -- in Initialize_TCB and the Storage_Error is handled. Other mutexes (such
++ -- as RTS_Lock, Memory_Lock...) used in RTS is initialized before any
++ -- status change of RTS. Therefore raising Storage_Error in the following
++ -- routines should be able to be handled safely.
++
++ function Initialize_Lock
++ (L : not null access RTS_Lock;
++ Prio : System.Any_Priority) return int
++ is
++ Attributes : aliased pthread_mutexattr_t;
++ Result, Result_2 : int;
++
++ begin
++ Result := pthread_mutexattr_init (Attributes'Access);
++ pragma Assert (Result = 0 or else Result = ENOMEM);
++
++ if Result = ENOMEM then
++ return Result;
++ end if;
++
++ if Ceiling_Support then
++ Result := pthread_mutexattr_setprotocol
++ (Attributes'Access, PTHREAD_PRIO_PROTECT);
++ pragma Assert (Result = 0);
++
++ Result := pthread_mutexattr_setprioceiling
++ (Attributes'Access, int (Prio));
++ pragma Assert (Result = 0);
++
++ elsif Locking_Policy = 'I' then
++ Result := pthread_mutexattr_setprotocol
++ (Attributes'Access, PTHREAD_PRIO_INHERIT);
++ pragma Assert (Result = 0);
++ end if;
++
++ Result := pthread_mutex_init (L, Attributes'Access);
++ pragma Assert (Result = 0 or else Result = ENOMEM);
++
++ Result_2 := pthread_mutexattr_destroy (Attributes'Access);
++ pragma Assert (Result_2 = 0);
++ return Result;
++ end Initialize_Lock;
++
++ procedure Initialize_Lock
++ (Prio : System.Any_Priority;
++ L : not null access Lock)
++ is
++ begin
++ if Locking_Policy = 'R' then
++ declare
++ RWlock_Attr : aliased pthread_rwlockattr_t;
++ Result, Result_2 : int;
++
++ begin
++ -- Set the rwlock to prefer writer to avoid writers starvation
++
++ Result := pthread_rwlockattr_init (RWlock_Attr'Access);
++ pragma Assert (Result = 0 or else Result = ENOMEM);
++
++ if Result = ENOMEM then
++ raise Storage_Error with "Failed to allocate a lock attribute";
++ end if;
++
++ Result := pthread_rwlock_init (L.RW'Access, RWlock_Attr'Access);
++
++ pragma Assert (Result = 0 or else Result = ENOMEM);
++
++ Result_2 := pthread_rwlockattr_destroy (RWlock_Attr'Access);
++ pragma Assert (Result_2 = 0);
++
++ if Result = ENOMEM then
++ raise Storage_Error with "Failed to allocate a lock";
++ end if;
++ end;
++ else
++ if Initialize_Lock (L.WO'Access, Prio) = ENOMEM then
++ raise Storage_Error with "Failed to allocate a lock";
++ end if;
++ end if;
++ end Initialize_Lock;
++
++ procedure Initialize_Lock
++ (L : not null access RTS_Lock;
++ Level : Lock_Level)
++ is
++ pragma Unreferenced (Level);
++ begin
++ if Initialize_Lock (L, System.Any_Priority'Last) = ENOMEM then
++ raise Storage_Error with "Failed to allocate a lock";
++ end if;
++ end Initialize_Lock;
++
++ -------------------
++ -- Finalize_Lock --
++ -------------------
++
++ procedure Finalize_Lock (L : not null access Lock) is
++ Result : int;
++ begin
++ if Locking_Policy = 'R' then
++ Result := pthread_rwlock_destroy (L.RW'Access);
++ else
++ Result := pthread_mutex_destroy (L.WO'Access);
++ end if;
++ pragma Assert (Result = 0);
++ end Finalize_Lock;
++
++ procedure Finalize_Lock (L : not null access RTS_Lock) is
++ Result : int;
++ begin
++ Result := pthread_mutex_destroy (L);
++ pragma Assert (Result = 0);
++ end Finalize_Lock;
++
++ ----------------
++ -- Write_Lock --
++ ----------------
++
++ procedure Write_Lock
++ (L : not null access Lock; Ceiling_Violation : out Boolean)
++ is
++ Result : int;
++
++ begin
++ if Locking_Policy = 'R' then
++ Result := pthread_rwlock_wrlock (L.RW'Access);
++ else
++ Result := pthread_mutex_lock (L.WO'Access);
++ end if;
++
++ -- The cause of EINVAL is a priority ceiling violation
++
++ Ceiling_Violation := Result = EINVAL;
++ pragma Assert (Result = 0 or else Ceiling_Violation);
++ end Write_Lock;
++
++ procedure Write_Lock (L : not null access RTS_Lock) is
++ Result : int;
++ begin
++ Result := pthread_mutex_lock (L);
++ pragma Assert (Result = 0);
++ end Write_Lock;
++
++ procedure Write_Lock (T : Task_Id) is
++ Result : int;
++ begin
++ Result := pthread_mutex_lock (T.Common.LL.L'Access);
++ pragma Assert (Result = 0);
++ end Write_Lock;
++
++ ---------------
++ -- Read_Lock --
++ ---------------
++
++ procedure Read_Lock
++ (L : not null access Lock; Ceiling_Violation : out Boolean) is
++ begin
++ Write_Lock (L, Ceiling_Violation);
++ end Read_Lock;
++
++ ------------------------------
++ -- Requires_Affinity_Change --
++ ------------------------------
++
++ function Requires_Affinity_Change
++ (Domain : Dispatching_Domain_Access) return Boolean is
++ begin
++ return
++ Domain /= System_Domain
++ or else Domain.all
++ /= [Multiprocessors.CPU'First
++ .. Multiprocessors.Number_Of_CPUs => True];
++ end Requires_Affinity_Change;
++
++ ------------
++ -- Unlock --
++ ------------
++
++ procedure Unlock (L : not null access Lock) is
++ Result : int;
++ begin
++ if Locking_Policy = 'R' then
++ Result := pthread_rwlock_unlock (L.RW'Access);
++ else
++ Result := pthread_mutex_unlock (L.WO'Access);
++ end if;
++ pragma Assert (Result = 0);
++ end Unlock;
++
++ procedure Unlock (L : not null access RTS_Lock) is
++ Result : int;
++ begin
++ Result := pthread_mutex_unlock (L);
++ pragma Assert (Result = 0);
++ end Unlock;
++
++ procedure Unlock (T : Task_Id) is
++ Result : int;
++ begin
++ Result := pthread_mutex_unlock (T.Common.LL.L'Access);
++ pragma Assert (Result = 0);
++ end Unlock;
++
++ -----------------
++ -- Set_Ceiling --
++ -----------------
++
++ -- Dynamic priority ceilings are not supported by the underlying system
++
++ procedure Set_Ceiling
++ (L : not null access Lock;
++ Prio : System.Any_Priority)
++ is
++ pragma Unreferenced (L, Prio);
++ begin
++ null;
++ end Set_Ceiling;
++
++ -----------
++ -- Sleep --
++ -----------
++
++ procedure Sleep
++ (Self_ID : Task_Id;
++ Reason : System.Tasking.Task_States)
++ is
++ pragma Unreferenced (Reason);
++
++ Result : int;
++
++ begin
++ pragma Assert (Self_ID = Self);
++
++ Result :=
++ pthread_cond_wait
++ (cond => Self_ID.Common.LL.CV'Access,
++ mutex => Self_ID.Common.LL.L'Access);
++
++ -- EINTR is not considered a failure
++
++ pragma Assert (Result = 0 or else Result = EINTR);
++ end Sleep;
++
++ -----------------
++ -- Timed_Sleep --
++ -----------------
++
++ -- This is for use within the run-time system, so abort is
++ -- assumed to be already deferred, and the caller should be
++ -- holding its own ATCB lock.
++
++ procedure Timed_Sleep
++ (Self_ID : Task_Id;
++ Time : Duration;
++ Mode : ST.Delay_Modes;
++ Reason : Task_States;
++ Timedout : out Boolean;
++ Yielded : out Boolean) renames Monotonic.Timed_Sleep;
++
++ -----------------
++ -- Timed_Delay --
++ -----------------
++
++ -- This is for use in implementing delay statements, so we assume the
++ -- caller is abort-deferred but is holding no locks.
++
++ procedure Timed_Delay
++ (Self_ID : Task_Id;
++ Time : Duration;
++ Mode : ST.Delay_Modes) renames Monotonic.Timed_Delay;
++
++ ---------------------
++ -- Monotonic_Clock --
++ ---------------------
++
++ function Monotonic_Clock return Duration renames Monotonic.Monotonic_Clock;
++
++ -------------------
++ -- RT_Resolution --
++ -------------------
++
++ function RT_Resolution return Duration renames Monotonic.RT_Resolution;
++
++ ------------
++ -- Wakeup --
++ ------------
++
++ procedure Wakeup (T : Task_Id; Reason : System.Tasking.Task_States) is
++ pragma Unreferenced (Reason);
++ Result : int;
++ begin
++ Result := pthread_cond_signal (T.Common.LL.CV'Access);
++ pragma Assert (Result = 0);
++ end Wakeup;
++
++ -----------
++ -- Yield --
++ -----------
++
++ procedure Yield (Do_Yield : Boolean := True) is
++ Result : int;
++ pragma Unreferenced (Result);
++ begin
++ if Do_Yield then
++ Result := sched_yield;
++ end if;
++ end Yield;
++
++ ------------------
++ -- Set_Priority --
++ ------------------
++
++ procedure Set_Priority
++ (T : Task_Id;
++ Prio : System.Any_Priority;
++ Loss_Of_Inheritance : Boolean := False)
++ is
++ pragma Unreferenced (Loss_Of_Inheritance);
++
++ Result : int;
++ Param : aliased struct_sched_param;
++
++ function Get_Policy (Prio : System.Any_Priority) return Character;
++ pragma Import (C, Get_Policy, "__gnat_get_specific_dispatching");
++ -- Get priority specific dispatching policy
++
++ Priority_Specific_Policy : constant Character := Get_Policy (Prio);
++ -- Upper case first character of the policy name corresponding to the
++ -- task as set by a Priority_Specific_Dispatching pragma.
++
++ begin
++ T.Common.Current_Priority := Prio;
++ Param.sched_priority := To_Target_Priority (Prio);
++
++ if Time_Slice_Supported
++ and then (Dispatching_Policy = 'R'
++ or else Priority_Specific_Policy = 'R'
++ or else Time_Slice_Val > 0)
++ then
++ Result := pthread_setschedparam
++ (T.Common.LL.Thread, SCHED_RR, Param'Access);
++
++ elsif Dispatching_Policy = 'F'
++ or else Priority_Specific_Policy = 'F'
++ or else Time_Slice_Val = 0
++ then
++ Result := pthread_setschedparam
++ (T.Common.LL.Thread, SCHED_FIFO, Param'Access);
++
++ else
++ Result := pthread_setschedparam
++ (T.Common.LL.Thread, SCHED_OTHER, Param'Access);
++ end if;
++
++ pragma Assert (Result = 0 or else Result = EINVAL);
++ end Set_Priority;
++
++ ------------------
++ -- Get_Priority --
++ ------------------
++
++ function Get_Priority (T : Task_Id) return System.Any_Priority is
++ begin
++ return T.Common.Current_Priority;
++ end Get_Priority;
++
++ ----------------
++ -- Enter_Task --
++ ----------------
++
++ procedure Enter_Task (Self_ID : Task_Id) is
++ begin
++ Self_ID.Common.LL.LWP := lwp_self;
++
++ Specific.Set (Self_ID);
++
++ if Use_Alternate_Stack then
++ declare
++ Stack : aliased stack_t;
++ Result : int;
++ begin
++ Stack.ss_sp := Self_ID.Common.Task_Alternate_Stack;
++ Stack.ss_size := Alternate_Stack_Size;
++ Stack.ss_flags := 0;
++ Result := sigaltstack (Stack'Access, null);
++ pragma Assert (Result = 0);
++ end;
++ end if;
++ end Enter_Task;
++
++ -------------------
++ -- Is_Valid_Task --
++ -------------------
++
++ function Is_Valid_Task return Boolean renames Specific.Is_Valid_Task;
++
++ -----------------------------
++ -- Register_Foreign_Thread --
++ -----------------------------
++
++ function Register_Foreign_Thread return Task_Id is
++ begin
++ if Is_Valid_Task then
++ return Self;
++ else
++ return Register_Foreign_Thread (pthread_self);
++ end if;
++ end Register_Foreign_Thread;
++
++ --------------------
++ -- Initialize_TCB --
++ --------------------
++
++ procedure Initialize_TCB (Self_ID : Task_Id; Succeeded : out Boolean) is
++ Result : int;
++ Cond_Attr : aliased pthread_condattr_t;
++
++ begin
++ -- Give the task a unique serial number
++
++ Self_ID.Serial_Number := Next_Serial_Number;
++ Next_Serial_Number := Next_Serial_Number + 1;
++ pragma Assert (Next_Serial_Number /= 0);
++
++ if Initialize_Lock (Self_ID.Common.LL.L'Access, Any_Priority'Last) /= 0
++ then
++ Succeeded := False;
++ return;
++ end if;
++
++ Result := pthread_condattr_init (Cond_Attr'Access);
++ pragma Assert (Result = 0 or else Result = ENOMEM);
++
++ if Result = 0 then
++ Result := GNAT_pthread_condattr_setup (Cond_Attr'Access);
++ pragma Assert (Result = 0);
++
++ Result :=
++ pthread_cond_init
++ (Self_ID.Common.LL.CV'Access, Cond_Attr'Access);
++ pragma Assert (Result = 0 or else Result = ENOMEM);
++ end if;
++
++ if Result = 0 then
++ Succeeded := True;
++ else
++ Result := pthread_mutex_destroy (Self_ID.Common.LL.L'Access);
++ pragma Assert (Result = 0);
++ Succeeded := False;
++ end if;
++
++ Result := pthread_condattr_destroy (Cond_Attr'Access);
++ pragma Assert (Result = 0);
++ end Initialize_TCB;
++
++ -----------------
++ -- Create_Task --
++ -----------------
++
++ procedure Create_Task
++ (T : Task_Id;
++ Wrapper : System.Address;
++ Stack_Size : System.Parameters.Size_Type;
++ Priority : System.Any_Priority;
++ Succeeded : out Boolean)
++ is
++ Attributes : aliased pthread_attr_t;
++ Adjusted_Stack_Size : size_t;
++ Page_Size : constant size_t :=
++ size_t (Get_Page_Size);
++ Result : int;
++
++ function Thread_Body_Access is new
++ Ada.Unchecked_Conversion (System.Address, Thread_Body);
++
++ use System.Task_Info;
++ use type Multiprocessors.CPU_Range;
++
++ begin
++ -- Check whether both Dispatching_Domain and CPU are specified for
++ -- the task, and the CPU value is not contained within the range of
++ -- processors for the domain.
++
++ if T.Common.Domain /= null
++ and then T.Common.Base_CPU /= Multiprocessors.Not_A_Specific_CPU
++ and then
++ (T.Common.Base_CPU not in T.Common.Domain'Range
++ or else not T.Common.Domain (T.Common.Base_CPU))
++ then
++ Succeeded := False;
++ return;
++ end if;
++
++ Adjusted_Stack_Size :=
++ size_t (Stack_Size + Alternate_Stack_Size);
++
++ if Stack_Base_Available then
++
++ -- If Stack Checking is supported then allocate 2 additional pages:
++
++ -- In the worst case, stack is allocated at something like
++ -- N * Get_Page_Size - epsilon, we need to add the size for 2 pages
++ -- to be sure the effective stack size is greater than what
++ -- has been asked.
++
++ Adjusted_Stack_Size := Adjusted_Stack_Size + 2 * Page_Size;
++ end if;
++
++ -- Round stack size as this is required by some OSes (Darwin)
++
++ Adjusted_Stack_Size := Adjusted_Stack_Size + Page_Size - 1;
++ Adjusted_Stack_Size :=
++ Adjusted_Stack_Size - Adjusted_Stack_Size mod Page_Size;
++
++ Result := pthread_attr_init (Attributes'Access);
++ pragma Assert (Result = 0 or else Result = ENOMEM);
++
++ if Result /= 0 then
++ Succeeded := False;
++ return;
++ end if;
++
++ Result :=
++ pthread_attr_setdetachstate
++ (Attributes'Access, PTHREAD_CREATE_DETACHED);
++ pragma Assert (Result = 0);
++
++ Result :=
++ pthread_attr_setstacksize
++ (Attributes'Access, Adjusted_Stack_Size);
++ pragma Assert (Result = 0);
++
++ if T.Common.Task_Info /= Default_Scope then
++ case T.Common.Task_Info is
++ when System.Task_Info.Process_Scope =>
++ Result :=
++ pthread_attr_setscope
++ (Attributes'Access, PTHREAD_SCOPE_PROCESS);
++
++ when System.Task_Info.System_Scope =>
++ Result :=
++ pthread_attr_setscope
++ (Attributes'Access, PTHREAD_SCOPE_SYSTEM);
++
++ when System.Task_Info.Default_Scope =>
++ Result := 0;
++ end case;
++
++ pragma Assert (Result = 0);
++ end if;
++
++ -- Since the initial signal mask of a thread is inherited from the
++ -- creator, and the Environment task has all its signals masked, we
++ -- do not need to manipulate caller's signal mask at this point.
++ -- All tasks in RTS will have All_Tasks_Mask initially.
++
++ -- The write to T.Common.LL.Thread is not racy with regard to the
++ -- created thread because the created thread will not access it until
++ -- we release the RTS lock (or the current task's lock when
++ -- Restricted.Stages is used). One can verify that by inspecting the
++ -- Task_Wrapper procedures.
++
++ Result := pthread_create
++ (T.Common.LL.Thread'Access,
++ Attributes'Access,
++ Thread_Body_Access (Wrapper),
++ To_Address (T));
++ pragma Assert (Result in 0 | EAGAIN | ENOMEM);
++
++ Succeeded := Result = 0;
++
++ Result := pthread_attr_destroy (Attributes'Access);
++ pragma Assert (Result = 0);
++
++ if Succeeded then
++ Set_Priority (T, Priority);
++ end if;
++ end Create_Task;
++
++ ------------------
++ -- Finalize_TCB --
++ ------------------
++
++ procedure Finalize_TCB (T : Task_Id) is
++ Result : int;
++
++ begin
++ Result := pthread_mutex_destroy (T.Common.LL.L'Access);
++ pragma Assert (Result = 0);
++
++ Result := pthread_cond_destroy (T.Common.LL.CV'Access);
++ pragma Assert (Result = 0);
++
++ if T.Known_Tasks_Index /= -1 then
++ Known_Tasks (T.Known_Tasks_Index) := null;
++ end if;
++
++ ATCB_Allocation.Free_ATCB (T);
++ end Finalize_TCB;
++
++ ---------------
++ -- Exit_Task --
++ ---------------
++
++ procedure Exit_Task is
++ begin
++ -- Mark this task as unknown, so that if Self is called, it won't
++ -- return a dangling pointer.
++
++ Specific.Set (null);
++ end Exit_Task;
++
++ ----------------
++ -- Abort_Task --
++ ----------------
++
++ procedure Abort_Task (T : Task_Id) is
++ Result : int;
++
++ ESRCH : constant int := 3;
++ -- It can happen that T has already vanished, in which case pthread_kill
++ -- returns ESRCH, so we don't consider that to be an error.
++ begin
++ if Abort_Handler_Installed then
++ Result :=
++ pthread_kill
++ (T.Common.LL.Thread,
++ Signal (System.Interrupt_Management.Abort_Task_Interrupt));
++ pragma Assert (Result = 0 or else Result = ESRCH);
++ end if;
++ end Abort_Task;
++
++ ----------------
++ -- Initialize --
++ ----------------
++
++ procedure Initialize (S : in out Suspension_Object) is
++ Mutex_Attr : aliased pthread_mutexattr_t;
++ Cond_Attr : aliased pthread_condattr_t;
++ Result, Result_2 : int;
++
++ begin
++ -- Initialize internal state (always to False (RM D.10 (6)))
++
++ S.State := False;
++ S.Waiting := False;
++
++ -- Initialize internal mutex
++
++ Result := pthread_mutexattr_init (Mutex_Attr'Access);
++ pragma Assert (Result = 0 or else Result = ENOMEM);
++
++ if Result = ENOMEM then
++ raise Storage_Error;
++ end if;
++
++ Result := pthread_mutex_init (S.L'Access, Mutex_Attr'Access);
++ pragma Assert (Result = 0 or else Result = ENOMEM);
++
++ Result_2 := pthread_mutexattr_destroy (Mutex_Attr'Access);
++ pragma Assert (Result_2 = 0);
++
++ if Result = ENOMEM then
++ raise Storage_Error;
++ end if;
++
++ -- Initialize internal condition variable
++
++ Result := pthread_condattr_init (Cond_Attr'Access);
++ pragma Assert (Result = 0 or else Result = ENOMEM);
++
++ if Result /= 0 then
++ Result := pthread_mutex_destroy (S.L'Access);
++ pragma Assert (Result = 0);
++
++ -- Storage_Error is propagated as intended if the allocation of the
++ -- underlying OS entities fails.
++
++ if Result = ENOMEM then
++ raise Storage_Error;
++ end if;
++ end if;
++
++ Result := GNAT_pthread_condattr_setup (Cond_Attr'Access);
++ pragma Assert (Result = 0);
++
++ Result := pthread_cond_init (S.CV'Access, Cond_Attr'Access);
++ pragma Assert (Result = 0 or else Result = ENOMEM);
++
++ Result_2 := pthread_condattr_destroy (Cond_Attr'Access);
++ pragma Assert (Result_2 = 0);
++
++ if Result /= 0 then
++ Result_2 := pthread_mutex_destroy (S.L'Access);
++ pragma Assert (Result_2 = 0);
++
++ -- Storage_Error is propagated as intended if the allocation of the
++ -- underlying OS entities fails.
++
++ if Result = ENOMEM then
++ raise Storage_Error;
++ end if;
++ end if;
++ end Initialize;
++
++ --------------
++ -- Finalize --
++ --------------
++
++ procedure Finalize (S : in out Suspension_Object) is
++ Result : int;
++
++ begin
++ -- Destroy internal mutex
++
++ Result := pthread_mutex_destroy (S.L'Access);
++ pragma Assert (Result = 0);
++
++ -- Destroy internal condition variable
++
++ Result := pthread_cond_destroy (S.CV'Access);
++ pragma Assert (Result = 0);
++ end Finalize;
++
++ -------------------
++ -- Current_State --
++ -------------------
++
++ function Current_State (S : Suspension_Object) return Boolean is
++ begin
++ -- We do not want to use lock on this read operation. State is marked
++ -- as Atomic so that we ensure that the value retrieved is correct.
++
++ return S.State;
++ end Current_State;
++
++ ---------------
++ -- Set_False --
++ ---------------
++
++ procedure Set_False (S : in out Suspension_Object) is
++ Result : int;
++
++ begin
++ SSL.Abort_Defer.all;
++
++ Result := pthread_mutex_lock (S.L'Access);
++ pragma Assert (Result = 0);
++
++ S.State := False;
++
++ Result := pthread_mutex_unlock (S.L'Access);
++ pragma Assert (Result = 0);
++
++ SSL.Abort_Undefer.all;
++ end Set_False;
++
++ --------------
++ -- Set_True --
++ --------------
++
++ procedure Set_True (S : in out Suspension_Object) is
++ Result : int;
++
++ begin
++ SSL.Abort_Defer.all;
++
++ Result := pthread_mutex_lock (S.L'Access);
++ pragma Assert (Result = 0);
++
++ -- If there is already a task waiting on this suspension object then
++ -- we resume it, leaving the state of the suspension object to False,
++ -- as it is specified in (RM D.10(9)). Otherwise, it just leaves
++ -- the state to True.
++
++ if S.Waiting then
++ S.Waiting := False;
++ S.State := False;
++
++ Result := pthread_cond_signal (S.CV'Access);
++ pragma Assert (Result = 0);
++
++ else
++ S.State := True;
++ end if;
++
++ Result := pthread_mutex_unlock (S.L'Access);
++ pragma Assert (Result = 0);
++
++ SSL.Abort_Undefer.all;
++ end Set_True;
++
++ ------------------------
++ -- Suspend_Until_True --
++ ------------------------
++
++ procedure Suspend_Until_True (S : in out Suspension_Object) is
++ Result : int;
++
++ begin
++ SSL.Abort_Defer.all;
++
++ Result := pthread_mutex_lock (S.L'Access);
++ pragma Assert (Result = 0);
++
++ if S.Waiting then
++
++ -- Program_Error must be raised upon calling Suspend_Until_True
++ -- if another task is already waiting on that suspension object
++ -- (RM D.10(10)).
++
++ Result := pthread_mutex_unlock (S.L'Access);
++ pragma Assert (Result = 0);
++
++ SSL.Abort_Undefer.all;
++
++ raise Program_Error;
++
++ else
++ -- Suspend the task if the state is False. Otherwise, the task
++ -- continues its execution, and the state of the suspension object
++ -- is set to False (ARM D.10 par. 9).
++
++ if S.State then
++ S.State := False;
++ else
++ S.Waiting := True;
++
++ loop
++ -- Loop in case pthread_cond_wait returns earlier than expected
++ -- (e.g. in case of EINTR caused by a signal).
++
++ Result := pthread_cond_wait (S.CV'Access, S.L'Access);
++ pragma Assert (Result = 0 or else Result = EINTR);
++
++ exit when not S.Waiting;
++ end loop;
++ end if;
++
++ Result := pthread_mutex_unlock (S.L'Access);
++ pragma Assert (Result = 0);
++
++ SSL.Abort_Undefer.all;
++ end if;
++ end Suspend_Until_True;
++
++ ----------------
++ -- Check_Exit --
++ ----------------
++
++ -- Dummy version
++
++ function Check_Exit (Self_ID : ST.Task_Id) return Boolean is
++ pragma Unreferenced (Self_ID);
++ begin
++ return True;
++ end Check_Exit;
++
++ --------------------
++ -- Check_No_Locks --
++ --------------------
++
++ function Check_No_Locks (Self_ID : ST.Task_Id) return Boolean is
++ pragma Unreferenced (Self_ID);
++ begin
++ return True;
++ end Check_No_Locks;
++
++ ----------------------
++ -- Environment_Task --
++ ----------------------
++
++ function Environment_Task return Task_Id is
++ begin
++ return Environment_Task_Id;
++ end Environment_Task;
++
++ --------------
++ -- Lock_RTS --
++ --------------
++
++ procedure Lock_RTS is
++ begin
++ Write_Lock (Single_RTS_Lock'Access);
++ end Lock_RTS;
++
++ ----------------
++ -- Unlock_RTS --
++ ----------------
++
++ procedure Unlock_RTS is
++ begin
++ Unlock (Single_RTS_Lock'Access);
++ end Unlock_RTS;
++
++ ------------------
++ -- Suspend_Task --
++ ------------------
++
++ function Suspend_Task
++ (T : ST.Task_Id;
++ Thread_Self : Thread_Id) return Boolean
++ is
++ begin
++ if T.Common.LL.Thread /= Thread_Self then
++ return pthread_kill (T.Common.LL.Thread, SIGSTOP) = 0;
++ end if;
++ return False;
++ end Suspend_Task;
++
++ -----------------
++ -- Resume_Task --
++ -----------------
++
++ function Resume_Task
++ (T : ST.Task_Id;
++ Thread_Self : Thread_Id) return Boolean
++ is
++ begin
++ if T.Common.LL.Thread /= Thread_Self then
++ return pthread_kill (T.Common.LL.Thread, SIGCONT) = 0;
++ end if;
++ return False;
++ end Resume_Task;
++
++ --------------------
++ -- Stop_All_Tasks --
++ --------------------
++
++ procedure Stop_All_Tasks is
++ begin
++ null;
++ end Stop_All_Tasks;
++
++ ---------------
++ -- Stop_Task --
++ ---------------
++
++ function Stop_Task (T : ST.Task_Id) return Boolean is
++ pragma Unreferenced (T);
++ begin
++ return False;
++ end Stop_Task;
++
++ -------------------
++ -- Continue_Task --
++ -------------------
++
++ function Continue_Task (T : ST.Task_Id) return Boolean is
++ pragma Unreferenced (T);
++ begin
++ return False;
++ end Continue_Task;
++
++ ----------------
++ -- Initialize --
++ ----------------
++
++ procedure Initialize (Environment_Task : Task_Id) is
++ act : aliased struct_sigaction;
++ old_act : aliased struct_sigaction;
++ Tmp_Set : aliased sigset_t;
++ Result : int;
++
++ function State
++ (Int : System.Interrupt_Management.Interrupt_ID) return Character;
++ pragma Import (C, State, "__gnat_get_interrupt_state");
++ -- Get interrupt state. Defined in a-init.c
++ -- The input argument is the interrupt number,
++ -- and the result is one of the following:
++
++ Default : constant Character := 's';
++ -- 'n' this interrupt not set by any Interrupt_State pragma
++ -- 'u' Interrupt_State pragma set state to User
++ -- 'r' Interrupt_State pragma set state to Runtime
++ -- 's' Interrupt_State pragma set state to System (use "default"
++ -- system handler)
++
++ begin
++ Environment_Task_Id := Environment_Task;
++ Environment_Task.Common.LL.Thread := pthread_self;
++
++ Interrupt_Management.Initialize;
++
++ -- Prepare the set of signals that should unblocked in all tasks
++
++ Result := sigemptyset (Unblocked_Signal_Mask'Access);
++ pragma Assert (Result = 0);
++
++ for J in Interrupt_Management.Interrupt_ID loop
++ if System.Interrupt_Management.Keep_Unmasked (J) then
++ Result := sigaddset (Unblocked_Signal_Mask'Access, Signal (J));
++ pragma Assert (Result = 0);
++ end if;
++ end loop;
++
++ -- Initialize the lock used to synchronize chain of all ATCBs
++
++ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
++
++ Specific.Initialize (Environment_Task);
++
++ -- Do not use an alternate stack if no handler for SEGV is installed
++
++ if State (SIGSEGV) = Default then
++ Use_Alternate_Stack := False;
++ end if;
++
++ if Use_Alternate_Stack then
++ Environment_Task.Common.Task_Alternate_Stack :=
++ Alternate_Stack'Address;
++ end if;
++
++ -- Make environment task known here because it doesn't go through
++ -- Activate_Tasks, which does it for all other tasks.
++
++ Known_Tasks (Known_Tasks'First) := Environment_Task;
++ Environment_Task.Known_Tasks_Index := Known_Tasks'First;
++
++ Enter_Task (Environment_Task);
++
++ if State
++ (System.Interrupt_Management.Abort_Task_Interrupt) /= Default
++ then
++ act.sa_flags := 0;
++ act.sa_handler := Abort_Handler'Address;
++
++ Result := sigemptyset (Tmp_Set'Access);
++ pragma Assert (Result = 0);
++ act.sa_mask := Tmp_Set;
++
++ Result :=
++ sigaction
++ (Signal (System.Interrupt_Management.Abort_Task_Interrupt),
++ act'Unchecked_Access,
++ old_act'Unchecked_Access);
++ pragma Assert (Result = 0);
++ Abort_Handler_Installed := True;
++ end if;
++
++ -- pragma CPU and dispatching domains for the environment task
++
++ Set_Task_Affinity (Environment_Task);
++
++ end Initialize;
++
++ -----------------------
++ -- Set_Task_Affinity --
++ -----------------------
++
++ procedure Set_Task_Affinity (T : ST.Task_Id) is
++ use type Multiprocessors.CPU_Range;
++
++ begin
++ -- Do nothing if there is no support for setting affinities or the
++ -- underlying thread has not yet been created. If the thread has not
++ -- yet been created then the proper affinity will be set during its
++ -- creation.
++
++ if pthread_setaffinity_np'Address /= Null_Address
++ and then (T.Common.CPU_Is_Explicit
++ or else Requires_Affinity_Change (T.Common.Domain))
++ then
++ declare
++ CPU_Set : constant access cpuset_t := cpuset_create;
++ Result : int;
++ begin
++ if CPU_Set = null then
++ raise Storage_Error with "Failed to allocate a CPU set";
++ end if;
++
++ -- We look at the specific CPU (Base_CPU) first, then at the
++ -- Task_Info field, and finally at the assigned dispatching
++ -- domain, if any.
++
++ if T.Common.Base_CPU /= Multiprocessors.Not_A_Specific_CPU then
++
++ -- Set the affinity to an unique CPU
++
++ Result := cpuset_set (cpuid_t (T.Common.Base_CPU), CPU_Set);
++
++ -- Handle dispatching domains
++
++ else
++ -- Set the affinity to all the processors belonging to the
++ -- dispatching domain.
++
++ for Proc in T.Common.Domain'Range loop
++ if T.Common.Domain (Proc) then
++ Result := cpuset_set (cpuid_t (Proc), CPU_Set);
++ end if;
++ end loop;
++ end if;
++
++ Result :=
++ pthread_setaffinity_np (
++ T.Common.LL.Thread, cpuset_size (CPU_Set), CPU_Set);
++ pragma Assert (Result = 0);
++
++ cpuset_destroy (CPU_Set);
++ end;
++ end if;
++ end Set_Task_Affinity;
++
++end System.Task_Primitives.Operations;
Index: pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnat_g-socthi____bsd.adb
diff -u /dev/null pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnat_g-socthi____bsd.adb:1.1
--- /dev/null Sat Jun 6 06:15:50 2026
+++ pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnat_g-socthi____bsd.adb Sat Jun 6 06:15:50 2026
@@ -0,0 +1,508 @@
+$NetBSD: patch-gcc_ada_libgnat_g-socthi____bsd.adb,v 1.1 2026/06/06 06:15:50 dkazankov Exp $
+
+Create a g-socthi package that is common to all *BSD systems.
+
+--- /dev/null
++++ gcc/ada/libgnat/g-socthi__bsd.adb
+@@ -0,0 +1,501 @@
++------------------------------------------------------------------------------
++-- --
++-- GNAT COMPILER COMPONENTS --
++-- --
++-- G N A T . S O C K E T S . T H I N --
++-- --
++-- B o d y --
++-- --
++-- Copyright (C) 2001-2018, AdaCore --
++-- --
++-- GNAT is free software; you can redistribute it and/or modify it under --
++-- terms of the GNU General Public License as published by the Free Soft- --
++-- ware Foundation; either version 3, or (at your option) any later ver- --
++-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
++-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
++-- or FITNESS FOR A PARTICULAR PURPOSE. --
++-- --
++-- As a special exception under Section 7 of GPL version 3, you are granted --
++-- additional permissions described in the GCC Runtime Library Exception, --
++-- version 3.1, as published by the Free Software Foundation. --
++-- --
++-- You should have received a copy of the GNU General Public License and --
++-- a copy of the GCC Runtime Library Exception along with this program; --
++-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
++-- <http://www.gnu.org/licenses/>. --
++-- --
++-- GNAT was originally developed by the GNAT team at New York University. --
++-- Extensive contributions were provided by Ada Core Technologies Inc. --
++-- --
++------------------------------------------------------------------------------
++
++-- This package provides a target dependent thin interface to the sockets
++-- layer for use by the GNAT.Sockets package (g-socket.ads). This package
++-- should not be directly with'ed by an applications program.
++
++-- This is the *BSD version which uses fcntl rather than ioctl
++-- The constant SCON.Thread_Blocking_IO is always true (for all platforms, not
++-- just *BSD), so this binding is significantly simpler than the standard
++-- one it replaces.
++
++with GNAT.OS_Lib; use GNAT.OS_Lib;
++
++with Interfaces.C; use Interfaces.C;
++
++package body GNAT.Sockets.Thin is
++
++ function Syscall_Accept
++ (S : C.int;
++ Addr : System.Address;
++ Addrlen : not null access socklen_t) return C.int;
++ pragma Import (C, Syscall_Accept, "accept");
++ -- The accept() function accepts a connection on a socket. An incoming
++ -- connection is acknowledged and associated with an immediately created
++ -- socket. The original socket is returned to the listening state.
++
++ function Syscall_Connect
++ (S : C.int;
++ Name : System.Address;
++ Namelen : socklen_t) return C.int;
++ pragma Import (C, Syscall_Connect, "connect");
++ -- The connect() system call initiates a connection on a socket. If the
++ -- parameter S is of type SOCK_DGRAM then connect() permanently specifies
++ -- the peer to which datagrams are to be sent. If S is type SOCK_STREAM
++ -- then connect() attempts to make a connection with another socket, which
++ -- is identified by the parameter Name.
++
++ function Syscall_Recv
++ (S : C.int;
++ Msg : System.Address;
++ Len : C.size_t;
++ Flags : C.int) return System.CRTL.ssize_t;
++ pragma Import (C, Syscall_Recv, "recv");
++ -- The recv() function receives a message from a socket. The call can be
++ -- used on a connection mode socket or a bound, connectionless socket. If
++ -- no messages are available at the socket, the recv() call waits for a
++ -- message to arrive unless the socket is non-blocking. If a socket is
++ -- non-blocking, the call returns a -1 and ERRNO is set to EWOULDBLOCK.
++
++ function Syscall_Recvfrom
++ (S : C.int;
++ Msg : System.Address;
++ Len : C.size_t;
++ Flags : C.int;
++ From : System.Address;
++ Fromlen : not null access socklen_t) return System.CRTL.ssize_t;
++ pragma Import (C, Syscall_Recvfrom, "recvfrom");
++ -- The recvfrom() system call receives a message from a socket and captures
++ -- the address from which the data was sent. It can be used to receive
++ -- data on an unconnected socket as well. If no messages are available,
++ -- the call waits for a message to arrive on blocking sockets. For
++ -- non-blocking sockets without messages, -1 is returned and ERRNO is set
++ -- to EAGAIN or EWOULDBLOCK.
++
++ function Syscall_Recvmsg
++ (S : C.int;
++ Msg : System.Address;
++ Flags : C.int) return System.CRTL.ssize_t;
++ pragma Import (C, Syscall_Recvmsg, "recvmsg");
++ -- The recvmsg call receives a message from a socket, and can be used to
++ -- receive data on an unconnected socket as well. If no messages are
++ -- available, the call waits for a message to arrive on blocking sockets.
++ -- For non-blocking sockets without messages, -1 is returned and ERRNO is
++ -- set to EAGAIN or EWOULDBLOCK.
++
++ function Syscall_Sendmsg
++ (S : C.int;
++ Msg : System.Address;
++ Flags : C.int) return System.CRTL.ssize_t;
++ pragma Import (C, Syscall_Sendmsg, "sendmsg");
++ -- The sendmsg() function sends a message to a socket, and can be used with
++ -- unconnected sockets as well (the msg is ignored in this case). The
++ -- function returns the number of bytes sent when successful, otherwise it
++ -- returns -1 and ERRNO is set (many possible values).
++
++ function Syscall_Sendto
++ (S : C.int;
++ Msg : System.Address;
++ Len : C.size_t;
++ Flags : C.int;
++ To : System.Address;
++ Tolen : socklen_t) return System.CRTL.ssize_t;
++ pragma Import (C, Syscall_Sendto, "sendto");
++ -- The sendto() function only works for connected sockets and it initiates
++ -- the transmission of a message. A successful call returns the numbers of
++ -- bytes sent, and a failure returns a -1 and ERRNO is set.
++
++ function Syscall_Socket
++ (Domain : C.int;
++ Typ : C.int;
++ Protocol : C.int) return C.int;
++ pragma Import (C, Syscall_Socket, "socket");
++ -- The socket() function is used to create an unbound socket and returns a
++ -- file descriptor that can be used with other socket functions. Upon
++ -- failure, a -1 is returned and ERRNO is set.
++
++ procedure Disable_SIGPIPE (S : C.int);
++ pragma Import (C, Disable_SIGPIPE, "__gnat_disable_sigpipe");
++
++ procedure Disable_All_SIGPIPEs;
++ pragma Import (C, Disable_All_SIGPIPEs, "__gnat_disable_all_sigpipes");
++ -- Sets the process to ignore all SIGPIPE signals on platforms that
++ -- don't support Disable_SIGPIPE for particular streams.
++
++ function C_Fcntl
++ (Fd : C.int;
++ Cmd : C.int;
++ Val : C.int) return C.int;
++ pragma Import (C, C_Fcntl, "fcntl");
++ -- The ioctl of 64-bit DragonFlyBSD, OpenBSD, and NetBSD does not support
++ -- setting a socket in non-blocking mode. fcntl must be used instead.
++
++ --------------
++ -- C_Bind --
++ --------------
++
++ function C_Bind
++ (S : C.int;
++ Name : System.Address;
++ Namelen : C.int) return C.int
++ is
++ function Bind
++ (S : C.int;
++ Name : System.Address;
++ Namelen : socklen_t) return C.int
++ with Import, Convention => C, External_Name => "bind";
++ begin
++ return Bind (S, Name, socklen_t (Namelen));
++ end C_Bind;
++
++ --------------
++ -- C_Accept --
++ --------------
++
++ function C_Accept
++ (S : C.int;
++ Addr : System.Address;
++ Addrlen : not null access C.int) return C.int
++ is
++ U_Addrlen : aliased socklen_t := socklen_t (Addrlen.all);
++ R : constant C.int := Syscall_Accept (
++ S, Addr, U_Addrlen'Unchecked_Access);
++ begin
++ Addrlen.all := C.int (U_Addrlen);
++ Disable_SIGPIPE (R);
++ return R;
++ end C_Accept;
++
++ ---------------
++ -- C_Connect --
++ ---------------
++
++ function C_Connect
++ (S : C.int;
++ Name : System.Address;
++ Namelen : C.int) return C.int
++ is
++ begin
++ return Syscall_Connect (S, Name, socklen_t (Namelen));
++ end C_Connect;
++
++ -------------------
++ -- C_Getpeername --
++ -------------------
++
++ function C_Getpeername
++ (S : C.int;
++ Name : System.Address;
++ Namelen : not null access C.int) return C.int
++ is
++ function Getpeername
++ (S : C.int;
++ Name : System.Address;
++ Namelen : not null access socklen_t) return C.int
++ with Import, Convention => C, External_Name => "getpeername";
++
++ U_Namelen : aliased socklen_t := socklen_t (Namelen.all);
++ Val : constant C.int := Getpeername (
++ S, Name, U_Namelen'Unchecked_Access);
++ begin
++ Namelen.all := C.int (U_Namelen);
++ return Val;
++ end C_Getpeername;
++
++ -------------------
++ -- C_Getsockname --
++ -------------------
++
++ function C_Getsockname
++ (S : C.int;
++ Name : System.Address;
++ Namelen : not null access C.int) return C.int
++ is
++ function Getsockname
++ (S : C.int;
++ Name : System.Address;
++ Namelen : not null access socklen_t) return C.int
++ with Import, Convention => C, External_Name => "getsockname";
++
++ U_Namelen : aliased socklen_t := socklen_t (Namelen.all);
++ Val : constant C.int := Getsockname (
++ S, Name, U_Namelen'Unchecked_Access);
++ begin
++ Namelen.all := C.int (U_Namelen);
++ return Val;
++ end C_Getsockname;
++
++ -------------------
++ -- C_Getsockopt --
++ -------------------
++
++ function C_Getsockopt
++ (S : C.int;
++ Level : C.int;
++ Optname : C.int;
++ Optval : System.Address;
++ Optlen : not null access C.int) return C.int
++ is
++ function Getsockopt
++ (S : C.int;
++ Level : C.int;
++ Optname : C.int;
++ Optval : System.Address;
++ Optlen : not null access socklen_t) return C.int
++ with Import, Convention => C, External_Name => "getsockopt";
++
++ U_Optlen : aliased socklen_t := socklen_t (Optlen.all);
++ Val : constant C.int := Getsockopt (
++ S, Level, Optname, Optval, U_Optlen'Unchecked_Access);
++
++ begin
++ Optlen.all := C.int (U_Optlen);
++ return Val;
++ end C_Getsockopt;
++
++ ------------------
++ -- Socket_Ioctl --
++ ------------------
++
++ function Socket_Ioctl
++ (S : C.int;
++ Req : SOSC.IOCTL_Req_T;
++ Arg : access C.int) return C.int
++ is
++ begin
++ if Req = SOSC.FIONBIO then
++ -- This is equivalent to fcntl() F_SETFL O_NONBLOCK
++ -- and the fcntl() form should be preferred
++ declare
++ flags : C.unsigned := C.unsigned (C_Fcntl (S, SOSC.F_GETFL, 0));
++ O_NDELAY : constant C.unsigned := C.unsigned (SOSC.O_NDELAY);
++ -- Set non-blocking I/O mode if the argument is non-zero
++ enable : constant Boolean := Arg.all /= 0;
++ enabled : constant Boolean := (flags and O_NDELAY) /= 0;
++ begin
++ if enable then
++ if not enabled then
++ flags := flags or O_NDELAY;
++ end if;
++ elsif enabled then
++ flags := flags and not O_NDELAY;
++ end if;
++ return C_Fcntl (
++ Fd => S, Cmd => SOSC.F_SETFL, Val => C.int (flags));
++ end;
++ end if;
++
++ return C_Ioctl (S, Req, Arg);
++ end Socket_Ioctl;
++
++ ------------
++ -- C_Recv --
++ ------------
++
++ function C_Recv
++ (S : C.int;
++ Msg : System.Address;
++ Len : C.size_t;
++ Flags : C.int) return C.int
++ is
++ begin
++ return C.int (Syscall_Recv (S, Msg, Len, Flags));
++ end C_Recv;
++
++ ----------------
++ -- C_Recvfrom --
++ ----------------
++
++ function C_Recvfrom
++ (S : C.int;
++ Msg : System.Address;
++ Len : C.size_t;
++ Flags : C.int;
++ From : System.Address;
++ Fromlen : not null access C.int) return C.int
++ is
++ U_Fromlen : aliased socklen_t := socklen_t (Fromlen.all);
++ Val : constant System.CRTL.ssize_t := Syscall_Recvfrom (
++ S, Msg, Len, Flags, From, U_Fromlen'Unchecked_Access);
++ begin
++ Fromlen.all := C.int (U_Fromlen);
++ return C.int (Val);
++ end C_Recvfrom;
++
++ ---------------
++ -- C_Recvmsg --
++ ---------------
++
++ function C_Recvmsg
++ (S : C.int;
++ Msg : System.Address;
++ Flags : C.int) return System.CRTL.ssize_t
++ is
++ begin
++ return Syscall_Recvmsg (S, Msg, Flags);
++ end C_Recvmsg;
++
++ ---------------
++ -- C_Sendmsg --
++ ---------------
++
++ function C_Sendmsg
++ (S : C.int;
++ Msg : System.Address;
++ Flags : C.int) return System.CRTL.ssize_t
++ is
++ begin
++ return Syscall_Sendmsg (S, Msg, Flags);
++ end C_Sendmsg;
++
++ --------------
++ -- C_Sendto --
++ --------------
++
++ function C_Sendto
++ (S : C.int;
++ Msg : System.Address;
++ Len : C.size_t;
++ Flags : C.int;
++ To : System.Address;
++ Tolen : C.int) return C.int
++ is
++ begin
++ return C.int (
++ Syscall_Sendto (S, Msg, Len, Flags, To, socklen_t (Tolen)));
++ end C_Sendto;
++
++ ------------------
++ -- C_Setsockopt --
++ ------------------
++
++ function C_Setsockopt
++ (S : C.int;
++ Level : C.int;
++ Optname : C.int;
++ Optval : System.Address;
++ Optlen : C.int) return C.int
++ is
++ function Setsockopt
++ (S : C.int;
++ Level : C.int;
++ Optname : C.int;
++ Optval : System.Address;
++ Optlen : socklen_t) return C.int
++ with Import, Convention => C, External_Name => "setsockopt";
++
++ begin
++ return Setsockopt (S, Level, Optname, Optval, socklen_t (Optlen));
++ end C_Setsockopt;
++
++ --------------
++ -- C_Socket --
++ --------------
++
++ function C_Socket
++ (Domain : C.int;
++ Typ : C.int;
++ Protocol : C.int) return C.int
++ is
++ R : constant C.int := Syscall_Socket (Domain, Typ, Protocol);
++ begin
++ Disable_SIGPIPE (R);
++ return R;
++ end C_Socket;
++
++ --------------
++ -- Finalize --
++ --------------
++
++ procedure Finalize is
++ begin
++ null;
++ end Finalize;
++
++ -------------------------
++ -- Host_Error_Messages --
++ -------------------------
++
++ package body Host_Error_Messages is separate;
++
++ ----------------
++ -- Initialize --
++ ----------------
++
++ procedure Initialize is
++ begin
++ Disable_All_SIGPIPEs;
++ end Initialize;
++
++ --------------------------------
++ -- Nonreentrant_Gethostbyaddr --
++ --------------------------------
++
++ function Nonreentrant_Gethostbyaddr
++ (Addr : System.Address;
++ Addr_Len : C.int;
++ Addr_Type : C.int) return Hostent_Access
++ is
++ function Gethostbyaddr
++ (Addr : System.Address;
++ Addr_Len : socklen_t;
++ Addr_Type : C.int) return Hostent_Access
++ with Import, Convention => C, External_Name => "gethostbyaddr";
++
++ begin
++ return Gethostbyaddr (Addr, socklen_t (Addr_Len), Addr_Type);
++ end Nonreentrant_Gethostbyaddr;
++
++ --------------------
++ -- Signalling_Fds --
++ --------------------
++
++ package body Signalling_Fds is
++
++ -- In this default implementation, we use a C version of these
++ -- subprograms provided by socket.c.
++
++ function C_Create (Fds : not null access Fd_Pair) return C.int;
++ function C_Read (Rsig : C.int) return C.int;
++ function C_Write (Wsig : C.int) return C.int;
++ procedure C_Close (Sig : C.int);
++
++ pragma Import (C, C_Create, "__gnat_create_signalling_fds");
++ pragma Import (C, C_Read, "__gnat_read_signalling_fd");
++ pragma Import (C, C_Write, "__gnat_write_signalling_fd");
++ pragma Import (C, C_Close, "__gnat_close_signalling_fd");
++
++ function Create
++ (Fds : not null access Fd_Pair) return C.int renames C_Create;
++ function Read (Rsig : C.int) return C.int renames C_Read;
++ function Write (Wsig : C.int) return C.int renames C_Write;
++ procedure Close (Sig : C.int) renames C_Close;
++
++ end Signalling_Fds;
++
++ --------------------------
++ -- Socket_Error_Message --
++ --------------------------
++
++ function Socket_Error_Message (Errno : Integer) return String is separate;
++
++end GNAT.Sockets.Thin;
Index: pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnat_g-socthi____bsd.ads
diff -u /dev/null pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnat_g-socthi____bsd.ads:1.1
--- /dev/null Sat Jun 6 06:15:50 2026
+++ pkgsrc/lang/gcc15-gnat/patches/patch-gcc_ada_libgnat_g-socthi____bsd.ads Sat Jun 6 06:15:50 2026
@@ -0,0 +1,279 @@
+$NetBSD: patch-gcc_ada_libgnat_g-socthi____bsd.ads,v 1.1 2026/06/06 06:15:50 dkazankov Exp $
+
+Create a g-socthi package that is common to all *BSD systems.
+
+--- /dev/null
++++ gcc/ada/libgnat/g-socthi__bsd.ads
+@@ -0,0 +1,272 @@
++------------------------------------------------------------------------------
++-- --
++-- GNAT COMPILER COMPONENTS --
++-- --
++-- G N A T . S O C K E T S . T H I N --
++-- --
++-- S p e c --
++-- --
++-- Copyright (C) 2001-2024, AdaCore --
++-- --
++-- GNAT is free software; you can redistribute it and/or modify it under --
++-- terms of the GNU General Public License as published by the Free Soft- --
++-- ware Foundation; either version 3, or (at your option) any later ver- --
++-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
++-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
++-- or FITNESS FOR A PARTICULAR PURPOSE. --
++-- --
++-- As a special exception under Section 7 of GPL version 3, you are granted --
++-- additional permissions described in the GCC Runtime Library Exception, --
++-- version 3.1, as published by the Free Software Foundation. --
++-- --
++-- You should have received a copy of the GNU General Public License and --
++-- a copy of the GCC Runtime Library Exception along with this program; --
++-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
++-- <http://www.gnu.org/licenses/>. --
++-- --
++-- GNAT was originally developed by the GNAT team at New York University. --
++-- Extensive contributions were provided by Ada Core Technologies Inc. --
++-- --
++------------------------------------------------------------------------------
++
++-- This package provides a target dependent thin interface to the sockets
++-- layer for use by the GNAT.Sockets package (g-socket.ads). This package
++-- should not be directly with'ed by an applications program.
++
++-- This is the default version
++
++with Interfaces.C;
++
++with GNAT.OS_Lib;
++with GNAT.Sockets.Thin_Common;
++
++with System;
++with System.CRTL;
++
++package GNAT.Sockets.Thin is
++
++ -- This package is intended for hosts implementing BSD sockets with a
++ -- standard interface. It will be used as a default for all the platforms
++ -- that do not have a specific version of this file.
++
++ use Thin_Common;
++
++ package C renames Interfaces.C;
++
++ function Socket_Errno return Integer renames GNAT.OS_Lib.Errno;
++ -- Returns last socket error number
++
++ function Socket_Error_Message (Errno : Integer) return String;
++ -- Returns the error message string for the error number Errno. If Errno is
++ -- not known, returns "Unknown system error".
++
++ function Host_Errno return Integer;
++ pragma Import (C, Host_Errno, "__gnat_get_h_errno");
++ -- Returns last host error number
++
++ package Host_Error_Messages is
++
++ function Host_Error_Message (H_Errno : Integer) return String;
++ -- Returns the error message string for the host error number H_Errno.
++ -- If H_Errno is not known, returns "Unknown system error".
++
++ end Host_Error_Messages;
++
++ --------------------------------
++ -- Standard library functions --
++ --------------------------------
++
++ function C_Accept
++ (S : C.int;
++ Addr : System.Address;
++ Addrlen : not null access C.int) return C.int;
++
++ function C_Bind
++ (S : C.int;
++ Name : System.Address;
++ Namelen : C.int) return C.int;
++
++ function C_Close
++ (Fd : C.int) return C.int;
++
++ function C_Connect
++ (S : C.int;
++ Name : System.Address;
++ Namelen : C.int) return C.int;
++
++ function C_Gethostname
++ (Name : System.Address;
++ Namelen : C.size_t) return C.int;
++
++ function C_Getpeername
++ (S : C.int;
++ Name : System.Address;
++ Namelen : not null access C.int) return C.int;
++
++ function C_Getsockname
++ (S : C.int;
++ Name : System.Address;
++ Namelen : not null access C.int) return C.int;
++
++ function C_Getsockopt
++ (S : C.int;
++ Level : C.int;
++ Optname : C.int;
++ Optval : System.Address;
++ Optlen : not null access C.int) return C.int;
++
++ function Socket_Ioctl
++ (S : C.int;
++ Req : SOSC.IOCTL_Req_T;
++ Arg : access C.int) return C.int;
++
++ function C_Listen
++ (S : C.int;
++ Backlog : C.int) return C.int;
++
++ function C_Recv
++ (S : C.int;
++ Msg : System.Address;
++ Len : C.size_t;
++ Flags : C.int) return C.int;
++
++ function C_Recvfrom
++ (S : C.int;
++ Msg : System.Address;
++ Len : C.size_t;
++ Flags : C.int;
++ From : System.Address;
++ Fromlen : not null access C.int) return C.int;
++
++ function C_Recvmsg
++ (S : C.int;
++ Msg : System.Address;
++ Flags : C.int) return System.CRTL.ssize_t;
++
++ function C_Select
++ (Nfds : C.int;
++ Readfds : access Fd_Set;
++ Writefds : access Fd_Set;
++ Exceptfds : access Fd_Set;
++ Timeout : Timeval_Access) return C.int;
++
++ function C_Sendmsg
++ (S : C.int;
++ Msg : System.Address;
++ Flags : C.int) return System.CRTL.ssize_t;
++
++ function C_Sendto
++ (S : C.int;
++ Msg : System.Address;
++ Len : C.size_t;
++ Flags : C.int;
++ To : System.Address;
++ Tolen : C.int) return C.int;
++
++ function C_Setsockopt
++ (S : C.int;
++ Level : C.int;
++ Optname : C.int;
++ Optval : System.Address;
++ Optlen : C.int) return C.int;
++
++ function C_Shutdown
++ (S : C.int;
++ How : C.int) return C.int;
++
++ function C_Socket
++ (Domain : C.int;
++ Typ : C.int;
++ Protocol : C.int) return C.int;
++
++ function C_System
++ (Command : System.Address) return C.int;
++
++ Default_Socket_Pair_Family : constant := SOSC.AF_UNIX;
++ -- UNIX has socketpair system call and AF_UNIX family is widely supported
++
++ function C_Socketpair
++ (Domain : C.int;
++ Typ : C.int;
++ Protocol : C.int;
++ Fds : not null access Fd_Pair) return C.int;
++ -- Creates pair of connected sockets
++
++ -------------------------------------------------------
++ -- Signalling file descriptors for selector abortion --
++ -------------------------------------------------------
++
++ package Signalling_Fds is
++
++ function Create (Fds : not null access Fd_Pair) return C.int;
++ pragma Convention (C, Create);
++ -- Create a pair of connected descriptors suitable for use with C_Select
++ -- (used for signalling in Selector objects).
++
++ function Read (Rsig : C.int) return C.int;
++ pragma Convention (C, Read);
++ -- Read one byte of data from rsig, the read end of a pair of signalling
++ -- fds created by Create_Signalling_Fds.
++
++ function Write (Wsig : C.int) return C.int;
++ pragma Convention (C, Write);
++ -- Write one byte of data to wsig, the write end of a pair of signalling
++ -- fds created by Create_Signalling_Fds.
++
++ procedure Close (Sig : C.int);
++ pragma Convention (C, Close);
++ -- Close one end of a pair of signalling fds (ignoring any error)
++
++ end Signalling_Fds;
++
++ -------------------------------------------
++ -- Nonreentrant network databases access --
++ -------------------------------------------
++
++ -- The following are used only on systems that have nonreentrant
++ -- getXXXbyYYY functions, and do NOT have corresponding getXXXbyYYY_
++ -- functions. Currently, LynxOS is the only such system.
++
++ function Nonreentrant_Gethostbyname
++ (Name : C.char_array) return Hostent_Access;
++
++ function Nonreentrant_Gethostbyaddr
++ (Addr : System.Address;
++ Addr_Len : C.int;
++ Addr_Type : C.int) return Hostent_Access;
++
++ function Nonreentrant_Getservbyname
++ (Name : C.char_array;
++ Proto : C.char_array) return Servent_Access;
++
++ function Nonreentrant_Getservbyport
++ (Port : C.int;
++ Proto : C.char_array) return Servent_Access;
++
++ procedure Initialize;
++ procedure Finalize;
++
++private
++ pragma Inline (C_Bind);
++ pragma Inline (C_Connect);
++ pragma Import (C, C_Close, "close");
++ pragma Import (C, C_Gethostname, "gethostname");
++ pragma Inline (C_Getpeername);
++ pragma Inline (C_Getsockname);
++ pragma Inline (C_Getsockopt);
++ pragma Import (C, C_Listen, "listen");
++ pragma Inline (C_Recv);
++ pragma Inline (C_Recvmsg);
++ pragma Import (C, C_Select, "select");
++ pragma Inline (C_Sendmsg);
++ pragma Inline (C_Setsockopt);
++ pragma Import (C, C_Shutdown, "shutdown");
++ pragma Import (C, C_Socketpair, "socketpair");
++ pragma Import (C, C_System, "system");
++
++ pragma Import (C, Nonreentrant_Gethostbyname, "gethostbyname");
++ pragma Inline (Nonreentrant_Gethostbyaddr);
++ pragma Import (C, Nonreentrant_Getservbyname, "getservbyname");
++ pragma Import (C, Nonreentrant_Getservbyport, "getservbyport");
++
++end GNAT.Sockets.Thin;
Index: pkgsrc/lang/gcc15-gnat/patches/patch-gcc_config.gcc
diff -u /dev/null pkgsrc/lang/gcc15-gnat/patches/patch-gcc_config.gcc:1.1
--- /dev/null Sat Jun 6 06:15:50 2026
+++ pkgsrc/lang/gcc15-gnat/patches/patch-gcc_config.gcc Sat Jun 6 06:15:50 2026
@@ -0,0 +1,14 @@
+$NetBSD: patch-gcc_config.gcc,v 1.1 2026/06/06 06:15:50 dkazankov Exp $
+
+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
+@@ -1992,6 +1992,7 @@
+ ;;
+ x86_64-*-netbsd*)
+ tm_file="${tm_file} i386/unix.h i386/att.h elfos.h ${nbsd_tm_file} i386/x86-64.h i386/netbsd64.h"
++ tmake_file="${tmake_file} i386/t-netbsd64"
+ extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
+ ;;
+ i[34567]86-*-openbsd*)
Index: pkgsrc/lang/gcc15-gnat/patches/patch-gcc_config_netbsd.h
diff -u /dev/null pkgsrc/lang/gcc15-gnat/patches/patch-gcc_config_netbsd.h:1.1
--- /dev/null Sat Jun 6 06:15:50 2026
+++ pkgsrc/lang/gcc15-gnat/patches/patch-gcc_config_netbsd.h Sat Jun 6 06:15:50 2026
@@ -0,0 +1,14 @@
+$NetBSD: patch-gcc_config_netbsd.h,v 1.1 2026/06/06 06:15:50 dkazankov Exp $
+
+NetBSD doesn't have a -ldl.
+
+
+--- gcc/config/netbsd.h.orig 2025-08-07 23:51:40.599350224 -0700
++++ gcc/config/netbsd.h 2025-11-06 12:07:01.954484996 -0800
+@@ -166,3 +166,6 @@ along with GCC; see the file COPYING3.
+ do { \
+ netbsd_patch_builtins (); \
+ } while(0)
++
++/* NetBSD does not have a dl library. */
++#define DL_LIBRARY ""
Index: pkgsrc/lang/gcc15-gnat/patches/patch-libgcc_config.host
diff -u /dev/null pkgsrc/lang/gcc15-gnat/patches/patch-libgcc_config.host:1.1
--- /dev/null Sat Jun 6 06:15:50 2026
+++ pkgsrc/lang/gcc15-gnat/patches/patch-libgcc_config.host Sat Jun 6 06:15:50 2026
@@ -0,0 +1,15 @@
+$NetBSD: patch-libgcc_config.host,v 1.1 2026/06/06 06:15:50 dkazankov Exp $
+
+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*)
+ aarch64*-*-netbsd*)
+ extra_parts="$extra_parts crtfastmath.o"
+ tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
++ tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc"
+ 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
Index: pkgsrc/lang/gcc15-gnat/patches/patch-libgcc_enable-execute-stack-mprotect.c
diff -u /dev/null pkgsrc/lang/gcc15-gnat/patches/patch-libgcc_enable-execute-stack-mprotect.c:1.1
--- /dev/null Sat Jun 6 06:15:50 2026
+++ pkgsrc/lang/gcc15-gnat/patches/patch-libgcc_enable-execute-stack-mprotect.c Sat Jun 6 06:15:50 2026
@@ -0,0 +1,15 @@
+$NetBSD: patch-libgcc_enable-execute-stack-mprotect.c,v 1.1 2026/06/06 06:15:50 dkazankov Exp $
+
+Avoid GCC warning?
+
+
+--- libgcc/enable-execute-stack-mprotect.c.orig 2025-08-07 23:51:44.916422240 -0700
++++ libgcc/enable-execute-stack-mprotect.c 2025-11-05 20:05:27.517319554 -0800
+@@ -30,7 +30,6 @@
+
+ static int need_enable_exec_stack;
+
+-static void check_enabling (void) __attribute__ ((unused));
+ extern void __enable_execute_stack (void *);
+
+ #if defined __sun__ && defined __svr4__
Home |
Main Index |
Thread Index |
Old Index