Re: [PATCH v2 00/20] aarch64-gnu port & GNU/Hurd on AArch64 progress

2024-03-23 Thread Samuel Thibault
Hello,

Sergey Bugaev, le sam. 23 mars 2024 20:32:41 +0300, a ecrit:
> This is v2 of my work on the aarch64-gnu port, aka GNU/Hurd on 64-bit
> ARM. v1 is here [0].

Thanks!

I applied the easy parts: patches 1-6 and 18 for now.

Samuel



[PATCH v2 12/20] mach: Declare the new thread_set_self_state () trap

2024-03-23 Thread Sergey Bugaev
This is a new Mach trap for setting the state of the current thread, as
if with thread_set_state () RPC.  The trap has been added to GNU Mach as
a part of the AArch64 port, to make it possible to implement sigreturn
in glibc; however, the trap itself is fully arch-independent.

There does not seem to be an easy way to feature-test, in a header, for
existence of traps in the Mach version being built against.  Instead,
just declare the trap prototype unconditionally, and don't add an
exported version for now.

Signed-off-by: Sergey Bugaev 
---
 sysdeps/mach/include/mach/mach_traps.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/sysdeps/mach/include/mach/mach_traps.h 
b/sysdeps/mach/include/mach/mach_traps.h
index c4334952..a942212c 100644
--- a/sysdeps/mach/include/mach/mach_traps.h
+++ b/sysdeps/mach/include/mach/mach_traps.h
@@ -19,5 +19,12 @@ kern_return_t __thread_switch (mach_port_t new_thread,
 libc_hidden_proto (__thread_switch)
 kern_return_t __evc_wait (unsigned int event);
 libc_hidden_proto (__evc_wait)
+
+/* Set current thread's state, as if with thread_set_state() RPC.
+   This syscall is only really available in recent enough GNU Mach.  */
+extern kern_return_t __thread_set_self_state (int flavor,
+ natural_t *new_state,
+ natural_t new_state_count);
+libc_hidden_proto (__thread_set_self_state)
 #endif
 #endif
-- 
2.44.0




[PATCH v2 10/20] aarch64: Allow building without kernel support for BTI

2024-03-23 Thread Sergey Bugaev
If PROT_BTI is not defined, turn _dl_bti_protect () into a no-op.

We intend to support BTI & PROT_BTI on the Hurd eventually, but we're
not there yet.

Signed-off-by: Sergey Bugaev 
---
 sysdeps/aarch64/dl-bti.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/sysdeps/aarch64/dl-bti.c b/sysdeps/aarch64/dl-bti.c
index fd0d308a..4cf85630 100644
--- a/sysdeps/aarch64/dl-bti.c
+++ b/sysdeps/aarch64/dl-bti.c
@@ -28,6 +28,7 @@
 
 /* Enable BTI protection for MAP.  */
 
+#ifdef PROT_BTI
 void
 _dl_bti_protect (struct link_map *map, int fd)
 {
@@ -59,6 +60,15 @@ _dl_bti_protect (struct link_map *map, int fd)
   }
 }
 
+#else /* PROT_BTI */
+void
+_dl_bti_protect (struct link_map *map, int fd)
+{
+  (void) map;
+  (void) fd;
+}
+#endif
+
 
 static void
 bti_failed (struct link_map *l, const char *program)
-- 
2.44.0




[PATCH v2 15/20] hurd: Implement longjmp for AArch64

2024-03-23 Thread Sergey Bugaev
This is based on the generic AArch64 version, but it additionally
respects and updates the Hurd sigstate.

Signed-off-by: Sergey Bugaev 
---

Same patch as last time.

Something somewhere here should probably be hooked up to the
hurd_userlink mechanism; I haven't looked into that.

 sysdeps/aarch64/htl/tcb-offsets.sym  |   5 +
 sysdeps/mach/hurd/aarch64/Makefile   |  24 +++
 sysdeps/mach/hurd/aarch64/longjmp_chk.S  | 173 +++
 sysdeps/mach/hurd/aarch64/__longjmp.S| 150 
 sysdeps/mach/hurd/aarch64/signal-defines.sym |  10 ++
 5 files changed, 362 insertions(+)
 create mode 100644 sysdeps/aarch64/htl/tcb-offsets.sym
 create mode 100644 sysdeps/mach/hurd/aarch64/Makefile
 create mode 100644 sysdeps/mach/hurd/aarch64/longjmp_chk.S
 create mode 100644 sysdeps/mach/hurd/aarch64/__longjmp.S
 create mode 100644 sysdeps/mach/hurd/aarch64/signal-defines.sym

diff --git a/sysdeps/aarch64/htl/tcb-offsets.sym 
b/sysdeps/aarch64/htl/tcb-offsets.sym
new file mode 100644
index ..56140780
--- /dev/null
+++ b/sysdeps/aarch64/htl/tcb-offsets.sym
@@ -0,0 +1,5 @@
+#include 
+#include 
+#include 
+
+SIGSTATE_OFFSET offsetof (tcbprehead_t, _hurd_sigstate) - sizeof 
(tcbprehead_t)
diff --git a/sysdeps/mach/hurd/aarch64/Makefile 
b/sysdeps/mach/hurd/aarch64/Makefile
new file mode 100644
index ..9210d436
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/Makefile
@@ -0,0 +1,24 @@
+# Copyright (C) 2020-2024 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# .
+
+ifeq ($(subdir),debug)
+gen-as-const-headers += signal-defines.sym
+endif
+
+ifeq ($(subdir),setjmp)
+gen-as-const-headers += signal-defines.sym
+endif
diff --git a/sysdeps/mach/hurd/aarch64/longjmp_chk.S 
b/sysdeps/mach/hurd/aarch64/longjmp_chk.S
new file mode 100644
index ..90f062df
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/longjmp_chk.S
@@ -0,0 +1,173 @@
+/* Copyright (C) 1997-2024 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   .  */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SS_ONSTACK 1
+#define SS_ONSTACK_BIT 0
+
+   .section .rodata.str1.1,"aMS",%progbits,1
+   .type   longjmp_msg,%object
+longjmp_msg:
+   .string "longjmp causes uninitialized stack frame"
+   .size   longjmp_msg, .-longjmp_msg
+   .text
+
+# define CALL_FAIL \
+   adrpx0, longjmp_msg;\
+   add x0, x0, :lo12:longjmp_msg;  \
+   b   HIDDEN_JUMPTARGET(__fortify_fail)   \
+
+/* Jump to the position specified by ENV, causing the
+   setjmp call there to return VAL, or 1 if VAL is 0.
+   void __longjmp (__jmp_buf env, int val).  */
+.text
+ENTRY(longjmp_chk)
+   cfi_def_cfa(x0, 0)
+   cfi_offset(x19, JB_X19<<3)
+   cfi_offset(x20, JB_X20<<3)
+   cfi_offset(x21, JB_X21<<3)
+   cfi_offset(x22, JB_X22<<3)
+   cfi_offset(x23, JB_X23<<3)
+   cfi_offset(x24, JB_X24<<3)
+   cfi_offset(x25, JB_X25<<3)
+   cfi_offset(x26, JB_X26<<3)
+   cfi_offset(x27, JB_X27<<3)
+   cfi_offset(x28, JB_X28<<3)
+   cfi_offset(x29, JB_X29<<3)
+   cfi_offset(x30, JB_LR<<3)
+
+   cfi_offset( d8, JB_D8<<3)
+   cfi_offset( d9, JB_D9<<3)
+   cfi_offset(d10, JB_D10<<3)
+   cfi_offset(d11, JB_D11<<3)
+   cfi_offset(d12, JB_D12<<3)
+   cfi_offset(d13, JB_D13<<3)
+   cfi_offset(d14, JB_D14<<3)
+   cfi_offset(d15, JB_D15<<3)
+
+   

[PATCH v2 17/20] hurd: Add an AArch64 signal implementation

2024-03-23 Thread Sergey Bugaev
Signed-off-by: Sergey Bugaev 
---
 sysdeps/mach/hurd/aarch64/Makefile  |   4 +
 sysdeps/mach/hurd/aarch64/bits/sigcontext.h |  96 ++
 sysdeps/mach/hurd/aarch64/exc2signal.c  | 149 +
 sysdeps/mach/hurd/aarch64/intr-msg.h| 123 
 sysdeps/mach/hurd/aarch64/sigreturn.c   | 127 
 sysdeps/mach/hurd/aarch64/trampoline.c  | 325 
 6 files changed, 824 insertions(+)
 create mode 100644 sysdeps/mach/hurd/aarch64/bits/sigcontext.h
 create mode 100644 sysdeps/mach/hurd/aarch64/exc2signal.c
 create mode 100644 sysdeps/mach/hurd/aarch64/intr-msg.h
 create mode 100644 sysdeps/mach/hurd/aarch64/sigreturn.c
 create mode 100644 sysdeps/mach/hurd/aarch64/trampoline.c

diff --git a/sysdeps/mach/hurd/aarch64/Makefile 
b/sysdeps/mach/hurd/aarch64/Makefile
index 9210d436..6cc831d6 100644
--- a/sysdeps/mach/hurd/aarch64/Makefile
+++ b/sysdeps/mach/hurd/aarch64/Makefile
@@ -22,3 +22,7 @@ endif
 ifeq ($(subdir),setjmp)
 gen-as-const-headers += signal-defines.sym
 endif
+
+ifeq ($(subdir),signal)
+CFLAGS-sigreturn.c += -mgeneral-regs-only
+endif
diff --git a/sysdeps/mach/hurd/aarch64/bits/sigcontext.h 
b/sysdeps/mach/hurd/aarch64/bits/sigcontext.h
new file mode 100644
index ..163523fa
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/bits/sigcontext.h
@@ -0,0 +1,96 @@
+/* Machine-dependent signal context structure for GNU Hurd.  AArch64 version.
+   Copyright (C) 1991-2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#ifndef _BITS_SIGCONTEXT_H
+#define _BITS_SIGCONTEXT_H 1
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never use  directly; include  instead."
+#endif
+
+/* Signal handlers are actually called:
+   void handler (int sig, int code, struct sigcontext *scp);  */
+
+#include 
+#include 
+
+/* State of this thread when the signal was taken.  */
+struct sigcontext
+  {
+/* These first members are machine-independent.  */
+
+int sc_onstack;/* Nonzero if running on sigstack.  */
+__sigset_t sc_mask;/* Blocked signals to restore.  */
+
+/* MiG reply port this thread is using.  */
+unsigned int sc_reply_port;
+
+/* Port this thread is doing an interruptible RPC on.  */
+unsigned int sc_intr_port;
+
+/* Error code associated with this signal (interpreted as `error_t').  */
+int sc_error;
+
+/* Make sure the below members are properly aligned, and not packed
+   together with sc_error -- otherwise the layout won't match that of
+   aarch64_thread_state.  */
+int sc_pad1;
+
+/* All following members are machine-dependent.  The rest of this
+   structure is written to be laid out identically to:
+   {
+struct aarch64_thread_state basic;
+struct aarch64_float_state fpu;
+   }
+   trampoline.c knows this, so it must be changed if this changes.  */
+
+#define sc_aarch64_thread_state sc_x[0] /* Beginning of correspondence.  */
+long sc_x[31];
+long sc_sp;
+long sc_pc;
+long sc_tpidr_el0;
+long sc_cpsr;
+
+#define sc_aarch64_float_state sc_v[0]
+__int128_t sc_v[32];
+long sc_fpsr;
+long sc_fpcr;
+  };
+
+/* Traditional BSD names for some members.  */
+#define sc_fp  sc_x[29]/* Frame pointer.  */
+#define sc_ps  sc_cpsr
+
+
+/* The deprecated sigcode values below are passed as an extra, non-portable
+   argument to regular signal handlers.  You should use SA_SIGINFO handlers
+   instead, which use the standard POSIX signal codes.  */
+
+/* Codes for SIGFPE.  */
+#define FPE_INTOVF_TRAP0x1 /* integer overflow */
+#define FPE_INTDIV_FAULT   0x2 /* integer divide by zero */
+#define FPE_FLTOVF_FAULT   0x3 /* floating overflow */
+#define FPE_FLTDIV_FAULT   0x4 /* floating divide by zero */
+#define FPE_FLTUND_FAULT   0x5 /* floating underflow */
+#define FPE_SUBRNG_FAULT   0x7 /* BOUNDS instruction failed */
+#define FPE_FLTDNR_FAULT   0x8 /* denormalized operand */
+#define FPE_FLTINX_FAULT   0x9 /* floating loss of precision */
+#define FPE_EMERR_FAULT0xa /* mysterious emulation error 33 */
+#define FPE_EMBND_FAULT0xb /* emulation BOUNDS instruction 
failed */
+
+#endif /* bits/sigcontext.h */

[PATCH v2 04/20] hurd: Disable Prefer_MAP_32BIT_EXEC on non-x86_64 for now

2024-03-23 Thread Sergey Bugaev
While we could support it on any architecture, the tunable is currently
only defined on x86_64.

Signed-off-by: Sergey Bugaev 
---
 sysdeps/mach/hurd/dl-sysdep.c | 2 +-
 sysdeps/mach/hurd/mmap.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c
index 43129a1e..6ba00e41 100644
--- a/sysdeps/mach/hurd/dl-sysdep.c
+++ b/sysdeps/mach/hurd/dl-sysdep.c
@@ -457,7 +457,7 @@ __mmap (void *addr, size_t len, int prot, int flags, int 
fd, off_t offset)
   if (prot & PROT_EXEC)
 vmprot |= VM_PROT_EXECUTE;
 
-#ifdef __LP64__
+#ifdef __x86_64__
   if ((addr == NULL) && (prot & PROT_EXEC)
   && HAS_ARCH_FEATURE (Prefer_MAP_32BIT_EXEC))
 flags |= MAP_32BIT;
diff --git a/sysdeps/mach/hurd/mmap.c b/sysdeps/mach/hurd/mmap.c
index 7b945610..30e369f0 100644
--- a/sysdeps/mach/hurd/mmap.c
+++ b/sysdeps/mach/hurd/mmap.c
@@ -60,7 +60,7 @@ __mmap (void *addr, size_t len, int prot, int flags, int fd, 
off_t offset)
   copy = ! (flags & MAP_SHARED);
   anywhere = ! (flags & MAP_FIXED);
 
-#ifdef __LP64__
+#ifdef __x86_64__
   if ((addr == NULL) && (prot & PROT_EXEC)
   && HAS_ARCH_FEATURE (Prefer_MAP_32BIT_EXEC))
 flags |= MAP_32BIT;
-- 
2.44.0




[PATCH v2 13/20] hurd: Add a basic AArch64 port

2024-03-23 Thread Sergey Bugaev
The following commits will add TLS, HTL, and the signal bits.

Signed-off-by: Sergey Bugaev 
---
 sysdeps/mach/hurd/aarch64/Implies|  3 ++
 sysdeps/mach/hurd/aarch64/longjmp-ts.c   | 49 ++
 sysdeps/mach/hurd/aarch64/shlib-versions |  2 +
 sysdeps/mach/hurd/aarch64/static-start.S | 52 
 sysdeps/mach/hurd/aarch64/vm_param.h | 24 +++
 5 files changed, 130 insertions(+)
 create mode 100644 sysdeps/mach/hurd/aarch64/Implies
 create mode 100644 sysdeps/mach/hurd/aarch64/longjmp-ts.c
 create mode 100644 sysdeps/mach/hurd/aarch64/shlib-versions
 create mode 100644 sysdeps/mach/hurd/aarch64/static-start.S
 create mode 100644 sysdeps/mach/hurd/aarch64/vm_param.h

diff --git a/sysdeps/mach/hurd/aarch64/Implies 
b/sysdeps/mach/hurd/aarch64/Implies
new file mode 100644
index ..02af165f
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/Implies
@@ -0,0 +1,3 @@
+mach/hurd/htl
+aarch64/htl
+mach/hurd/aarch64/htl
diff --git a/sysdeps/mach/hurd/aarch64/longjmp-ts.c 
b/sysdeps/mach/hurd/aarch64/longjmp-ts.c
new file mode 100644
index ..2fcb7493
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/longjmp-ts.c
@@ -0,0 +1,49 @@
+/* Perform a `longjmp' on a Mach thread_state.  AArch64 version.
+   Copyright (C) 1991-2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#include 
+#include 
+#include 
+
+
+/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'.  */
+
+void
+_hurd_longjmp_thread_state (void *state, jmp_buf env, int val)
+{
+  struct aarch64_thread_state *ts = state;
+
+  ts->x[19] = env[0].__jmpbuf[JB_X19];
+  ts->x[20] = env[0].__jmpbuf[JB_X20];
+  ts->x[21] = env[0].__jmpbuf[JB_X21];
+  ts->x[22] = env[0].__jmpbuf[JB_X22];
+  ts->x[23] = env[0].__jmpbuf[JB_X23];
+  ts->x[24] = env[0].__jmpbuf[JB_X24];
+  ts->x[25] = env[0].__jmpbuf[JB_X25];
+  ts->x[26] = env[0].__jmpbuf[JB_X26];
+  ts->x[27] = env[0].__jmpbuf[JB_X27];
+  ts->x[28] = env[0].__jmpbuf[JB_X28];
+  ts->x[29] = env[0].__jmpbuf[JB_X29];
+
+  /* XXX: We're ignoring all the d[] (SIMD) registers.
+ Is that fine?  */
+
+  ts->pc = PTR_DEMANGLE (env[0].__jmpbuf[JB_LR]);
+  ts->sp = _jmpbuf_sp (env[0].__jmpbuf);
+  ts->x[0] = val ?: 1;
+}
diff --git a/sysdeps/mach/hurd/aarch64/shlib-versions 
b/sysdeps/mach/hurd/aarch64/shlib-versions
new file mode 100644
index ..b9e7c2cb
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/shlib-versions
@@ -0,0 +1,2 @@
+DEFAULTGLIBC_2.40
+ld=ld-aarch64.so.1
diff --git a/sysdeps/mach/hurd/aarch64/static-start.S 
b/sysdeps/mach/hurd/aarch64/static-start.S
new file mode 100644
index ..e09865c4
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/static-start.S
@@ -0,0 +1,52 @@
+/* Startup code for statically linked Hurd/AArch64 binaries.
+   Copyright (C) 1998-2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#include 
+
+/* This is the actual entry point for statically linked aarch64-gnu 
executables,
+   the very first code to run in a process.  */
+
+   .text
+ENTRY(_start)
+   /* Set up the initial stack frame.  */
+   cfi_undefined (x30)
+   mov x29, #0
+   mov x30, #0
+
+   /* Pre-fill GOT entries for select ifunc routines that may get
+  called during _hurd_stack_setup () with baseline implementations.  */
+   adrpx1, __memcpy_generic
+   add x1, x1, #:lo12:__memcpy_generic
+   adrpx0, :got:memcpy
+   str x1, [x0, :got_lo12:memcpy]
+
+   adrpx1, __strlen_generic
+   add x1, x1, 

[PATCH v2 18/20] htl: Implement some support for TLS_DTV_AT_TP

2024-03-23 Thread Sergey Bugaev
Signed-off-by: Sergey Bugaev 
---
 htl/pt-create.c |  2 ++
 sysdeps/htl/dl-thread_gscope_wait.c | 16 ++--
 sysdeps/mach/hurd/htl/pt-sysdep.c   |  9 +
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/htl/pt-create.c b/htl/pt-create.c
index fac61f1b..8a735d99 100644
--- a/htl/pt-create.c
+++ b/htl/pt-create.c
@@ -177,7 +177,9 @@ __pthread_create_internal (struct __pthread **thread,
   err = ENOMEM;
   goto failed_thread_tls_alloc;
 }
+#if TLS_TCB_AT_TP
   pthread->tcb->tcb = pthread->tcb;
+#endif
 
   /* And initialize the rest of the machine context.  This may include
  additional machine- and system-specific initializations that
diff --git a/sysdeps/htl/dl-thread_gscope_wait.c 
b/sysdeps/htl/dl-thread_gscope_wait.c
index 90a9a798..ee0a3165 100644
--- a/sysdeps/htl/dl-thread_gscope_wait.c
+++ b/sysdeps/htl/dl-thread_gscope_wait.c
@@ -20,6 +20,18 @@
 #include 
 #include 
 
+static inline int *
+thread_gscope_flag (struct __pthread *t)
+{
+#if TLS_TCB_AT_TP
+  return >tcb->gscope_flag;
+#elif TLS_DTV_AT_TP
+  return &((tcbprehead_t *) t->tcb - 1)->gscope_flag;
+#else
+# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+#endif
+}
+
 void
 __thread_gscope_wait (void)
 {
@@ -33,10 +45,10 @@ __thread_gscope_wait (void)
   for (i = 0; i < GL (dl_pthread_num_threads); ++i)
 {
   t = GL (dl_pthread_threads[i]);
-  if (t == NULL || t->tcb->gscope_flag == THREAD_GSCOPE_FLAG_UNUSED)
+  if (t == NULL || *thread_gscope_flag (t) == THREAD_GSCOPE_FLAG_UNUSED)
 continue;
 
-  gscope_flagp = >tcb->gscope_flag;
+  gscope_flagp = thread_gscope_flag (t);
 
   /* We have to wait until this thread is done with the global
  scope.  First tell the thread that we are waiting and
diff --git a/sysdeps/mach/hurd/htl/pt-sysdep.c 
b/sysdeps/mach/hurd/htl/pt-sysdep.c
index 270e7753..5372cbf7 100644
--- a/sysdeps/mach/hurd/htl/pt-sysdep.c
+++ b/sysdeps/mach/hurd/htl/pt-sysdep.c
@@ -100,7 +100,16 @@ _init_routine (void *stack)
  to the new stack.  Pretend it wasn't allocated so that it remains
  valid if the main thread terminates.  */
   thread->stack = 0;
+#if TLS_TCB_AT_TP
   thread->tcb = THREAD_SELF;
+#elif TLS_DTV_AT_TP
+  /* Assuming THREAD_SELF is implemented as subtracting TLS_PRE_TCB_SIZE
+ from the value of a thread pointer regsiter, this should optimize
+ down to simply reading that register.  */
+  thread->tcb = (tcbhead_t *) (((char *) THREAD_SELF) + TLS_PRE_TCB_SIZE);
+#else
+# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+#endif
 
 #ifndef PAGESIZE
   __pthread_default_attr.__guardsize = __vm_page_size;
-- 
2.44.0




[PATCH v2 08/20] aarch64: Add dl-procinfo

2024-03-23 Thread Sergey Bugaev
This is based on the Linux version, but doesn't define
GLRO(dl_aarch64_cap_flags) and implement _dl_hwcap_string (which seems
unused anyway) based on Linux HWCAP bit values.

Signed-off-by: Sergey Bugaev 
---
 sysdeps/aarch64/dl-procinfo.c | 59 +++
 sysdeps/aarch64/dl-procinfo.h | 38 ++
 2 files changed, 97 insertions(+)
 create mode 100644 sysdeps/aarch64/dl-procinfo.c
 create mode 100644 sysdeps/aarch64/dl-procinfo.h

diff --git a/sysdeps/aarch64/dl-procinfo.c b/sysdeps/aarch64/dl-procinfo.c
new file mode 100644
index ..5a51edbc
--- /dev/null
+++ b/sysdeps/aarch64/dl-procinfo.c
@@ -0,0 +1,59 @@
+/* Data for AArch64 version of processor capability information.
+   Copyright (C) 2017-2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+/* If anything should be added here check whether the size of each string
+   is still ok with the given array size.
+
+   All the #ifdefs in the definitions are quite irritating but
+   necessary if we want to avoid duplicating the information.  There
+   are three different modes:
+
+   - PROCINFO_DECL is defined.  This means we are only interested in
+ declarations.
+
+   - PROCINFO_DECL is not defined:
+
+ + if SHARED is defined the file is included in an array
+   initializer.  The .element = { ... } syntax is needed.
+
+ + if SHARED is not defined a normal array initialization is
+   needed.
+  */
+
+#ifndef PROCINFO_CLASS
+# define PROCINFO_CLASS
+#endif
+
+#if !IS_IN (ldconfig)
+# if !defined PROCINFO_DECL && defined SHARED
+  ._dl_aarch64_cpu_features
+# else
+PROCINFO_CLASS struct cpu_features _dl_aarch64_cpu_features
+# endif
+# ifndef PROCINFO_DECL
+= { }
+# endif
+# if !defined SHARED || defined PROCINFO_DECL
+;
+# else
+,
+# endif
+#endif
+
+#undef PROCINFO_DECL
+#undef PROCINFO_CLASS
diff --git a/sysdeps/aarch64/dl-procinfo.h b/sysdeps/aarch64/dl-procinfo.h
new file mode 100644
index ..176de5cd
--- /dev/null
+++ b/sysdeps/aarch64/dl-procinfo.h
@@ -0,0 +1,38 @@
+/* Processor capability information handling macros - aarch64 version.
+   Copyright (C) 2017-2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#ifndef _DL_PROCINFO_H
+#define _DL_PROCINFO_H 1
+
+#include 
+#include 
+#include 
+#include 
+
+/* We cannot provide a general printing function.  */
+#define _dl_procinfo(type, word) -1
+
+/* No additional library search paths.  */
+#define HWCAP_IMPORTANT HWCAP_ATOMICS
+
+/* There're no platforms to filter out.  */
+#define _DL_HWCAP_PLATFORM 0
+
+#define _dl_string_platform(str) (-1)
+
+#endif /* dl-procinfo.h */
-- 
2.44.0




[PATCH v2 11/20] mach: Add a basic AArch64 port

2024-03-23 Thread Sergey Bugaev
This doesn't add any of the Hurd- or HTL-specific bits yet.

Signed-off-by: Sergey Bugaev 
---
 mach/Makefile  |   1 +
 sysdeps/mach/aarch64/bits/mach/param.h |  24 ++
 sysdeps/mach/aarch64/cpu-features.c| 109 +
 sysdeps/mach/aarch64/sys/ucontext.h|  73 +
 sysdeps/mach/aarch64/sysdep.h  |  52 
 sysdeps/mach/aarch64/thread_state.h|  49 +++
 sysdeps/mach/configure |   1 +
 sysdeps/mach/configure.ac  |   1 +
 8 files changed, 310 insertions(+)
 create mode 100644 sysdeps/mach/aarch64/bits/mach/param.h
 create mode 100644 sysdeps/mach/aarch64/cpu-features.c
 create mode 100644 sysdeps/mach/aarch64/sys/ucontext.h
 create mode 100644 sysdeps/mach/aarch64/sysdep.h
 create mode 100644 sysdeps/mach/aarch64/thread_state.h

diff --git a/mach/Makefile b/mach/Makefile
index 0ea3b3c1..92394951 100644
--- a/mach/Makefile
+++ b/mach/Makefile
@@ -56,6 +56,7 @@ generated =
 
 # Avoid ssp before TLS is initialized.
 CFLAGS-mach_init.o = $(no-stack-protector)
+CFLAGS-RPC_aarch64_get_hwcaps.o = $(no-stack-protector)
 CFLAGS-RPC_vm_statistics.o = $(no-stack-protector)
 CFLAGS-RPC_vm_map.o = $(no-stack-protector)
 CFLAGS-RPC_vm_protect.o = $(no-stack-protector)
diff --git a/sysdeps/mach/aarch64/bits/mach/param.h 
b/sysdeps/mach/aarch64/bits/mach/param.h
new file mode 100644
index ..4f7b76ed
--- /dev/null
+++ b/sysdeps/mach/aarch64/bits/mach/param.h
@@ -0,0 +1,24 @@
+/* Old-style Unix parameters and limits.  aarch64 Mach version.
+   Copyright (C) 1993-2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#ifndef _SYS_PARAM_H
+# error "Never use  directly; include  
instead."
+#endif
+
+/* There is no EXEC_PAGESIZE.  Use vm_page_size or getpagesize ()
+   or sysconf (_SC_PAGESIZE) instead.  */
diff --git a/sysdeps/mach/aarch64/cpu-features.c 
b/sysdeps/mach/aarch64/cpu-features.c
new file mode 100644
index ..1d1f5201
--- /dev/null
+++ b/sysdeps/mach/aarch64/cpu-features.c
@@ -0,0 +1,109 @@
+/* Initialize CPU feature data.  Mach AArch64 version.
+   This file is part of the GNU C Library.
+   Copyright (C) 2017-2024 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DCZID_DZP_MASK (1 << 4)
+#define DCZID_BS_MASK (0xf)
+
+/* The maximal set of permitted tags that the MTE random tag generation
+   instruction may use.  We exclude tag 0 because a) we want to reserve
+   that for the libc heap structures and b) because it makes it easier
+   to see when pointer have been correctly tagged.  */
+#define MTE_ALLOWED_TAGS (0xfffe << PR_MTE_TAG_SHIFT)
+
+struct cpu_list
+{
+  const char *name;
+  size_t len;
+  uint64_t midr;
+};
+
+static const struct cpu_list cpu_list[] =
+{
+#define CPU_LIST_ENTRY(__str, __num) { __str, sizeof (__str) - 1, __num }
+  CPU_LIST_ENTRY ("thunderxt88",0x430F0A10),
+  CPU_LIST_ENTRY ("thunderx2t99",   0x431F0AF0),
+  CPU_LIST_ENTRY ("thunderx2t99p1", 0x420F5160),
+  CPU_LIST_ENTRY ("ares",   0x411FD0C0),
+  CPU_LIST_ENTRY ("emag",   0x503F0001),
+  CPU_LIST_ENTRY ("kunpeng920", 0x481FD010),
+  CPU_LIST_ENTRY ("a64fx",  0x460F0010),
+  CPU_LIST_ENTRY ("generic",0x0),
+};
+
+static uint64_t
+get_midr_from_mcpu (const struct tunable_str_t *mcpu)
+{
+  for (int i = 0; i < array_length (cpu_list); i++)
+if (tunable_strcmp (mcpu, cpu_list[i].name, cpu_list[i].len))
+  return cpu_list[i].midr;
+
+  return UINT64_MAX;
+}
+
+static inline void
+init_cpu_features 

[PATCH v2 16/20] Add FPE_FLTIDO

2024-03-23 Thread Sergey Bugaev
This is a new si_code value for the SIGFPE signal that has been added
to FreeBSD, and is also going to be used on the Hurd.

Signed-off-by: Sergey Bugaev 
---

This makes sense, right?

We should probably define more codes still (see exception2signal in the
next patch).

 bits/siginfo-consts.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/bits/siginfo-consts.h b/bits/siginfo-consts.h
index 4eef775e..362a06a6 100644
--- a/bits/siginfo-consts.h
+++ b/bits/siginfo-consts.h
@@ -75,8 +75,10 @@ enum
 #  define FPE_FLTRES   FPE_FLTRES
   FPE_FLTINV,  /* Floating point invalid operation.  */
 #  define FPE_FLTINV   FPE_FLTINV
-  FPE_FLTSUB   /* Subscript out of range.  */
+  FPE_FLTSUB,  /* Subscript out of range.  */
 #  define FPE_FLTSUB   FPE_FLTSUB
+  FPE_FLTIDO   /* Input denormal operation.  */
+#  define FPE_FLTIDO   FPE_FLTIDO
 };
 
 /* `si_code' values for SIGSEGV signal.  */
-- 
2.44.0




[PATCH v2 19/20] htl: Add an AArch64 implementation

2024-03-23 Thread Sergey Bugaev
Signed-off-by: Sergey Bugaev 
---
 sysdeps/aarch64/htl/Makefile | 20 ++
 sysdeps/aarch64/htl/bits/pthreadtypes-arch.h | 36 ++
 sysdeps/aarch64/htl/machine-sp.h | 29 
 sysdeps/aarch64/htl/pt-machdep.h | 28 
 sysdeps/mach/hurd/aarch64/htl/pt-machdep.c   | 55 ++
 sysdeps/mach/hurd/aarch64/htl/pt-setup.c | 76 
 6 files changed, 244 insertions(+)
 create mode 100644 sysdeps/aarch64/htl/Makefile
 create mode 100644 sysdeps/aarch64/htl/bits/pthreadtypes-arch.h
 create mode 100644 sysdeps/aarch64/htl/machine-sp.h
 create mode 100644 sysdeps/aarch64/htl/pt-machdep.h
 create mode 100644 sysdeps/mach/hurd/aarch64/htl/pt-machdep.c
 create mode 100644 sysdeps/mach/hurd/aarch64/htl/pt-setup.c

diff --git a/sysdeps/aarch64/htl/Makefile b/sysdeps/aarch64/htl/Makefile
new file mode 100644
index ..686b843d
--- /dev/null
+++ b/sysdeps/aarch64/htl/Makefile
@@ -0,0 +1,20 @@
+# Copyright (C) 2020-2024 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# .
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/sysdeps/aarch64/htl/bits/pthreadtypes-arch.h 
b/sysdeps/aarch64/htl/bits/pthreadtypes-arch.h
new file mode 100644
index ..9ee1568e
--- /dev/null
+++ b/sysdeps/aarch64/htl/bits/pthreadtypes-arch.h
@@ -0,0 +1,36 @@
+/* Machine-specific pthread type layouts.  Hurd AArch64 version.
+   Copyright (C) 2002-2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#ifndef _BITS_PTHREADTYPES_ARCH_H
+#define _BITS_PTHREADTYPES_ARCH_H  1
+
+#define __SIZEOF_PTHREAD_MUTEX_T 32
+#define __SIZEOF_PTHREAD_ATTR_T 48
+#define __SIZEOF_PTHREAD_RWLOCK_T 48
+#define __SIZEOF_PTHREAD_BARRIER_T 40
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 16
+#define __SIZEOF_PTHREAD_COND_T 40
+#define __SIZEOF_PTHREAD_CONDATTR_T 8
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 4
+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+#define __SIZEOF_PTHREAD_ONCE_T 8
+
+#define __LOCK_ALIGNMENT
+#define __ONCE_ALIGNMENT
+
+#endif /* bits/pthreadtypes.h */
diff --git a/sysdeps/aarch64/htl/machine-sp.h b/sysdeps/aarch64/htl/machine-sp.h
new file mode 100644
index ..b21331a0
--- /dev/null
+++ b/sysdeps/aarch64/htl/machine-sp.h
@@ -0,0 +1,29 @@
+/* Machine-specific function to return the stack pointer.  AArch64 version.
+   Copyright (C) 1994-2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library;  if not, see
+   .  */
+
+#ifndef _MACHINE_SP_H
+#define _MACHINE_SP_H
+
+/* Return the current stack pointer.  */
+
+#define __thread_stack_pointer() ({
\
+  register uintptr_t __sp__ asm("sp"); 
\
+  __sp__;  
\
+})
+
+#endif /* machine-sp.h */
diff --git 

[PATCH v2 09/20] aarch64: Move saving user entry into _dl_start_user

2024-03-23 Thread Sergey Bugaev
In the Hurd ports, _dl_start () does not return the normal way; instead,
_dl_sysdep_start () jumps to _dl_start_user directly using the RETURN_TO
macro.  Unlike in the i386 and x86_64 ports, the instruction that was
saving the returned user entry into a different register (to avoid it
getting clobbered by the _dl_init () call) was not marked as a part of
_dl_start_user, causing it to be skipped when jumping to _dl_start_user
using RETURN_TO, and control subsequently getting transferred to a
random address left in x21.

This should not make any difference for Linux ports, other than the
_dl_start_user label pointing to an earlier instruction.

Signed-off-by: Sergey Bugaev 
---
 sysdeps/aarch64/dl-start.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sysdeps/aarch64/dl-start.S b/sysdeps/aarch64/dl-start.S
index d645484e..e35431ca 100644
--- a/sysdeps/aarch64/dl-start.S
+++ b/sysdeps/aarch64/dl-start.S
@@ -29,10 +29,10 @@ ENTRY (_start)
PTR_ARG (0)
bl  _dl_start
/* Returns user entry point in x0.  */
-   mov PTR_REG (21), PTR_REG (0)
 .globl _dl_start_user
 .type _dl_start_user, %function
 _dl_start_user:
+   mov PTR_REG (21), PTR_REG (0)
/* Get argc.  */
ldr PTR_REG (1), [sp]
/* Get argv.  */
-- 
2.44.0




[PATCH v2 20/20] hurd: Add expected aarch64-gnu abistlists

2024-03-23 Thread Sergey Bugaev
Signed-off-by: Sergey Bugaev 
---

We obviously didn't make it into the 2.39 timeframe, so now tentatively
targeting 2.40.

 sysdeps/mach/hurd/aarch64/ld.abilist  |   18 +
 .../mach/hurd/aarch64/libBrokenLocale.abilist |1 +
 sysdeps/mach/hurd/aarch64/libanl.abilist  |4 +
 sysdeps/mach/hurd/aarch64/libc.abilist| 2193 +
 .../hurd/aarch64/libc_malloc_debug.abilist|   26 +
 sysdeps/mach/hurd/aarch64/libdl.abilist   |0
 sysdeps/mach/hurd/aarch64/libm.abilist| 1030 
 sysdeps/mach/hurd/aarch64/libmvec.abilist |   75 +
 sysdeps/mach/hurd/aarch64/libpthread.abilist  |  165 ++
 sysdeps/mach/hurd/aarch64/libresolv.abilist   |   55 +
 sysdeps/mach/hurd/aarch64/librt.abilist   |   33 +
 11 files changed, 3600 insertions(+)
 create mode 100644 sysdeps/mach/hurd/aarch64/ld.abilist
 create mode 100644 sysdeps/mach/hurd/aarch64/libBrokenLocale.abilist
 create mode 100644 sysdeps/mach/hurd/aarch64/libanl.abilist
 create mode 100644 sysdeps/mach/hurd/aarch64/libc.abilist
 create mode 100644 sysdeps/mach/hurd/aarch64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/mach/hurd/aarch64/libdl.abilist
 create mode 100644 sysdeps/mach/hurd/aarch64/libm.abilist
 create mode 100644 sysdeps/mach/hurd/aarch64/libmvec.abilist
 create mode 100644 sysdeps/mach/hurd/aarch64/libpthread.abilist
 create mode 100644 sysdeps/mach/hurd/aarch64/libresolv.abilist
 create mode 100644 sysdeps/mach/hurd/aarch64/librt.abilist

diff --git a/sysdeps/mach/hurd/aarch64/ld.abilist 
b/sysdeps/mach/hurd/aarch64/ld.abilist
new file mode 100644
index ..ba01b289
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/ld.abilist
@@ -0,0 +1,18 @@
+GLIBC_2.40 __close F
+GLIBC_2.40 __errno_location F
+GLIBC_2.40 __getpid F
+GLIBC_2.40 __libc_stack_end D 0x8
+GLIBC_2.40 __mmap F
+GLIBC_2.40 __open F
+GLIBC_2.40 __open64 F
+GLIBC_2.40 __pread64 F
+GLIBC_2.40 __read F
+GLIBC_2.40 __sbrk F
+GLIBC_2.40 __stack_chk_guard D 0x8
+GLIBC_2.40 __tls_get_addr F
+GLIBC_2.40 __write F
+GLIBC_2.40 __writev F
+GLIBC_2.40 _dl_mcount F
+GLIBC_2.40 _hurd_intr_rpc_mach_msg F
+GLIBC_2.40 _r_debug D 0x28
+GLIBC_2.40 abort F
diff --git a/sysdeps/mach/hurd/aarch64/libBrokenLocale.abilist 
b/sysdeps/mach/hurd/aarch64/libBrokenLocale.abilist
new file mode 100644
index ..f54dcd1b
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/libBrokenLocale.abilist
@@ -0,0 +1 @@
+GLIBC_2.40 __ctype_get_mb_cur_max F
diff --git a/sysdeps/mach/hurd/aarch64/libanl.abilist 
b/sysdeps/mach/hurd/aarch64/libanl.abilist
new file mode 100644
index ..47ee5ca3
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/libanl.abilist
@@ -0,0 +1,4 @@
+GLIBC_2.40 gai_cancel F
+GLIBC_2.40 gai_error F
+GLIBC_2.40 gai_suspend F
+GLIBC_2.40 getaddrinfo_a F
diff --git a/sysdeps/mach/hurd/aarch64/libc.abilist 
b/sysdeps/mach/hurd/aarch64/libc.abilist
new file mode 100644
index ..3e16e997
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/libc.abilist
@@ -0,0 +1,2193 @@
+GLIBC_2.40 _Exit F
+GLIBC_2.40 _Fork F
+GLIBC_2.40 _IO_2_1_stderr_ D 0xe0
+GLIBC_2.40 _IO_2_1_stdin_ D 0xe0
+GLIBC_2.40 _IO_2_1_stdout_ D 0xe0
+GLIBC_2.40 _IO_adjust_column F
+GLIBC_2.40 _IO_adjust_wcolumn F
+GLIBC_2.40 _IO_default_doallocate F
+GLIBC_2.40 _IO_default_finish F
+GLIBC_2.40 _IO_default_pbackfail F
+GLIBC_2.40 _IO_default_uflow F
+GLIBC_2.40 _IO_default_xsgetn F
+GLIBC_2.40 _IO_default_xsputn F
+GLIBC_2.40 _IO_do_write F
+GLIBC_2.40 _IO_doallocbuf F
+GLIBC_2.40 _IO_fclose F
+GLIBC_2.40 _IO_fdopen F
+GLIBC_2.40 _IO_feof F
+GLIBC_2.40 _IO_ferror F
+GLIBC_2.40 _IO_fflush F
+GLIBC_2.40 _IO_fgetpos F
+GLIBC_2.40 _IO_fgetpos64 F
+GLIBC_2.40 _IO_fgets F
+GLIBC_2.40 _IO_file_attach F
+GLIBC_2.40 _IO_file_close F
+GLIBC_2.40 _IO_file_close_it F
+GLIBC_2.40 _IO_file_doallocate F
+GLIBC_2.40 _IO_file_finish F
+GLIBC_2.40 _IO_file_fopen F
+GLIBC_2.40 _IO_file_init F
+GLIBC_2.40 _IO_file_jumps D 0xa8
+GLIBC_2.40 _IO_file_open F
+GLIBC_2.40 _IO_file_overflow F
+GLIBC_2.40 _IO_file_read F
+GLIBC_2.40 _IO_file_seek F
+GLIBC_2.40 _IO_file_seekoff F
+GLIBC_2.40 _IO_file_setbuf F
+GLIBC_2.40 _IO_file_stat F
+GLIBC_2.40 _IO_file_sync F
+GLIBC_2.40 _IO_file_underflow F
+GLIBC_2.40 _IO_file_write F
+GLIBC_2.40 _IO_file_xsputn F
+GLIBC_2.40 _IO_flockfile F
+GLIBC_2.40 _IO_flush_all F
+GLIBC_2.40 _IO_flush_all_linebuffered F
+GLIBC_2.40 _IO_fopen F
+GLIBC_2.40 _IO_fprintf F
+GLIBC_2.40 _IO_fputs F
+GLIBC_2.40 _IO_fread F
+GLIBC_2.40 _IO_free_backup_area F
+GLIBC_2.40 _IO_free_wbackup_area F
+GLIBC_2.40 _IO_fsetpos F
+GLIBC_2.40 _IO_fsetpos64 F
+GLIBC_2.40 _IO_ftell F
+GLIBC_2.40 _IO_ftrylockfile F
+GLIBC_2.40 _IO_funlockfile F
+GLIBC_2.40 _IO_fwrite F
+GLIBC_2.40 _IO_getc F
+GLIBC_2.40 _IO_getline F
+GLIBC_2.40 _IO_getline_info F
+GLIBC_2.40 _IO_gets F
+GLIBC_2.40 _IO_init F
+GLIBC_2.40 _IO_init_marker F
+GLIBC_2.40 _IO_init_wmarker F
+GLIBC_2.40 _IO_iter_begin F
+GLIBC_2.40 _IO_iter_end F
+GLIBC_2.40 _IO_iter_file F
+GLIBC_2.40 _IO_iter_next F
+GLIBC_2.40 _IO_least_wmarker F

[PATCH v2 14/20] hurd: Implement TLS on AArch64

2024-03-23 Thread Sergey Bugaev
This is using TLS_DTV_AT_TP, aka "Variant I" layout. tpidr_el0, which is
both readable and writable from userspace, is used as the thread pointer.

We store our Hurd-specific data (sigstate and reply port) *before* the
TCB head, in a tcbprehead_t structure. This tcbprehead_t structure is
also what THREAD_SELF, THREAD_GETMEM, and THREAD_SETMEM macros access.

Signed-off-by: Sergey Bugaev 
---
 .../mach/hurd/aarch64/dl-tls-initialized.c|  19 ++
 sysdeps/mach/hurd/aarch64/tls.h   | 206 ++
 2 files changed, 225 insertions(+)
 create mode 100644 sysdeps/mach/hurd/aarch64/dl-tls-initialized.c
 create mode 100644 sysdeps/mach/hurd/aarch64/tls.h

diff --git a/sysdeps/mach/hurd/aarch64/dl-tls-initialized.c 
b/sysdeps/mach/hurd/aarch64/dl-tls-initialized.c
new file mode 100644
index ..9beafec3
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/dl-tls-initialized.c
@@ -0,0 +1,19 @@
+/* Determine whether TLS is initialized, for AArch64/Hurd.
+   Copyright (C) 1995-2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+/* Nothing here, it's all handled in tls.h */
diff --git a/sysdeps/mach/hurd/aarch64/tls.h b/sysdeps/mach/hurd/aarch64/tls.h
new file mode 100644
index ..712134e1
--- /dev/null
+++ b/sysdeps/mach/hurd/aarch64/tls.h
@@ -0,0 +1,206 @@
+/* Copyright (C) 2005-2024 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#ifndef _AARCH64_TLS_H
+#define _AARCH64_TLS_H 1
+
+/* Some things really need not be machine-dependent.  */
+#include 
+
+#include 
+
+#ifndef __ASSEMBLER__
+# include 
+# include 
+# include 
+# include 
+# include 
+# include 
+# include 
+#endif /* __ASSEMBLER__ */
+
+#ifndef __ASSEMBLER__
+
+/* Get system call information.  */
+# include 
+
+/* The TP points to the start of the thread blocks.  */
+# define TLS_DTV_AT_TP 1
+# define TLS_TCB_AT_TP 0
+
+typedef struct
+{
+  /* Used by the exception handling implementation in the dynamic loader.  */
+  struct rtld_catch *rtld_catch;
+
+  struct hurd_sigstate *_hurd_sigstate;
+  mach_port_t reply_port;  /* This thread's reply port.  */
+
+  int gscope_flag;
+} tcbprehead_t;
+
+typedef struct
+{
+  dtv_t *dtv;
+  void *private;
+} tcbhead_t;
+
+/* This is the size of the initial TCB.  */
+# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+
+/* This is the size we need before TCB.  */
+# define TLS_PRE_TCB_SIZE  sizeof (tcbprehead_t)
+
+# define TCB_ALIGNMENT 64
+
+/* Install new dtv for current thread.  */
+# define INSTALL_NEW_DTV(dtv) \
+  (THREAD_DTV() = (dtv))
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+  (((tcbhead_t *) __builtin_thread_pointer ())->dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF \
+ ((tcbprehead_t *)__builtin_thread_pointer () - 1)
+
+/* Read member of the thread descriptor directly.  */
+# define THREAD_GETMEM(descr, member) \
+  ((descr)->member)
+
+/* Write member of the thread descriptor directly.  */
+# define THREAD_SETMEM(descr, member, value) \
+  ((descr)->member = (value))
+
+/* Return the TCB address of a thread given its state.
+   Note: this is expensive.  */
+static inline tcbprehead_t * __attribute__ ((unused))
+THREAD_TCB (thread_t thread,
+struct machine_thread_all_state *all_state)
+{
+  int ok;
+  const struct aarch64_thread_state *state;
+  tcbhead_t *tcb;
+
+  ok = machine_get_basic_state (thread, all_state);
+  assert (ok);
+  state = &((struct machine_thread_all_state *) all_state)->basic;
+  tcb = (tcbhead_t *) 

[PATCH v2 07/20] aarch64: Move pointer_guard.h out of sysdeps/unix/sysv/linux

2024-03-23 Thread Sergey Bugaev
Nothing about this is Linux-specific.

Signed-off-by: Sergey Bugaev 
---
 sysdeps/{unix/sysv/linux => }/aarch64/pointer_guard.h | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename sysdeps/{unix/sysv/linux => }/aarch64/pointer_guard.h (100%)

diff --git a/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h 
b/sysdeps/aarch64/pointer_guard.h
similarity index 100%
rename from sysdeps/unix/sysv/linux/aarch64/pointer_guard.h
rename to sysdeps/aarch64/pointer_guard.h
-- 
2.44.0




[PATCH v2 02/20] hurd: Stop relying on VM_MAX_ADDRESS

2024-03-23 Thread Sergey Bugaev
We'd like to avoid committing to a specific size of virtual address
space (i.e. the value of VM_AARCH64_T0SZ) on AArch64.  While the current
version of GNU Mach still exports VM_MAX_ADDRESS for compatibility, we
should try to avoid relying on it when we can.  This piece of logic in
_hurdsig_getenv () doesn't actually care about the size of user-
accessible virtual address space, it just wants to preempt faults on any
addresses starting from the value of the P pointer and above.  So, use
(unsigned long int) -1 instead of VM_MAX_ADDRESS.

While at it, change the casts to (unsigned long int) and not just
(long int), since the type of struct hurd_signal_preemptor.{first,last}
is unsigned long int.

Signed-off-by: Sergey Bugaev 
---
 hurd/hurdsig.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index 882a0347..8b1928d1 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -1658,8 +1658,8 @@ _hurdsig_getenv (const char *variable)
   while (*ep)
{
  const char *p = *ep;
- _hurdsig_fault_preemptor.first = (long int) p;
- _hurdsig_fault_preemptor.last = VM_MAX_ADDRESS;
+ _hurdsig_fault_preemptor.first = (unsigned long int) p;
+ _hurdsig_fault_preemptor.last = (unsigned long int) -1;
  if (! strncmp (p, variable, len) && p[len] == '=')
{
  size_t valuelen;
@@ -1671,8 +1671,8 @@ _hurdsig_getenv (const char *variable)
memcpy (value, p, valuelen);
  break;
}
- _hurdsig_fault_preemptor.first = (long int) ++ep;
- _hurdsig_fault_preemptor.last = (long int) (ep + 1);
+ _hurdsig_fault_preemptor.first = (unsigned long int) ++ep;
+ _hurdsig_fault_preemptor.last = (unsigned long int) (ep + 1);
}
   _hurdsig_end_catch_fault ();
   return value;
-- 
2.44.0




[PATCH v2 01/20] hurd: Move internal functions to internal header

2024-03-23 Thread Sergey Bugaev
Move _hurd_self_sigstate (), _hurd_critical_section_lock (), and
_hurd_critical_section_unlock () inline implementations (that were
already guarded by #if defined _LIBC) to the internal version of the
header.  While at it, add  to the includes, and use
__LIBC_NO_TLS () unconditionally.

Signed-off-by: Sergey Bugaev 
---

This is the remaining part of the "hurd: Add some missing includes"
patch from v1, redone in a different way, as discussed last time.

The hurd/check-installed-headers-c test seems to pass for me, but please
check on your end too.

 hurd/hurd/signal.h | 87 --
 sysdeps/hurd/include/hurd/signal.h | 78 +++
 2 files changed, 78 insertions(+), 87 deletions(-)

diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
index 6bc7103b..5d116fb2 100644
--- a/hurd/hurd/signal.h
+++ b/hurd/hurd/signal.h
@@ -40,11 +40,6 @@
 #include /* For `jmp_buf'.  */
 #include 
 struct hurd_signal_preemptor;  /*  */
-#if defined __USE_EXTERN_INLINES && defined _LIBC
-# if IS_IN (libc) || IS_IN (libpthread)
-#  include 
-# endif
-#endif
 
 
 /* Full details of a signal.  */
@@ -157,33 +152,6 @@ extern void _hurd_sigstate_unlock (struct hurd_sigstate 
*ss);
 /* Used by libpthread to remove stale sigstate structures.  */
 extern void _hurd_sigstate_delete (thread_t thread);
 
-#ifndef _HURD_SIGNAL_H_EXTERN_INLINE
-#define _HURD_SIGNAL_H_EXTERN_INLINE __extern_inline
-#endif
-
-#if defined __USE_EXTERN_INLINES && defined _LIBC
-# if IS_IN (libc)
-_HURD_SIGNAL_H_EXTERN_INLINE struct hurd_sigstate *
-_hurd_self_sigstate (void)
-{
-  struct hurd_sigstate *ss = THREAD_GETMEM (THREAD_SELF, _hurd_sigstate);
-  if (__glibc_unlikely (ss == NULL))
-{
-  thread_t self = __mach_thread_self ();
-
-  /* The thread variable is unset; this must be the first time we've
-asked for it.  In this case, the critical section flag cannot
-possible already be set.  Look up our sigstate structure the slow
-way.  */
-  ss = _hurd_thread_sigstate (self);
-  THREAD_SETMEM (THREAD_SELF, _hurd_sigstate, ss);
-  __mach_port_deallocate (__mach_task_self (), self);
-}
-  return ss;
-}
-# endif
-#endif
-
 struct machine_thread_all_state;
 extern mach_port_t
 _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,
@@ -215,63 +183,8 @@ extern int _hurd_core_limit;
avoid unexpectingly exposing EINTR to the application.  */
 
 extern void *_hurd_critical_section_lock (void);
-
-#if defined __USE_EXTERN_INLINES && defined _LIBC
-# if IS_IN (libc)
-_HURD_SIGNAL_H_EXTERN_INLINE void *
-_hurd_critical_section_lock (void)
-{
-  struct hurd_sigstate *ss;
-
-#ifdef __LIBC_NO_TLS
-  if (__LIBC_NO_TLS ())
-/* TLS is currently initializing, no need to enter critical section.  */
-return NULL;
-#endif
-
-  ss = _hurd_self_sigstate ();
-
-  if (! __spin_try_lock (>critical_section_lock))
-/* We are already in a critical section, so do nothing.  */
-return NULL;
-
-  /* With the critical section lock held no signal handler will run.
- Return our sigstate pointer; this will be passed to
- _hurd_critical_section_unlock to unlock it.  */
-  return ss;
-}
-# endif
-#endif
-
 extern void _hurd_critical_section_unlock (void *our_lock);
 
-#if defined __USE_EXTERN_INLINES && defined _LIBC
-# if IS_IN (libc)
-_HURD_SIGNAL_H_EXTERN_INLINE void
-_hurd_critical_section_unlock (void *our_lock)
-{
-  if (our_lock == NULL)
-/* The critical section lock was held when we began.  Do nothing.  */
-return;
-  else
-{
-  /* It was us who acquired the critical section lock.  Unlock it.  */
-  struct hurd_sigstate *ss = (struct hurd_sigstate *) our_lock;
-  sigset_t pending;
-  _hurd_sigstate_lock (ss);
-  __spin_unlock (>critical_section_lock);
-  pending = _hurd_sigstate_pending (ss) & ~ss->blocked;
-  _hurd_sigstate_unlock (ss);
-  if (__glibc_unlikely (!__sigisemptyset ()))
-   /* There are unblocked signals pending, which weren't
-  delivered because we were in the critical section.
-  Tell the signal thread to deliver them now.  */
-   __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
-}
-}
-# endif
-#endif
-
 /* Convenient macros for simple uses of critical sections.
These two must be used as a pair at the same C scoping level.  */
 
diff --git a/sysdeps/hurd/include/hurd/signal.h 
b/sysdeps/hurd/include/hurd/signal.h
index 1dc8a1f3..fab8d1b6 100644
--- a/sysdeps/hurd/include/hurd/signal.h
+++ b/sysdeps/hurd/include/hurd/signal.h
@@ -9,6 +9,84 @@ libc_hidden_proto (_hurd_self_sigstate)
 #include_next 
 
 #ifndef _ISOMAC
+
+#if defined __USE_EXTERN_INLINES
+# if IS_IN (libc) || IS_IN (libpthread)
+#  include 
+#  include 
+# endif
+#endif
+
+#ifndef _HURD_SIGNAL_H_EXTERN_INLINE
+#define _HURD_SIGNAL_H_EXTERN_INLINE __extern_inline
+#endif
+
+#if defined __USE_EXTERN_INLINES && IS_IN (libc)
+_HURD_SIGNAL_H_EXTERN_INLINE struct 

[PATCH v2 06/20] htl: Respect GL(dl_stack_flags) when allocating stacks

2024-03-23 Thread Sergey Bugaev
Previously, HTL would always allocate non-executable stacks.  This has
never been noticed, since GNU Mach on x86 ignores VM_PROT_EXECUTE and
makes all pages implicitly executable.  Since GNU Mach on AArch64
supports non-executable pages, HTL forgetting to pass VM_PROT_EXECUTE
immediately breaks any code that (unfortunately, still) relies on
executable stacks.

Signed-off-by: Sergey Bugaev 
---
 sysdeps/htl/Versions  | 4 
 sysdeps/mach/htl/pt-stack-alloc.c | 9 +++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/sysdeps/htl/Versions b/sysdeps/htl/Versions
index 3a3b1e8b..7b5450d2 100644
--- a/sysdeps/htl/Versions
+++ b/sysdeps/htl/Versions
@@ -12,4 +12,8 @@ libc {
 pthread_spin_destroy; pthread_spin_init; pthread_spin_lock;
 pthread_spin_trylock; pthread_spin_unlock;
   }
+
+  GLIBC_PRIVATE {
+__vm_map;
+  }
 }
diff --git a/sysdeps/mach/htl/pt-stack-alloc.c 
b/sysdeps/mach/htl/pt-stack-alloc.c
index 61974bd5..0597770b 100644
--- a/sysdeps/mach/htl/pt-stack-alloc.c
+++ b/sysdeps/mach/htl/pt-stack-alloc.c
@@ -31,9 +31,14 @@ int
 __pthread_stack_alloc (void **stackaddr, size_t stacksize)
 {
   error_t err;
+  vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;
 
-  err = __vm_allocate (__mach_task_self (), (vm_offset_t *) stackaddr,
-  stacksize, TRUE);
+  if (GL(dl_stack_flags) & PF_X)
+prot |= VM_PROT_EXECUTE;
+
+  err = __vm_map (__mach_task_self (), (vm_offset_t *) stackaddr,
+ stacksize, 0, TRUE, MEMORY_OBJECT_NULL, 0, FALSE,
+ prot, VM_PROT_ALL, VM_INHERIT_COPY);
 
   if (err == KERN_NO_SPACE)
 err = EAGAIN;
-- 
2.44.0




[PATCH v2 00/20] aarch64-gnu port & GNU/Hurd on AArch64 progress

2024-03-23 Thread Sergey Bugaev
Hello!

This is v2 of my work on the aarch64-gnu port, aka GNU/Hurd on 64-bit
ARM. v1 is here [0].

[0]: https://sourceware.org/pipermail/libc-alpha/2024-January/153675.html

Last time, Joseph Myers has pointed out that the aarch64-gnu port can
not be merged into glibc until aarch64-gnu support is upstream in all of
glibc's build-time dependencies. That is still not the case, so this
patchset can not be merged yet; but otherwise it should be in a fairly
mergeable state. It does not yet anything to NEWS or
build-many-glibcs.py, though.

I'm porting this, again, to gather some feedback (hopefully more than
last time...), and at Maxim's request, so Linaro can test this on their
CI and ensure this doesn't break existing ports.

The upstreaming status of various aarch64-gnu components is,
specifically:

* Binutils patch to add the aarch64-gnu target is upstream and in the
  2.42 release;
* GCC patches to add aarch64-gnu target (& libgcc host) have been
  reviewed by ARM and Hurd port maintainers and should land upstream
  very soon;
* initial Hurd patches are upstream;
* glibc patches (this patchset) are not yet upstream;
* GNU Mach changes are not upstream, and upstreaming story is unclear;
* GNU MIG needs no changes, it just works.

Last time, there was no AArch64 port of GNU Mach, and so the only
testing I have done was running a simple statically-linked executable on
Linux under GDB -- which, nevertheless, helped me identify and fix a
number of issues.

Since then, however, I have been (some may say, relentlessly) working on
filling in the missing piece, namely porting gnumach (with important
help & contributions by Luca D.). I am happy to report that we now have
an experimental port of gnumach that builds and works on AArch64! While
that may sound impressive, note that various things about it are in an
extremely basic, proof-of-concept state rather than being seriously
production-ready; and also that Mach is a small kernel (indeed, a
microkernel), and it was designed from the start (back in the 80s) to be
portable, so most of the "buisness logic" functionality (virtual memory,
IPC, tasks/threads/scheduler) is explicitly arch-independent.

Despite the scary "WIP proof-of-concept" status, there is enough
functionality in Mach to run userland code, handle exceptions and
syscalls, interact with the MMU to implement all the expected virtual
memory semantics, schedule/switch tasks and threads, and so on.
Moreover, all of gnumach's userspace self-tests pass!

This meant there was enough things in place for me to try running glibc
on it, and the amazing thing is my simple test executable, the same one
I previously tested on Linux w/ GDB, just worked on real Mach without me
having to make any additional changes to the glibc side, or even
recompile it.

But I did not stop there, and got several of the core Hurd servers
working! Namely, these are ext2fs, exec, startup, auth, and proc
servers. All of them but ext2fs are dynamically linked; ld-aarch64.so.1
sucessfully locates and maps the programs themselves and their required
dependencies, and Mach pages in code and data pages from ext2fs as they
are accessed, transparently to the program, just as one would expect it
to.

It turned out that Mach on i386 and x86_64 did not enforce the (lack of)
execute permission on pages, i.e. even pages mapped without
VM_PROT_EXECUTE were executable in practice. This caused a number of
bugs related to mapping executable stacks to go unnoticed, there were
issues in all of Mach, glibc, and the Hurd's exec server related to
not creating executable stacks as actually executable. As I implemented
the execute permission properly in Mach on AArch64 (indeed, I even
support execute-only pages when the hardware implements FEAT_EPAN), I
have encountered all of those oversights one by one when trying to run
progressively more code, and have hopefully fixed them all. Hopefully
we'll stop requiring executable stacks for glibc and Hurd libraries some
time, and then we'll get working non-executable stacks on AArch64.

As expected, I have done some tweaks to the AArch64-specific Mach APIs
(primarily thread state and exception code definitions) compared to the
"preliminary sketches" of them that I posted in January, but they were
actually rather small. I've got some more confidence in the APIs now
after having implemented support for them from both sides now, and
having tested that it works in practice. No more backwards-incompatible
changes to AArch64-specific Mach APIs are expected (by me anyway); we'll
definetely want to add more things later (aarch64_debug_state for GDB,
PAC RPCs, and more), but those should be purely additive.

I have added a new Mach syscall (trap), thread_set_self_state (), to
implement sigreturn () on top of. I have originally hoped that it would
be possible to use the regular thread_set_state (mach_thread_self ())
call for it (special-casing it on AArch64 to allow setting the calling
thread's state), and indeed have 

[PATCH v2 05/20] hurd: Use the RETURN_ADDRESS macro

2024-03-23 Thread Sergey Bugaev
This gives us PAC stripping on AArch64.

Signed-off-by: Sergey Bugaev 
---

PAC is still not implemented on gnumach side, though.

 sysdeps/mach/hurd/init-first.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sysdeps/mach/hurd/init-first.c b/sysdeps/mach/hurd/init-first.c
index 22c35747..5777c44c 100644
--- a/sysdeps/mach/hurd/init-first.c
+++ b/sysdeps/mach/hurd/init-first.c
@@ -222,7 +222,7 @@ _hurd_stack_setup (void **argptr)
  this may not be a valid pointer in case we're supposed to receive the
  arguments from the exec server, so we can not dereference it yet.  */
 
-  void *caller = __builtin_extract_return_addr (__builtin_return_address (0));
+  void *caller = RETURN_ADDRESS (0);
   /* Init the essential things.  */
   first_init ();
 
-- 
2.44.0




[PATCH v2 03/20] Allow glibc to be compiled without EXEC_PAGESIZE

2024-03-23 Thread Sergey Bugaev
We would like to avoid statically defining any specific page size on
aarch64-gnu, and instead make sure that everything uses the dynamic
page size, available via vm_page_size and GLRO(dl_pagesize).

There are currently a few places in glibc that require EXEC_PAGESIZE
to be defined. Per Roland's suggestion [0], drop the static
GLRO(dl_pagesize) initializers (for now, only if EXEC_PAGESIZE is not
defined), and don't require EXEC_PAGESIZE definition for libio to
enable mmap usage.

[0]: https://mail.gnu.org/archive/html/bug-hurd/2011-10/msg00035.html

Signed-off-by: Sergey Bugaev 
---

Same patch as last time. At least in the Hurd port, GLRO(dl_pagesize)
is one of the very things to get initialized, so this shouldn't cause
any initialization order issues. But, if it's really undesirable for
EXEC_PAGESIZE to be dropped, we could of course also define
EXEC_PAGESIZE to some large value (16K?) on aarch64-gnu, provided that
nothing actually tries to use it for anything.

PAGE_SIZE is 4k in the current AArch64 GNU Mach, for what it's worth,
but this is intended to eventually be build-time configurable.

 elf/dl-support.c | 6 +-
 elf/rtld.c   | 2 ++
 libio/libioP.h   | 2 +-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/elf/dl-support.c b/elf/dl-support.c
index 451932dd..cb0bbd21 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -135,7 +135,11 @@ void *_dl_random;
 #include 
 #include 
 
-size_t _dl_pagesize = EXEC_PAGESIZE;
+size_t _dl_pagesize
+#ifdef EXEC_PAGESIZE
+  = EXEC_PAGESIZE
+#endif
+;
 
 size_t _dl_minsigstacksize = CONSTANT_MINSIGSTKSZ;
 
diff --git a/elf/rtld.c b/elf/rtld.c
index ac4bb236..18d73f19 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -358,7 +358,9 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
 ._dl_debug_fd = STDERR_FILENO,
 ._dl_lazy = 1,
 ._dl_fpu_control = _FPU_DEFAULT,
+#ifdef EXEC_PAGESIZE
 ._dl_pagesize = EXEC_PAGESIZE,
+#endif
 ._dl_inhibit_cache = 0,
 ._dl_profile_output = "/var/tmp",
 
diff --git a/libio/libioP.h b/libio/libioP.h
index 1af287b1..1a7f547e 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -852,7 +852,7 @@ extern off64_t _IO_seekpos_unlocked (FILE *, off64_t, int)
 #  define MAP_ANONYMOUS MAP_ANON
 # endif
 
-# if !defined(MAP_ANONYMOUS) || !defined(EXEC_PAGESIZE)
+# if !defined(MAP_ANONYMOUS)
 #  undef _G_HAVE_MMAP
 #  define _G_HAVE_MMAP 0
 # endif
-- 
2.44.0




Re: [PATCH gcc 1/3] Move GNU/Hurd startfile spec from config/i386/gnu.h to config/gnu.h

2024-03-23 Thread Sergey Bugaev
On Wed, Mar 20, 2024 at 10:20 PM Thomas Schwinge  wrote:
> Hi!

Hi Thomas,

> Sergey, great work on aarch64 GNU/Hurd!  (... where these GCC bits
> clearly were the less complicated part...)  ;-)

thanks! (and indeed they were :)

> Please re-submit with ChangeLog updates added to the Git commit logs; see
>  ->
> , and/or 'git log'
> for guidance.  You may use
> 'contrib/gcc-changelog/git_check_commit.py --print-changelog' to verify.

Done so, and git_check_commit.py seems happy with my attempt. I
rebased (fixing a trivial merge conflict) and posted v2, please take a
look.

Sergey



[PATCH v2 1/3] Move GNU/Hurd startfile spec from config/i386/gnu.h to config/gnu.h

2024-03-23 Thread Sergey Bugaev
Since it's not i386-specific; this makes it possible to reuse it for other
architectures.

Also, add a warning for the case gnu.h is specified before gnu-user.h, which
would cause gnu-user's version of the spec to override gnu's, and not the other
way around as it's intended. The i?86-gnu target currently specifies them in
the right order, but it's easy to accidentally put them in a wrong order.

gcc/Changelog:

* config/i386/gnu.h: Move GNU/Hurd STARTFILE_SPEC from here...
* config/gnu.h: ...to here.

Signed-off-by: Sergey Bugaev 
---
 gcc/config/gnu.h  | 16 
 gcc/config/i386/gnu.h | 11 ---
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/gcc/config/gnu.h b/gcc/config/gnu.h
index ac99f7605..e2a33baf0 100644
--- a/gcc/config/gnu.h
+++ b/gcc/config/gnu.h
@@ -31,3 +31,19 @@ along with GCC.  If not, see .
builtin_assert ("system=unix"); \
builtin_assert ("system=posix");\
 } while (0)
+
+
+#ifndef GNU_USER_TARGET_STARTFILE_SPEC
+# warning This file should be included after gnu-user.h, to override its 
STARTFILE_SPEC
+#endif
+
+#undef STARTFILE_SPEC
+#if defined HAVE_LD_PIE
+#define STARTFILE_SPEC \
+  "%{!shared: 
%{pg|p|profile:%{static-pie:grcrt0.o%s;static:gcrt0.o%s;:gcrt1.o%s};static-pie:rcrt0.o%s;static:crt0.o%s;"
 PIE_SPEC ":Scrt1.o%s;:crt1.o%s}} \
+   crti.o%s %{static:crtbeginT.o%s;shared|static-pie|" PIE_SPEC 
":crtbeginS.o%s;:crtbegin.o%s}"
+#else
+#define STARTFILE_SPEC \
+  "%{!shared: 
%{pg|p|profile:%{static:gcrt0.o%s;:gcrt1.o%s};static:crt0.o%s;:crt1.o%s}} \
+   crti.o%s %{static:crtbeginT.o%s;shared:crtbeginS.o%s;:crtbegin.o%s}"
+#endif
diff --git a/gcc/config/i386/gnu.h b/gcc/config/i386/gnu.h
index 3f42714d1..af1d55887 100644
--- a/gcc/config/i386/gnu.h
+++ b/gcc/config/i386/gnu.h
@@ -24,17 +24,6 @@ along with GCC.  If not, see .
 #undef GNU_USER_DYNAMIC_LINKER
 #define GNU_USER_DYNAMIC_LINKER "/lib/ld.so"
 
-#undef STARTFILE_SPEC
-#if defined HAVE_LD_PIE
-#define STARTFILE_SPEC \
-  "%{!shared: 
%{pg|p|profile:%{static-pie:grcrt0.o%s;static:gcrt0.o%s;:gcrt1.o%s};static-pie:rcrt0.o%s;static:crt0.o%s;"
 PIE_SPEC ":Scrt1.o%s;:crt1.o%s}} \
-   crti.o%s %{static:crtbeginT.o%s;shared|static-pie|" PIE_SPEC 
":crtbeginS.o%s;:crtbegin.o%s}"
-#else
-#define STARTFILE_SPEC \
-  "%{!shared: 
%{pg|p|profile:%{static:gcrt0.o%s;:gcrt1.o%s};static:crt0.o%s;:crt1.o%s}} \
-   crti.o%s %{static:crtbeginT.o%s;shared:crtbeginS.o%s;:crtbegin.o%s}"
-#endif
-
 #ifdef TARGET_LIBC_PROVIDES_SSP
 
 /* i386 glibc provides __stack_chk_guard in %gs:0x14.  */
-- 
2.44.0




[PATCH v2 3/3] libgcc: Add basic support for aarch64-gnu (GNU/Hurd on AArch64)

2024-03-23 Thread Sergey Bugaev
There is currently no unwinding implementation.

libgcc/ChangeLog:

* config.host: Recognize aarch64*-*-gnu* hosts.
* config/aarch64/gnu-unwind.h: New file.
* config/aarch64/heap-trampoline.c
(allocate_trampoline_page): Support GNU/Hurd.

Signed-off-by: Sergey Bugaev 
---
 libgcc/config.host  |  9 +++
 libgcc/config/aarch64/gnu-unwind.h  | 36 +
 libgcc/config/aarch64/heap-trampoline.c |  4 +--
 3 files changed, 47 insertions(+), 2 deletions(-)
 create mode 100644 libgcc/config/aarch64/gnu-unwind.h

diff --git a/libgcc/config.host b/libgcc/config.host
index 59a42d3a0..e75a7af64 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -448,6 +448,15 @@ aarch64*-*-linux*)
tmake_file="${tmake_file} t-dfprules"
tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline"
;;
+aarch64*-*-gnu*)
+   extra_parts="$extra_parts crtfastmath.o"
+   md_unwind_header=aarch64/gnu-unwind.h
+   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"
+   tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline"
+   ;;
 aarch64*-*-vxworks7*)
extra_parts="$extra_parts crtfastmath.o"
md_unwind_header=aarch64/aarch64-unwind.h
diff --git a/libgcc/config/aarch64/gnu-unwind.h 
b/libgcc/config/aarch64/gnu-unwind.h
new file mode 100644
index 0..d9e485a18
--- /dev/null
+++ b/libgcc/config/aarch64/gnu-unwind.h
@@ -0,0 +1,36 @@
+/* DWARF2 EH unwinding support for GNU Hurd: aarch64.
+   Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+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
+.  */
+
+/* Always include AArch64 unwinder header file.  */
+#include "config/aarch64/aarch64-unwind.h"
+
+#ifndef inhibit_libc
+
+#include 
+
+/*
+ * TODO: support for aarch64 needs to be implemented.
+ */
+
+#endif /* ifndef inhibit_libc */
diff --git a/libgcc/config/aarch64/heap-trampoline.c 
b/libgcc/config/aarch64/heap-trampoline.c
index 885df629d..26957a3ee 100644
--- a/libgcc/config/aarch64/heap-trampoline.c
+++ b/libgcc/config/aarch64/heap-trampoline.c
@@ -29,7 +29,7 @@ void *allocate_trampoline_page (void);
 void __gcc_nested_func_ptr_created (void *chain, void *func, void *dst);
 void __gcc_nested_func_ptr_deleted (void);
 
-#if defined(__linux__)
+#if defined(__linux__) || defined(__gnu_hurd__)
 static const unsigned char aarch64_trampoline_insns[6][4] = {
   {0x5f, 0x24, 0x03, 0xd5}, /* hint34 */
   {0xb1, 0x00, 0x00, 0x58}, /* ldr x17, .+20 */
@@ -82,7 +82,7 @@ allocate_trampoline_page (void)
 {
   void *page;
 
-#if defined(__linux__)
+#if defined(__linux__) || defined(__gnu_hurd__)
   page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC,
   MAP_ANON | MAP_PRIVATE, 0, 0);
 #elif __APPLE__
-- 
2.44.0




[PATCH v2 2/3] aarch64: Add support for aarch64-gnu (GNU/Hurd on AArch64)

2024-03-23 Thread Sergey Bugaev
Coupled with a corresponding binutils patch, this produces a toolchain that can
sucessfully build working binaries targeting aarch64-gnu.

gcc/Changelog:

* config.gcc: Recognize aarch64*-*-gnu* targets.
* config/aarch64/aarch64-gnu.h: New file.

Signed-off-by: Sergey Bugaev 
---
 gcc/config.gcc   |  6 +++
 gcc/config/aarch64/aarch64-gnu.h | 68 
 2 files changed, 74 insertions(+)
 create mode 100644 gcc/config/aarch64/aarch64-gnu.h

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 87a5c92b6..9d935164c 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1264,6 +1264,12 @@ aarch64*-*-linux*)
done
TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
;;
+aarch64*-*-gnu*)
+tm_file="${tm_file} elfos.h gnu-user.h gnu.h glibc-stdint.h"
+tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-errata.h 
aarch64/aarch64-gnu.h"
+tmake_file="${tmake_file} aarch64/t-aarch64"
+tm_defines="${tm_defines}  TARGET_DEFAULT_ASYNC_UNWIND_TABLES=1"
+   ;;
 aarch64*-wrs-vxworks*)
 tm_file="${tm_file} elfos.h aarch64/aarch64-elf.h"
 tm_file="${tm_file} vx-common.h vxworks.h aarch64/aarch64-vxworks.h"
diff --git a/gcc/config/aarch64/aarch64-gnu.h b/gcc/config/aarch64/aarch64-gnu.h
new file mode 100644
index 0..ee5494034
--- /dev/null
+++ b/gcc/config/aarch64/aarch64-gnu.h
@@ -0,0 +1,68 @@
+/* Definitions for AArch64 running GNU/Hurd.
+   Copyright (C) 2009-2024 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   .  */
+
+#ifndef GCC_AARCH64_GNU_H
+#define GCC_AARCH64_GNU_H
+
+#define GNU_USER_DYNAMIC_LINKER 
"/lib/ld-aarch64%{mbig-endian:_be}%{mabi=ilp32:_ilp32}.so.1"
+
+#define CPP_SPEC "%{pthread:-D_REENTRANT}"
+
+#define GNU_TARGET_LINK_SPEC  "%{h*}   \
+   %{static:-Bstatic}  \
+   %{shared:-shared}   \
+   %{symbolic:-Bsymbolic}  \
+   %{!static:%{!static-pie:\
+ %{rdynamic:-export-dynamic}   \
+ %{!shared:-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}} \
+   %{static-pie:-Bstatic -pie --no-dynamic-linker -z text} \
+   -X  \
+   %{mbig-endian:-EB} %{mlittle-endian:-EL} \
+   -maarch64gnu%{mabi=ilp32:32}%{mbig-endian:b}"
+
+
+#define LINK_SPEC GNU_TARGET_LINK_SPEC AARCH64_ERRATA_LINK_SPEC
+
+#define GNU_USER_TARGET_MATHFILE_SPEC \
+  "%{Ofast|ffast-math|funsafe-math-optimizations:%{!shared:crtfastmath.o%s}}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC   \
+  GNU_USER_TARGET_MATHFILE_SPEC " " \
+  GNU_USER_TARGET_ENDFILE_SPEC
+
+#define TARGET_OS_CPP_BUILTINS()   \
+  do   \
+{  \
+   GNU_USER_TARGET_OS_CPP_BUILTINS();  \
+}  \
+  while (0)
+
+#define TARGET_ASM_FILE_END aarch64_file_end_indicate_exec_stack
+
+/* Uninitialized common symbols in non-PIE executables, even with
+   strong definitions in dependent shared libraries, will resolve
+   to COPY relocated symbol in the executable.  See PR65780.  */
+#undef TARGET_BINDS_LOCAL_P
+#define TARGET_BINDS_LOCAL_P default_binds_local_p_2
+
+/* Define this to be nonzero if static stack checking is supported.  */
+#define STACK_CHECK_STATIC_BUILTIN 1
+
+#endif  /* GCC_AARCH64_GNU_H */
-- 
2.44.0




Re: [PATCH 01/10] term: Fix function prototype

2024-03-23 Thread Samuel Thibault
Sergey Bugaev, le sam. 23 mars 2024 15:12:21 +0300, a ecrit:
> On Sat, Mar 23, 2024 at 3:06 PM Samuel Thibault  
> wrote:
> > Applied the whole series, thanks!
> 
> Looks like "[PATCH 07/10] exec: Add support for AArch64 executables"
> fell through the cracks...

Indeed! Sorry for the miss.

Samuel



Re: [PATCH 01/10] term: Fix function prototype

2024-03-23 Thread Sergey Bugaev
On Sat, Mar 23, 2024 at 3:06 PM Samuel Thibault  wrote:
> Applied the whole series, thanks!

Looks like "[PATCH 07/10] exec: Add support for AArch64 executables"
fell through the cracks...

Sergey



Re: [PATCH 01/10] term: Fix function prototype

2024-03-23 Thread Samuel Thibault
Hello,

Applied the whole series, thanks!

Samuel



[PATCH 09/10] proc: Add support for AArch64 in uname

2024-03-23 Thread Sergey Bugaev
Since no CPU subtypes are defined for CPU_TYPE_ARM64, just report the
type, same as for x86_64.

Sample uname(2) output:

sysname: GNU
release: 0.9
version: GNU-Mach 1.8/Hurd-0.9
machine: aarch64
---
 proc/cpu-types.c | 3 +++
 proc/host.c  | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/proc/cpu-types.c b/proc/cpu-types.c
index 3d89d5a7..41af0888 100644
--- a/proc/cpu-types.c
+++ b/proc/cpu-types.c
@@ -35,6 +35,9 @@ const char *const mach_cpu_types[] =
 #endif
 #ifdef CPU_TYPE_X86_64
 [CPU_TYPE_X86_64] = "x86_64",
+#endif
+#ifdef CPU_TYPE_ARM64
+[CPU_TYPE_ARM64] = "aarch64",
 #endif
   };
 
diff --git a/proc/host.c b/proc/host.c
index 0197fecf..e0aff20a 100644
--- a/proc/host.c
+++ b/proc/host.c
@@ -355,11 +355,11 @@ initialize_version_info (void)
   assert_backtrace (! err);
   snprintf (uname_info.machine, sizeof uname_info.machine,
"%s"
-#ifndef __x86_64__
+#if !defined (__x86_64__) && !defined (__aarch64__)
"-%s"
 #endif
, mach_cpu_types[info.cpu_type]
-#ifndef __x86_64__
+#if !defined (__x86_64__) && !defined (__aarch64__)
, mach_cpu_subtypes[info.cpu_type][info.cpu_subtype]
 #endif
);
-- 
2.44.0




[PATCH 01/10] term: Fix function prototype

2024-03-23 Thread Sergey Bugaev
struct bottomhalf.mdmstate is of type error_t (*)(int *state).

Fixes -Wincompatible-pointer-types, which is a hard error by default
in GCC 14.
---
 term/hurdio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/term/hurdio.c b/term/hurdio.c
index c6e14a4a..eab59b72 100644
--- a/term/hurdio.c
+++ b/term/hurdio.c
@@ -614,7 +614,7 @@ hurdio_mdmctl (int how, int bits)
 
 
 static int
-hurdio_mdmstate (void)
+hurdio_mdmstate (int *state)
 {
   int oldbits;
 
-- 
2.44.0




[PATCH 06/10] exec: Stop relying on address space size

2024-03-23 Thread Sergey Bugaev
The code here just wants to deallocate the whole address space, and Mach
already contains the logic to limit the passed-in range to the vm_map's
actual bounds (see VM_MAP_RANGE_CHECK).
---
 exec/exec.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/exec/exec.c b/exec/exec.c
index f6788520..ac226f9a 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -1219,9 +1219,7 @@ do_exec (file_t file,
   munmap ((caddr_t) threads, nthreads * sizeof (thread_t));
 
   /* Deallocate the entire virtual address space of the task.  */
-
-  vm_deallocate (oldtask,
-VM_MIN_ADDRESS, VM_MAX_ADDRESS - VM_MIN_ADDRESS);
+  vm_deallocate (oldtask, 0, (vm_size_t) -1);
 
   /* Nothing is supposed to go wrong any more.  If anything does, the
 old task is now in a hopeless state and must be killed.  */
-- 
2.44.0




[PATCH 08/10] elfcore: Add support for saving AArch64 registers

2024-03-23 Thread Sergey Bugaev
---
 exec/elfcore.c | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/exec/elfcore.c b/exec/elfcore.c
index c6aa2bc8..8c85b13b 100644
--- a/exec/elfcore.c
+++ b/exec/elfcore.c
@@ -187,6 +187,32 @@ fetch_thread_fpregset (thread_t thread, prfpregset_t 
*fpregs)
   (thread_state_t) fpregs, );
 }
 
+#elif defined (AARCH64_THREAD_STATE)
+
+# define ELF_MACHINE   EM_AARCH64
+
+static inline void
+fetch_thread_regset (thread_t thread, prgregset_t *gregs)
+{
+  mach_msg_type_number_t count = AARCH64_THREAD_STATE_COUNT;
+  _Static_assert (sizeof (prgregset_t) == sizeof (struct aarch64_thread_state),
+ "thread state mismatch");
+  (void) thread_get_state (thread, AARCH64_THREAD_STATE,
+  (thread_state_t) gregs, );
+  assert_backtrace (count == AARCH64_THREAD_STATE_COUNT);
+}
+
+static inline void
+fetch_thread_fpregset (thread_t thread, prfpregset_t *fpregs)
+{
+  mach_msg_type_number_t count = AARCH64_FLOAT_STATE_COUNT;
+  _Static_assert (sizeof (prfpregset_t) == sizeof (struct aarch64_float_state),
+ "float state mismatch");
+  (void) thread_get_state (thread, AARCH64_FLOAT_STATE,
+  (thread_state_t) fpregs, );
+  assert_backtrace (count == AARCH64_FLOAT_STATE_COUNT);
+}
+
 #else
 # warning "do not understand this machine flavor, no registers in dumps"
 # define ELF_MACHINE   EM_NONE
-- 
2.44.0




[PATCH 07/10] exec: Add support for AArch64 executables

2024-03-23 Thread Sergey Bugaev
This maps to EM_AARCH64.  Just like the x86_64 branch, we only compile
this code if CPU_TYPE_ARM64 is defined in Mach headers, to avoid
raising Mach version requirement on other architectures; and we
explicitly enable the branch when building for AArch64 itself, to get
a build error if CPU_TYPE_ARM64 is somehow not defined.
---
 exec/hostarch.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/exec/hostarch.c b/exec/hostarch.c
index ed50e0a8..81bbeb63 100644
--- a/exec/hostarch.c
+++ b/exec/hostarch.c
@@ -90,6 +90,11 @@ elf_machine_matches_host (ElfW(Half) e_machine)
 case CPU_TYPE_HPPA:
   CACHE (e_machine == EM_PARISC);
 
+#if defined (CPU_TYPE_ARM64) || defined(__aarch64__)
+case CPU_TYPE_ARM64:
+  CACHE (e_machine == EM_AARCH64);
+#endif
+
 default:
   return EGRATUITOUS;  /* XXX */
 }
-- 
2.44.0




[PATCH 10/10] boot: Add support for AArch64

2024-03-23 Thread Sergey Bugaev
---
 boot/userland-boot.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/boot/userland-boot.c b/boot/userland-boot.c
index f407f0a6..496628eb 100644
--- a/boot/userland-boot.c
+++ b/boot/userland-boot.c
@@ -334,6 +334,17 @@ boot_script_exec_cmd (void *hook,
 thread_set_state (thread, ALPHA_THREAD_STATE,
  (thread_state_t) , reg_size);
   }
+#elif defined (AARCH64_THREAD_STATE_COUNT)
+  {
+struct aarch64_thread_state regs;
+reg_size = AARCH64_THREAD_STATE_COUNT;
+thread_get_state (thread, AARCH64_THREAD_STATE,
+ (thread_state_t) , _size);
+regs.sp = (long) arg_pos;
+regs.pc = (long) startpc;
+thread_set_state (thread, AARCH64_THREAD_STATE,
+ (thread_state_t) , reg_size);
+  }
 #else
 # error needs to be ported
 #endif
-- 
2.44.0




[PATCH 02/10] exec: Fix creating executable stacks

2024-03-23 Thread Sergey Bugaev
The previous logic had two independent issues:

* We need to make the stack executable if either the program or its ELF
  interpreter requires executable stack.  In practice, it's common for
  the program itself to not require executable stack, but ld.so (glibc)
  needs it.

* mach_setup_thread () allocates stacks with a simple vm_allocate (),
  which creates non-executable memory.  So if an executable stack is
  required, the stack has to be vm_protect'ed to enable execution, not
  the other way around.  As the comment suggest, it would've been better
  to use vm_map () with the desired protection directly.
---
 exec/exec.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/exec/exec.c b/exec/exec.c
index 639564cb..f6788520 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -1335,11 +1335,12 @@ do_exec (file_t file,
   if (e.error)
 goto out;
 
-  /* It would probably be better to change mach_setup_thread so
- it does a vm_map with the right permissions to start with.  */
-  if (!e.info.elf.execstack)
+  /* mach_setup_thread () creates non-executable stacks (with vm_allocate ()).
+ It would probably be better to change mach_setup_thread () so it does
+ a vm_map () with the right permissions to start with.  */
+  if (e.info.elf.execstack || (e.interp.section && interp.info.elf.execstack))
 e.error = vm_protect (newtask, boot->stack_base, boot->stack_size,
- 0, VM_PROT_READ | VM_PROT_WRITE);
+ 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
 
   if (oldtask != newtask && oldtask != MACH_PORT_NULL)
 {
-- 
2.44.0




[PATCH 05/10] libshouldbeinlibc: Stop relying on address space size

2024-03-23 Thread Sergey Bugaev
While GNU Mach on AArch64 still exports VM_MIN_ADDRESS / VM_MAX_ADDRESS
for compatibility, we should try to rely on it less when possible; in
the future we might be able to stop exporting them from Mach.  The code
here really just wants to wire everything in its address space, and the
wire_segment_internal () routine already queries for actually present
memory regions dynamically.
---
 libshouldbeinlibc/wire.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libshouldbeinlibc/wire.c b/libshouldbeinlibc/wire.c
index ea6c5526..d1c745a8 100644
--- a/libshouldbeinlibc/wire.c
+++ b/libshouldbeinlibc/wire.c
@@ -136,7 +136,7 @@ wire_task_self (void)
   if (err)
 return err;
 
-  err = wire_segment_internal (VM_MIN_ADDRESS, VM_MAX_ADDRESS, host);
+  err = wire_segment_internal (0, (vm_size_t) -1, host);
   if (err)
 goto out;
 
-- 
2.44.0




[PATCH 03/10] Make long & friends 64-bit on 64-bit platforms

2024-03-23 Thread Sergey Bugaev
Not only on x86_64.
---
 hurd/hurd_types.defs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hurd/hurd_types.defs b/hurd/hurd_types.defs
index 9f176fef..0086d139 100644
--- a/hurd/hurd_types.defs
+++ b/hurd/hurd_types.defs
@@ -425,7 +425,7 @@ type flock_t = struct {
 };
 
 type unsigned_int = uint32_t;
-#if defined(__x86_64__)
+#if defined(__LP64__)
 type long = int64_t;
 type unsigned_long = uint64_t;
 
-- 
2.44.0




[PATCH 04/10] proc: Only try host_kernel_version () on i386

2024-03-23 Thread Sergey Bugaev
None of the new architectures are going to have it; that isn't specific
to x86_64.
---
 proc/host.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/proc/host.c b/proc/host.c
index 823bda53..0197fecf 100644
--- a/proc/host.c
+++ b/proc/host.c
@@ -371,8 +371,8 @@ initialize_version_info (void)
   server_versions_nalloc = 10;
 
   err = host_get_kernel_version (mach_host_self (), kv);
-#ifndef __x86_64__
-  /* We don't support host_kernel_version for x86_64. */
+#ifdef __i386__
+  /* We only supported host_kernel_version on i386.  */
   if (err == MIG_BAD_ID)
 {
   /* Delete after some time. */
-- 
2.44.0