[PATCH] libgo: check if -lucontext is required for {make, set, get}context

2022-12-19 Thread soeren--- via Gcc-patches
From: Sören Tempel 

This patch is similar to the existing check for librt. If libucontext
is installed and libucontext.a provides the aforementioned symbols, then
it is added to $LIBS. If not, no error is emitted. We could,
alternatively, also check libc.a for these symbols and thus prefer libc
over libucontext if both are installed and provide the symbols. If
deemed desirable, this could be achieved by changing the invocation
to AC_SEARCH_LIBS([makecontext], [c ucontext]).

This version of this patch has been tested on x86_64 Alpine Linux Edge
(libucontext 1.2 + musl 1.2.3) and Arch Linux (glibc 2.36). On the
latter, the check is a no-op and $LIBS is not modified.

Signed-off-by: Sören Tempel 
---
 libgo/configure| 178 +
 libgo/configure.ac |   5 ++
 2 files changed, 183 insertions(+)

diff --git a/libgo/configure b/libgo/configure
index 460fdad7..ac9202dc 100755
--- a/libgo/configure
+++ b/libgo/configure
@@ -14818,6 +14818,184 @@ fi
 
 
 
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing 
makecontext" >&5
+printf %s "checking for library containing makecontext... " >&6; }
+if test ${ac_cv_search_makecontext+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char makecontext ();
+int
+main (void)
+{
+return makecontext ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' ucontext
+do
+  if test -z "$ac_lib"; then
+ac_res="none required"
+  else
+ac_res=-l$ac_lib
+LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_search_makecontext=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+conftest$ac_exeext
+  if test ${ac_cv_search_makecontext+y}
+then :
+  break
+fi
+done
+if test ${ac_cv_search_makecontext+y}
+then :
+
+else $as_nop
+  ac_cv_search_makecontext=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: 
$ac_cv_search_makecontext" >&5
+printf "%s\n" "$ac_cv_search_makecontext" >&6; }
+ac_res=$ac_cv_search_makecontext
+if test "$ac_res" != no
+then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing 
getcontext" >&5
+printf %s "checking for library containing getcontext... " >&6; }
+if test ${ac_cv_search_getcontext+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char getcontext ();
+int
+main (void)
+{
+return getcontext ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' ucontext
+do
+  if test -z "$ac_lib"; then
+ac_res="none required"
+  else
+ac_res=-l$ac_lib
+LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_search_getcontext=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+conftest$ac_exeext
+  if test ${ac_cv_search_getcontext+y}
+then :
+  break
+fi
+done
+if test ${ac_cv_search_getcontext+y}
+then :
+
+else $as_nop
+  ac_cv_search_getcontext=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: 
$ac_cv_search_getcontext" >&5
+printf "%s\n" "$ac_cv_search_getcontext" >&6; }
+ac_res=$ac_cv_search_getcontext
+if test "$ac_res" != no
+then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing 
setcontext" >&5
+printf %s "checking for library containing setcontext... " >&6; }
+if test ${ac_cv_search_setcontext+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char setcontext ();
+int
+main (void)
+{
+return setcontext ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' ucontext
+do
+  if test -z "$ac_lib"; then
+ac_res="none required"
+  else
+ac_res=-l$ac_lib
+LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_search_setcontext=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+conftest$ac_exeext
+  if test ${ac_cv_search_setcontext+y}
+then :
+  break
+fi
+done

[PATCH v2] libgo: Don't rely on GNU-specific strerror_r variant on Linux

2022-11-29 Thread soeren--- via Gcc-patches
From: Sören Tempel 

On glibc, there are two versions of strerror_r: An XSI-compliant and a
GNU-specific version. The latter is only available on glibc. In order
to avoid duplicating the post-processing code of error messages, this
commit provides a separate strerror_go symbol which always refers to the
XSI-compliant version of strerror_r (even on glibc) by selectively
undefining the corresponding feature test macro.

Previously, gofrontend assumed that the GNU-specific version of
strerror_r was always available on Linux (which isn't the case when
using a musl as a libc, for example). This commit thereby improves
compatibility with Linux systems that are not using glibc.

Tested on x86_64 Alpine Linux Edge and Arch Linux (glibc 2.36).

Alternative: Use a GNU autoconf macro to detect which version is in
use. However, this requires moving the allocations and post-processing
logic from Go to C.

Signed-off-by: Sören Tempel 
---
Changes since v1: Fixed a typo in the Makefile.

 libgo/Makefile.am|  1 +
 libgo/Makefile.in|  6 +-
 libgo/go/syscall/errstr.go   |  9 +++--
 libgo/go/syscall/errstr_glibc.go | 34 
 libgo/runtime/go-strerror.c  | 30 
 5 files changed, 39 insertions(+), 41 deletions(-)
 delete mode 100644 libgo/go/syscall/errstr_glibc.go
 create mode 100644 libgo/runtime/go-strerror.c

diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index b03e6553..207d5a98 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -465,6 +465,7 @@ runtime_files = \
runtime/go-nanotime.c \
runtime/go-now.c \
runtime/go-nosys.c \
+   runtime/go-strerror.c \
runtime/go-reflect-call.c \
runtime/go-setenv.c \
runtime/go-signal.c \
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index 16ed62a8..0407e09c 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -247,7 +247,7 @@ am__objects_4 = runtime/aeshash.lo runtime/go-assert.lo \
runtime/go-fieldtrack.lo runtime/go-matherr.lo \
runtime/go-memclr.lo runtime/go-memmove.lo \
runtime/go-memequal.lo runtime/go-nanotime.lo \
-   runtime/go-now.lo runtime/go-nosys.lo \
+   runtime/go-now.lo runtime/go-nosys.lo runtime/go-strerror.lo \
runtime/go-reflect-call.lo runtime/go-setenv.lo \
runtime/go-signal.lo runtime/go-unsafe-pointer.lo \
runtime/go-unsetenv.lo runtime/go-unwind.lo \
@@ -917,6 +917,7 @@ runtime_files = \
runtime/go-nanotime.c \
runtime/go-now.c \
runtime/go-nosys.c \
+   runtime/go-strerror.c \
runtime/go-reflect-call.c \
runtime/go-setenv.c \
runtime/go-signal.c \
@@ -1390,6 +1391,8 @@ runtime/go-now.lo: runtime/$(am__dirstamp) \
runtime/$(DEPDIR)/$(am__dirstamp)
 runtime/go-nosys.lo: runtime/$(am__dirstamp) \
runtime/$(DEPDIR)/$(am__dirstamp)
+runtime/go-strerror.lo: runtime/$(am__dirstamp) \
+   runtime/$(DEPDIR)/$(am__dirstamp)
 runtime/go-reflect-call.lo: runtime/$(am__dirstamp) \
runtime/$(DEPDIR)/$(am__dirstamp)
 runtime/go-setenv.lo: runtime/$(am__dirstamp) \
@@ -1453,6 +1456,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ 
@am__quote@runtime/$(DEPDIR)/go-memmove.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@runtime/$(DEPDIR)/go-nanotime.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-nosys.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ 
@am__quote@runtime/$(DEPDIR)/go-strerror.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-now.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@runtime/$(DEPDIR)/go-reflect-call.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-setenv.Plo@am__quote@
diff --git a/libgo/go/syscall/errstr.go b/libgo/go/syscall/errstr.go
index 59f7a82c..6cc73853 100644
--- a/libgo/go/syscall/errstr.go
+++ b/libgo/go/syscall/errstr.go
@@ -4,18 +4,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !hurd && !linux
-// +build !hurd,!linux
-
 package syscall
 
-//sysnbstrerror_r(errnum int, buf []byte) (err Errno)
-//strerror_r(errnum _C_int, buf *byte, buflen Size_t) _C_int
+//sysnbstrerror_go(errnum int, buf []byte) (err Errno)
+//strerror_go(errnum _C_int, buf *byte, buflen Size_t) _C_int
 
 func Errstr(errnum int) string {
for len := 128; ; len *= 2 {
b := make([]byte, len)
-   errno := strerror_r(errnum, b)
+   errno := strerror_go(errnum, b)
if errno == 0 {
i := 0
for b[i] != 0 {
diff --git a/libgo/go/syscall/errstr_glibc.go b/libgo/go/syscall/errstr_glibc.go
deleted file mode 100644
index 03a327db..
--- a/libgo/go/syscall/errstr_glibc.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// errstr_glibc.go -- GNU/Linux and GNU/Hurd specific error strings.
-
-// Copyright 

[PATCH] libgo: Don't rely on GNU-specific strerror_r variant on Linux

2022-11-29 Thread soeren--- via Gcc-patches
From: Sören Tempel 

On glibc, there are two versions of strerror_r: An XSI-compliant and a
GNU-specific version. The latter is only available on glibc. In order
to avoid duplicating the post-processing code of error messages, this
commit provides a separate strerror_go symbol which always refers to the
XSI-compliant version of strerror_r (even on glibc) by selectively
undefining the corresponding feature test macro.

Previously, gofrontend assumed that the GNU-specific version of
strerror_r was always available on Linux (which isn't the case when
using a musl as a libc, for example). This commit thereby improves
compatibility with Linux systems that are not using glibc.

Tested on x86_64 Alpine Linux Edge and Arch Linux (glibc 2.36).

Alternative: Use a GNU autoconf macro to detect which version is in
use. However, this requires moving the allocations and post-processing
logic from Go to C.

Signed-off-by: Sören Tempel 
---
I previously experimented a bit with the aforementioned GNU autoconf
macro, however, I believe this is the more elegant and portable solution
as it doesn't require dealing with memory allocation for XSI strerror_r
buffers etc.

 libgo/Makefile.am|  1 +
 libgo/Makefile.in|  6 +-
 libgo/go/syscall/errstr.go   |  9 +++--
 libgo/go/syscall/errstr_glibc.go | 34 
 libgo/runtime/go-strerror.c  | 30 
 5 files changed, 39 insertions(+), 41 deletions(-)
 delete mode 100644 libgo/go/syscall/errstr_glibc.go
 create mode 100644 libgo/runtime/go-strerror.c

diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index b03e6553..207d5a98 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -465,6 +465,7 @@ runtime_files = \
runtime/go-nanotime.c \
runtime/go-now.c \
runtime/go-nosys.c \
+   runtime/go-strerror.c \
runtime/go-reflect-call.c \
runtime/go-setenv.c \
runtime/go-signal.c \
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index 16ed62a8..ab9fa376 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -247,7 +247,7 @@ am__objects_4 = runtime/aeshash.lo runtime/go-assert.lo \
runtime/go-fieldtrack.lo runtime/go-matherr.lo \
runtime/go-memclr.lo runtime/go-memmove.lo \
runtime/go-memequal.lo runtime/go-nanotime.lo \
-   runtime/go-now.lo runtime/go-nosys.lo \
+   runtime/go-now.lo runtime/go-nosys.lo runtime/go-strerror.lo \
runtime/go-reflect-call.lo runtime/go-setenv.lo \
runtime/go-signal.lo runtime/go-unsafe-pointer.lo \
runtime/go-unsetenv.lo runtime/go-unwind.lo \
@@ -917,6 +917,7 @@ runtime_files = \
runtime/go-nanotime.c \
runtime/go-now.c \
runtime/go-nosys.c \
+   runtime/go-strerror.c \
runtime/go-reflect-call.c \
runtime/go-setenv.c \
runtime/go-signal.c \
@@ -1390,6 +1391,8 @@ runtime/go-now.lo: runtime/$(am__dirstamp) \
runtime/$(DEPDIR)/$(am__dirstamp)
 runtime/go-nosys.lo: runtime/$(am__dirstamp) \
runtime/$(DEPDIR)/$(am__dirstamp)
+runtime/strerror.lo: runtime/$(am__dirstamp) \
+   runtime/$(DEPDIR)/$(am__dirstamp)
 runtime/go-reflect-call.lo: runtime/$(am__dirstamp) \
runtime/$(DEPDIR)/$(am__dirstamp)
 runtime/go-setenv.lo: runtime/$(am__dirstamp) \
@@ -1453,6 +1456,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ 
@am__quote@runtime/$(DEPDIR)/go-memmove.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@runtime/$(DEPDIR)/go-nanotime.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-nosys.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ 
@am__quote@runtime/$(DEPDIR)/go-strerror.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-now.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@runtime/$(DEPDIR)/go-reflect-call.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-setenv.Plo@am__quote@
diff --git a/libgo/go/syscall/errstr.go b/libgo/go/syscall/errstr.go
index 59f7a82c..6cc73853 100644
--- a/libgo/go/syscall/errstr.go
+++ b/libgo/go/syscall/errstr.go
@@ -4,18 +4,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !hurd && !linux
-// +build !hurd,!linux
-
 package syscall
 
-//sysnbstrerror_r(errnum int, buf []byte) (err Errno)
-//strerror_r(errnum _C_int, buf *byte, buflen Size_t) _C_int
+//sysnbstrerror_go(errnum int, buf []byte) (err Errno)
+//strerror_go(errnum _C_int, buf *byte, buflen Size_t) _C_int
 
 func Errstr(errnum int) string {
for len := 128; ; len *= 2 {
b := make([]byte, len)
-   errno := strerror_r(errnum, b)
+   errno := strerror_go(errnum, b)
if errno == 0 {
i := 0
for b[i] != 0 {
diff --git a/libgo/go/syscall/errstr_glibc.go b/libgo/go/syscall/errstr_glibc.go
deleted file mode 100644
index 

[PATCH] libgo: use _off_t for mmap offset argument

2022-09-29 Thread soeren--- via Gcc-patches
From: Sören Tempel 

On glibc-based systems, off_t is a 32-bit type on 32-bit systems and a
64-bit type on 64-bit systems by default. However, on systems using musl
libc off_t is unconditionally a 64-bit type. As such, it is insufficient
to use a uintptr type for the mmap offset parameter.

Presently, the (incorrect) mmap declaration causes a libgo run-time
failure on 32-bit musl systems (fatal error: runtime: cannot allocate
memory). This commit fixes this run-time error.

Signed-off-by: Sören Tempel 
---
This implements what has been proposed by Ian in a GitHub comment
https://github.com/golang/go/issues/51280#issuecomment-1046322011

I don't have access to a 32-bit glibc system to test this on but
this does seem to work fine on 32-bit and 64-bit musl systems.

 libgo/go/runtime/mem_gccgo.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgo/go/runtime/mem_gccgo.go b/libgo/go/runtime/mem_gccgo.go
index fa3389d8..07bf325a 100644
--- a/libgo/go/runtime/mem_gccgo.go
+++ b/libgo/go/runtime/mem_gccgo.go
@@ -15,7 +15,7 @@ import (
 //go:linkname sysFree
 
 //extern mmap
-func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off 
uintptr) unsafe.Pointer
+func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off 
_off_t) unsafe.Pointer
 
 //extern munmap
 func munmap(addr unsafe.Pointer, length uintptr) int32
@@ -38,7 +38,7 @@ func init() {
 }
 
 func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uintptr) 
(unsafe.Pointer, int) {
-   p := sysMmap(addr, n, prot, flags, fd, off)
+   p := sysMmap(addr, n, prot, flags, fd, _off_t(off))
if uintptr(p) == _MAP_FAILED {
return nil, errno()
}


[PATCH v2] libgo: Portable access to thread ID in struct sigevent

2022-09-23 Thread soeren--- via Gcc-patches
From: Sören Tempel 

Tested on x86_64 Arch Linux (glibc) and Alpine Linux (musl libc).

Previously, libgo relied on the _sigev_un implementation-specific
field in struct sigevent, which is only available on glibc. This
patch uses the sigev_notify_thread_id macro instead which is mandated
by timer_create(2). In theory, this should work with any libc
implementation for Linux. Unfortunately, there is an open glibc bug
as glibc does not define this macro. For this reason, a glibc-specific
workaround is required. Other libcs (such as musl) define the macro
and don't require the workaround.

This makes go_signal compatible with musl libc.

See: https://sourceware.org/bugzilla/show_bug.cgi?id=27417

Signed-off-by: Sören Tempel 
---
Changes since v1: Add workaround for glibc.

 libgo/go/runtime/os_linux.go |  4 +++-
 libgo/runtime/go-signal.c| 15 +++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/libgo/go/runtime/os_linux.go b/libgo/go/runtime/os_linux.go
index 96fb1788..6653d85e 100644
--- a/libgo/go/runtime/os_linux.go
+++ b/libgo/go/runtime/os_linux.go
@@ -22,6 +22,8 @@ type mOS struct {
profileTimerValid uint32
 }
 
+func setProcID(uintptr, int32)
+
 func getProcID() uint64 {
return uint64(gettid())
 }
@@ -365,7 +367,7 @@ func setThreadCPUProfiler(hz int32) {
var sevp _sigevent
sevp.sigev_notify = _SIGEV_THREAD_ID
sevp.sigev_signo = _SIGPROF
-   *((*int32)(unsafe.Pointer(_sigev_un))) = int32(mp.procid)
+   setProcID(uintptr(unsafe.Pointer()), int32(mp.procid))
ret := timer_create(_CLOCK_THREAD_CPUTIME_ID, , )
if ret != 0 {
// If we cannot create a timer for this M, leave 
profileTimerValid false
diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
index 528d9b6d..c56350cc 100644
--- a/libgo/runtime/go-signal.c
+++ b/libgo/runtime/go-signal.c
@@ -16,6 +16,11 @@
   #define SA_RESTART 0
 #endif
 
+// Workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=27417
+#if __linux__ && !defined(sigev_notify_thread_id)
+  #define sigev_notify_thread_id _sigev_un._tid
+#endif
+
 #ifdef USING_SPLIT_STACK
 
 extern void __splitstack_getcontext(void *context[10]);
@@ -183,6 +188,16 @@ setSigactionHandler(struct sigaction* sa, uintptr handler)
sa->sa_sigaction = (void*)(handler);
 }
 
+void setProcID(uintptr_t, int32_t)
+   __asm__ (GOSYM_PREFIX "runtime.setProcID");
+
+void
+setProcID(uintptr_t ptr, int32_t v)
+{
+   struct sigevent *s = (void *)ptr;
+   s->sigev_notify_thread_id = v;
+}
+
 // C code to fetch values from the siginfo_t and ucontext_t pointers
 // passed to a signal handler.
 


[PATCH] libgo: Explicitly define SYS_timer_settime for 32-bit musl targets

2022-07-28 Thread soeren--- via Gcc-patches
From: Sören Tempel 

On 32-bit systems, musl only defines SYS_timer_settime32 not
SYS_timer_settime. This causes the following compilation error:

os_linux.go:251:30: error: reference to undefined name 
'_SYS_timer_settime'
  251 | return int32(syscall(_SYS_timer_settime, 
uintptr(timerid), uintptr(flags), uintptr(unsafe.Pointer(new)), 
uintptr(unsafe.Pointer(old)), 0, 0))
  |  ^

This commit fixes this error by "aliasing" SYS_timer_settime to
SYS_timer_settime32 if the latter is defined. This is also what
musl does internally [1].

[1]: 
https://git.musl-libc.org/cgit/musl/tree/src/internal/syscall.h?h=v1.2.3#n212
---
 libgo/sysinfo.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/libgo/sysinfo.c b/libgo/sysinfo.c
index fc021099..6848fba5 100644
--- a/libgo/sysinfo.c
+++ b/libgo/sysinfo.c
@@ -354,6 +354,12 @@ enum {
 };
 #endif
 
+// musl libc does not have SYS_timer_settime on 32-bit platforms
+// but defines SYS_timer_settime32 instead, alias accordingly.
+#ifdef SYS_timer_settime32
+#define SYS_timer_settime SYS_timer_settime32
+#endif
+
 #if defined(HAVE_LOFF_T)
 // loff_t can be defined as a macro; for -fgo-dump-spec make sure we
 // see a typedef.


[PATCH] libgo: make match.sh POSIX-shell compatible

2022-07-20 Thread soeren--- via Gcc-patches
From: Sören Tempel 

The `(( expression ))` syntax is a Bash extension and not supported by
POSIX shell [1]. However, the arithmetic expressions used by the
gobuild() function can also be expressed using arithmetic POSIX
expansions with `$(( expression ))` [2].

Contrary to the Bash extension, arithmetic expansion doesn't set
the return value if the expression is non-zero but instead just prints
the expression result. Hence, the expression also needs to be negated.
Without this patch, match.sh does currently not work correctly if
/bin/sh is not a symlink to Bash.

[1]: https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructs
[2]: 
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04

Signed-off-by: Sören Tempel 
---
 libgo/match.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libgo/match.sh b/libgo/match.sh
index 7ed587ff794..9fbb498544c 100755
--- a/libgo/match.sh
+++ b/libgo/match.sh
@@ -111,7 +111,7 @@ gobuild() {
 if test "$goarch" != "386"; then
line=$(echo "$line" | sed -e "s/\\(${wrap}\\)386\\(${wrap}\\)/\10\2/g")
 fi
-(($line))
+return $((!(line)))
 }
 
 matched=


[PATCH] mksysinfo: add support for musl libc

2022-06-27 Thread soeren--- via Gcc-patches
From: Sören Tempel 

This patch addresses two minor compatibility issues with musl libc:

* On some architecture (e.g. PowerPC), musl has more than one field
  prefixed with st_{a,m,c}tim in struct stat. This causes the sed(1)
  invocation to not work correctly (since it will only replace the first
  occurrence) [1]. This can be fixed by passing the 'g' flag to replace
  all occurrences.
* Since version 1.2.3, musl defines SYS_SECCOMP in signal.h [2]. This
  conflicts with mksysinfo extraction of syscall numbers [3]. By
  restricting the grep expression to only match lower case characters we
  can avoid a redefinition of SYS_SECCOMP. This is GCC PR 105225.

This patch combines two Alpine Linux patches which have been written by
Ariadne Conill and Natanael Copa. I haven't tested this with glibc but I
strongly suspect that both changes should not introduce any issue with
glibc.

[1]: https://git.musl-libc.org/cgit/musl/tree/arch/powerpc/bits/stat.h
[2]: 
https://git.musl-libc.org/cgit/musl/commit/?id=3dcbd896907d9d474da811b7c6b769342abaf651
[3]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105225

Signed-off-by: Sören Tempel 
---
 libgo/mksysinfo.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh
index 5aa30915..72044624 100755
--- a/libgo/mksysinfo.sh
+++ b/libgo/mksysinfo.sh
@@ -126,7 +126,7 @@ if ! grep '^const SIGCLD ' ${OUT} >/dev/null 2>&1; then
 fi
 
 # The syscall numbers.  We force the names to upper case.
-grep '^const _SYS_' gen-sysinfo.go | \
+grep '^const _SYS_[a-z]' gen-sysinfo.go | \
   sed -e 's/const _\(SYS_[^= ]*\).*$/\1/' | \
   while read sys; do
 sup=`echo $sys | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
@@ -506,7 +506,7 @@ fi
 
 # For historical reasons Go uses the suffix "timespec" instead of "tim" for
 # stat_t's time fields on NetBSD.
-st_times='-e s/st_atim/Atim/ -e s/st_mtim/Mtim/ -e s/st_ctim/Ctim/'
+st_times='-e s/st_atim/Atim/g -e s/st_mtim/Mtim/g -e s/st_ctim/Ctim/g'
 if test "${GOOS}" = "netbsd"; then
 st_times='-e s/st_atim/Atimespec/ -e s/st_mtim/Mtimespec/ -e 
s/st_ctim/Ctimespec/'
 fi


[PATCH] libgo: Recognize off64_t / loff_t type definition of musl libc

2022-04-24 Thread soeren--- via Gcc-patches
From: Sören Tempel 

The libgo code assumes both off64_t and loff_t to be present. For
example, for the splice(2) function prototype. Similar to glibc,
musl libc supports these types but defines them as macros, not as
typedefs. Unfortunately, -fdump-go-spec only recognizes types defined
using typedef. To workaround that, this commit adds explicit typedefs
for these types if off64_t or loff_t are defined as macros.

Furthermore, loff_t is only defined on musl with -D_GNU_SOURCE and
requires an include of fcntl.h (this is in accordance with the splice(2)
man page). Therefore, the configure script has also been adjusted
accordingly.
---
 libgo/configure|  6 +-
 libgo/configure.ac |  6 +-
 libgo/sysinfo.c| 14 ++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/libgo/configure b/libgo/configure
index ffe17c9b..b83ddfb3 100755
--- a/libgo/configure
+++ b/libgo/configure
@@ -15546,7 +15546,10 @@ _ACEOF
 
 fi
 
-ac_fn_c_check_type "$LINENO" "loff_t" "ac_cv_type_loff_t" 
"$ac_includes_default"
+CFLAGS_hold=$CFLAGS
+CFLAGS="$CFLAGS -D_GNU_SOURCE"
+ac_fn_c_check_type "$LINENO" "loff_t" "ac_cv_type_loff_t" "#include 
+"
 if test "x$ac_cv_type_loff_t" = xyes; then :
 
 cat >>confdefs.h <<_ACEOF
@@ -15556,6 +15559,7 @@ _ACEOF
 
 fi
 
+CFLAGS=$CFLAGS_hold
 
 LIBS_hold="$LIBS"
 LIBS="$LIBS -lm"
diff --git a/libgo/configure.ac b/libgo/configure.ac
index 7e2b98ba..b8f7d1a0 100644
--- a/libgo/configure.ac
+++ b/libgo/configure.ac
@@ -601,7 +601,11 @@ AC_STRUCT_DIRENT_D_TYPE
 
 AC_CHECK_FUNCS(accept4 dup3 epoll_create1 faccessat fallocate fchmodat 
fchownat futimesat getxattr inotify_add_watch inotify_init inotify_init1 
inotify_rm_watch listxattr mkdirat mknodat open64 openat pipe2 removexattr 
renameat setxattr sync_file_range splice syscall tee unlinkat unshare utimensat)
 AC_TYPE_OFF_T
-AC_CHECK_TYPES([loff_t])
+
+CFLAGS_hold=$CFLAGS
+CFLAGS="$CFLAGS -D_GNU_SOURCE"
+AC_CHECK_TYPES([loff_t], [], [], [[#include ]])
+CFLAGS=$CFLAGS_hold
 
 LIBS_hold="$LIBS"
 LIBS="$LIBS -lm"
diff --git a/libgo/sysinfo.c b/libgo/sysinfo.c
index 8ce061e2..22f52e5b 100644
--- a/libgo/sysinfo.c
+++ b/libgo/sysinfo.c
@@ -343,6 +343,20 @@ enum {
 #endif
 };
 
+// musl libc has both off64_t and loff_t. However, both of these types
+// are defined as CPP macros, not as C typedefs. Unfortunately, the GCC
+// option -fdump-go-spec only recognizes types defined using typedefs.
+#if defined(HAVE_OFF64_T) && defined(off64_t)
+typedef off64_t __musl_off64_t;
+#undef off64_t
+typedef __musl_off64_t off64_t;
+#endif
+#if defined(HAVE_LOFF_T) && defined(loff_t)
+typedef loff_t __musl_loff_t;
+#undef loff_t
+typedef __musl_loff_t loff_t;
+#endif
+
 // SIOCGIFMTU can't be added in the above enum as it might
 // be signed in some OSes.
 #ifdef SIOCGIFMTU


[PATCH v4] libgo: Don't use pt_regs member in mcontext_t

2022-03-10 Thread soeren--- via Gcc-patches
From: Sören Tempel 

The .regs member is primarily intended to be used in conjunction with
ptrace. Since this code is not using ptrace, using .regs is a bad idea.
Furthermore, the code currently fails to compile on musl since the
pt_regs type (used by .regs) is in an incomplete type which has to be
completed by inclusion of the asm/ptrace.h Kernel header. Contrary to
glibc, this header is not indirectly included by musl through other
header files.

This patch fixes compilation of this code with musl libc by accessing
the register values via .gp_regs/.gregs (depending on 32-bit or 64-bit
PowerPC) instead of using .regs. For more details, see
https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591261.html

For the offsets in gp_regs refer to the Kernel asm/ptrace.h header.

This patch has been tested on Alpine Linux ppc64le (uses musl libc).

Signed-off-by: Sören Tempel 

ChangeLog:

* libgo/runtime/go-signal.c (defined): Use .gp_regs/.gregs
  to access ppc64/ppc32 registers.
(dumpregs): Ditto.
---
Changes since v3: Add special handling for 32-bit PowerPC with glibc,
also avoid use of gregs_t type since glibc does not seem to define
it on PowerPC.

This version of the patch introduces a new macro (PPC_GPREGS) to access
these registers to special case musl/glibc handling in a central place
once instead of duplicating it twice.

 libgo/runtime/go-signal.c | 32 
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
index d30d1603adc..3255046260d 100644
--- a/libgo/runtime/go-signal.c
+++ b/libgo/runtime/go-signal.c
@@ -16,6 +16,21 @@
   #define SA_RESTART 0
 #endif
 
+// The PowerPC API for accessing gregs/gp_regs differs greatly across
+// different libc implementations (musl and glibc).  To workaround that,
+// define the canonical way to access these registers once here.
+//
+// See https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591360.html
+#ifdef __PPC__
+#if defined(__PPC64__)   /* ppc64 glibc & musl */
+#define PPC_GPREGS(MCTX) (MCTX)->gp_regs
+#elif defined(__GLIBC__) /* ppc32 glibc */
+#define PPC_GPREGS(MCTX) (MCTX)->uc_regs->gregs
+#else/* ppc32 musl */
+#define PPC_GPREGS(MCTX) (MCTX)->gregs
+#endif /* __PPC64__ */
+#endif /* __PPC__ */
+
 #ifdef USING_SPLIT_STACK
 
 extern void __splitstack_getcontext(void *context[10]);
@@ -224,7 +239,8 @@ getSiginfo(siginfo_t *info, void *context 
__attribute__((unused)))
 #elif defined(__alpha__) && defined(__linux__)
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.sc_pc;
 #elif defined(__PPC__) && defined(__linux__)
-   ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.regs->nip;
+   mcontext_t *m = &((ucontext_t*)(context))->uc_mcontext;
+   ret.sigpc = PPC_GPREGS(m)[32];
 #elif defined(__PPC__) && defined(_AIX)
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.jmp_context.iar;
 #elif defined(__aarch64__) && defined(__linux__)
@@ -341,13 +357,13 @@ dumpregs(siginfo_t *info __attribute__((unused)), void 
*context __attribute__((u
int i;
 
for (i = 0; i < 32; i++)
-   runtime_printf("r%d %X\n", i, m->regs->gpr[i]);
-   runtime_printf("pc  %X\n", m->regs->nip);
-   runtime_printf("msr %X\n", m->regs->msr);
-   runtime_printf("cr  %X\n", m->regs->ccr);
-   runtime_printf("lr  %X\n", m->regs->link);
-   runtime_printf("ctr %X\n", m->regs->ctr);
-   runtime_printf("xer %X\n", m->regs->xer);
+   runtime_printf("r%d %X\n", i, PPC_GPREGS(m)[i]);
+   runtime_printf("pc  %X\n", PPC_GPREGS(m)[32]);
+   runtime_printf("msr %X\n", PPC_GPREGS(m)[33]);
+   runtime_printf("cr  %X\n", PPC_GPREGS(m)[38]);
+   runtime_printf("lr  %X\n", PPC_GPREGS(m)[36]);
+   runtime_printf("ctr %X\n", PPC_GPREGS(m)[35]);
+   runtime_printf("xer %X\n", PPC_GPREGS(m)[37]);
  }
 #elif defined(__PPC__) && defined(_AIX)
  {


[PATCH v3] libgo: Don't use pt_regs member in mcontext_t

2022-03-06 Thread soeren--- via Gcc-patches
From: Sören Tempel 

The .regs member is primarily intended to be used in conjunction with
ptrace. Since this code is not using ptrace, using .regs is a bad idea.
Furthermore, the code currently fails to compile on musl since the
pt_regs type (used by .regs) is in an incomplete type which has to be
completed by inclusion of the asm/ptrace.h Kernel header. Contrary to
glibc, this header is not indirectly included by musl through other
header files.

This patch fixes compilation of this code with musl libc by accessing
the register values via .gp_regs/.gregs (depending on 32-bit or 64-bit
PowerPC) instead of using .regs. For more details, see
https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591261.html

For the offsets in gp_regs refer to the Kernel asm/ptrace.h header.

This patch has been tested on Alpine Linux ppc64le (uses musl libc).

Signed-off-by: Sören Tempel 

ChangeLog:

* libgo/runtime/go-signal.c (defined): Use .gp_regs/.gregs
  to access ppc64/ppc32 registers.
(dumpregs): Ditto.
---
Changes since v2: Fixed a minor type mistake which, unfortunately,
did not result in a compilation error.

 libgo/runtime/go-signal.c | 25 +
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
index d30d1603adc..53fe270e66f 100644
--- a/libgo/runtime/go-signal.c
+++ b/libgo/runtime/go-signal.c
@@ -224,7 +224,11 @@ getSiginfo(siginfo_t *info, void *context 
__attribute__((unused)))
 #elif defined(__alpha__) && defined(__linux__)
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.sc_pc;
 #elif defined(__PPC__) && defined(__linux__)
-   ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.regs->nip;
+#ifdef __PPC64__
+   ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gp_regs[32];
+#else
+   ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gregs[32];
+#endif
 #elif defined(__PPC__) && defined(_AIX)
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.jmp_context.iar;
 #elif defined(__aarch64__) && defined(__linux__)
@@ -338,16 +342,21 @@ dumpregs(siginfo_t *info __attribute__((unused)), void 
*context __attribute__((u
 #elif defined(__PPC__) && defined(__LITTLE_ENDIAN__) && defined(__linux__)
  {
mcontext_t *m = &((ucontext_t*)(context))->uc_mcontext;
+#ifdef __PPC64__
+   greg_t *gp = m->gp_regs;
+#else
+   greg_t *gp = m->gregs;
+#endif
int i;
 
for (i = 0; i < 32; i++)
-   runtime_printf("r%d %X\n", i, m->regs->gpr[i]);
-   runtime_printf("pc  %X\n", m->regs->nip);
-   runtime_printf("msr %X\n", m->regs->msr);
-   runtime_printf("cr  %X\n", m->regs->ccr);
-   runtime_printf("lr  %X\n", m->regs->link);
-   runtime_printf("ctr %X\n", m->regs->ctr);
-   runtime_printf("xer %X\n", m->regs->xer);
+   runtime_printf("r%d %X\n", i, gp[i]);
+   runtime_printf("pc  %X\n", gp[32]);
+   runtime_printf("msr %X\n", gp[33]);
+   runtime_printf("cr  %X\n", gp[38]);
+   runtime_printf("lr  %X\n", gp[36]);
+   runtime_printf("ctr %X\n", gp[35]);
+   runtime_printf("xer %X\n", gp[37]);
  }
 #elif defined(__PPC__) && defined(_AIX)
  {


[PATCH v2] libgo: Don't use pt_regs member in mcontext_t

2022-03-06 Thread soeren--- via Gcc-patches
From: Sören Tempel 

The .regs member is primarily intended to be used in conjunction with
ptrace. Since this code is not using ptrace, using .regs is a bad idea.
Furthermore, the code currently fails to compile on musl since the
pt_regs type (used by .regs) is in an incomplete type which has to be
completed by inclusion of the asm/ptrace.h Kernel header. Contrary to
glibc, this header is not indirectly included by musl through other
header files.

This patch fixes compilation of this code with musl libc by accessing
the register values via .gp_regs/.gregs (depending on 32-bit or 64-bit
PowerPC) instead of using .regs. For more details, see
https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591261.html

For the offsets in gp_regs refer to the Kernel asm/ptrace.h header.

This patch has been tested on Alpine Linux ppc64le (uses musl libc).

Signed-off-by: Sören Tempel 

ChangeLog:

* libgo/runtime/go-signal.c (defined): Use .gp_regs/.gregs
  to access ppc64/ppc32 registers.
(dumpregs): Ditto.
---
Changes since v1: Use .gp_regs/.gregs instead of .regs based on
feedback by Rich Felker, thereby avoiding the need to include
asm/ptrace.h for struct pt_regs.

 libgo/runtime/go-signal.c | 25 +
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
index d30d1603adc..647ad606019 100644
--- a/libgo/runtime/go-signal.c
+++ b/libgo/runtime/go-signal.c
@@ -224,7 +224,11 @@ getSiginfo(siginfo_t *info, void *context 
__attribute__((unused)))
 #elif defined(__alpha__) && defined(__linux__)
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.sc_pc;
 #elif defined(__PPC__) && defined(__linux__)
-   ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.regs->nip;
+#ifdef __PPC64__
+   ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gp_regs[32];
+#else
+   ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gregs[32];
+#endif
 #elif defined(__PPC__) && defined(_AIX)
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.jmp_context.iar;
 #elif defined(__aarch64__) && defined(__linux__)
@@ -338,16 +342,21 @@ dumpregs(siginfo_t *info __attribute__((unused)), void 
*context __attribute__((u
 #elif defined(__PPC__) && defined(__LITTLE_ENDIAN__) && defined(__linux__)
  {
mcontext_t *m = &((ucontext_t*)(context))->uc_mcontext;
+#ifdef __PPC64__
+   greg_t *gp = >gp_regs;
+#else
+   greg_t *gp = >gregs;
+#endif
int i;
 
for (i = 0; i < 32; i++)
-   runtime_printf("r%d %X\n", i, m->regs->gpr[i]);
-   runtime_printf("pc  %X\n", m->regs->nip);
-   runtime_printf("msr %X\n", m->regs->msr);
-   runtime_printf("cr  %X\n", m->regs->ccr);
-   runtime_printf("lr  %X\n", m->regs->link);
-   runtime_printf("ctr %X\n", m->regs->ctr);
-   runtime_printf("xer %X\n", m->regs->xer);
+   runtime_printf("r%d %X\n", i, gp[i]);
+   runtime_printf("pc  %X\n", gp[32]);
+   runtime_printf("msr %X\n", gp[33]);
+   runtime_printf("cr  %X\n", gp[38]);
+   runtime_printf("lr  %X\n", gp[36]);
+   runtime_printf("ctr %X\n", gp[35]);
+   runtime_printf("xer %X\n", gp[37]);
  }
 #elif defined(__PPC__) && defined(_AIX)
  {


[PATCH v2] x86: Fix -fsplit-stack feature detection via TARGET_CAN_SPLIT_STACK

2022-02-21 Thread soeren--- via Gcc-patches
From: Sören Tempel 

Since commit c163647ffbc9a20c8feb6e079dbecccfe016c82e -fsplit-stack
is only supported on glibc targets. However, this original commit
required some fixups. As part of the fixup, the changes to the
gnu-user-common.h and gnu.h were partially reverted in commit
60953a23d57b13a672f751bec0c6eefc059eb1ab thus causing TARGET_CAN_SPLIT_STACK
to be defined for non-glibc targets even though -fsplit-stack is
actually not supported and attempting to use it causes a runtime error.

This causes gcc internal code, such as ./gcc/go/gospec.c to not
correctly detect that -fsplit-stack is not supported and thus causes
gccgo to fail compilation on non-glibc targets.

This commit ensures that TARGET_CAN_SPLIT_STACK is only set if the
default libc is glibc. It is presently unclear to me if there is a
better way to detect glibc at pre-processor time.

The proposed changes have been tested on x86 and x86_64 Alpine Linux
(which uses musl libc) and fix compilation of gccgo for this target.

Signed-off-by: Sören Tempel 

gcc/ChangeLog:

* config/i386/gnu-user-common.h (defined): Only define
TARGET_CAN_SPLIT_STACK for glibc targets.
* config/i386/gnu.h (defined): Ditto.
---
Changes since v1: Use (DEFAULT_LIBC == LIBC_GLIBC) instead of
OPTION_GLIBC_P to detect use of glibc in a pre-processor context.

Is there a better way to detect use of glibc in the config header?

 gcc/config/i386/gnu-user-common.h | 5 +++--
 gcc/config/i386/gnu.h | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/gcc/config/i386/gnu-user-common.h 
b/gcc/config/i386/gnu-user-common.h
index 00226f5a455..e126c3fa9fa 100644
--- a/gcc/config/i386/gnu-user-common.h
+++ b/gcc/config/i386/gnu-user-common.h
@@ -66,7 +66,8 @@ along with GCC; see the file COPYING3.  If not see
 #define STACK_CHECK_STATIC_BUILTIN 1
 
 /* We only build the -fsplit-stack support in libgcc if the
-   assembler has full support for the CFI directives.  */
-#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE
+   assembler has full support for the CFI directives.  Also
+   we only support -fsplit-stack on glibc targets.  */
+#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE && (DEFAULT_LIBC == LIBC_GLIBC)
 #define TARGET_CAN_SPLIT_STACK
 #endif
diff --git a/gcc/config/i386/gnu.h b/gcc/config/i386/gnu.h
index 25fbc07f58c..17494333bb9 100644
--- a/gcc/config/i386/gnu.h
+++ b/gcc/config/i386/gnu.h
@@ -41,8 +41,9 @@ along with GCC.  If not, see .
 #define TARGET_THREAD_SSP_OFFSET0x14
 
 /* We only build the -fsplit-stack support in libgcc if the
-   assembler has full support for the CFI directives.  */
-#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE
+   assembler has full support for the CFI directives.  Also
+   we only support -fsplit-stack on glibc targets.  */
+#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE && (DEFAULT_LIBC == LIBC_GLIBC)
 #define TARGET_CAN_SPLIT_STACK
 #endif
 /* We steal the last transactional memory word.  */


[PATCH] x86: Fix -fsplit-stack feature detection via TARGET_CAN_SPLIT_STACK

2022-02-20 Thread soeren--- via Gcc-patches
From: Sören Tempel 

Since commit c163647ffbc9a20c8feb6e079dbecccfe016c82e -fsplit-stack
is only supported on glibc targets. However, this original commit
required some fixups. As part of the fixup, the changes to the
gnu-user-common.h and gnu.h where partially reverted in commit
60953a23d57b13a672f751bec0c6eefc059eb1ab thus causing TARGET_CAN_SPLIT_STACK
to be defined for non-glibc targets even though -fsplit-stack is
actually not supported and attempting to use it causes a runtime error.

This causes gcc internal code, such as ./gcc/go/gospec.cc to not
correctly detect that -fsplit-stack is not supported and thus causes
gccgo to fail compilation on non-glibc targets.

This commit ensures that TARGET_CAN_SPLIT_STACK is set based on the
changes performed in 2c31a8be4a5db11a0a0e97c366dded6362421086, i.e.
the new OPTION_GLIBC_P macro is now used to detect if -fsplit-stack is
supported in the x86 header files.

The proposed changes have been tested on x86_64 Alpine Linux (which uses
musl libc) and fix compilation of gccgo for this target.

Signed-off-by: Sören Tempel 

gcc/ChangeLog:

* config/i386/gnu-user-common.h (defined): Only define
TARGET_CAN_SPLIT_STACK for glibc targets.
* config/i386/gnu.h (defined): Ditto.
---
I hope this is the last fixup commit needed for the original -fsplit-stack
change. Apologizes that the integration was a bit messy, I am simply not
deeply familiar with the gcc code base. The change works fine on Alpine
and fixes gccgo compilation but please review it carefully and make sure
the macro guards for TARGET_CAN_SPLIT_STACK are aligned with the
ix86_supports_split_stack implementation.

Should we also check if TARGET_THREAD_SPLIT_STACK_OFFSET is defined?

 gcc/config/i386/gnu-user-common.h | 5 +++--
 gcc/config/i386/gnu.h | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/gcc/config/i386/gnu-user-common.h 
b/gcc/config/i386/gnu-user-common.h
index 23b54c5be52..bb745c2edaa 100644
--- a/gcc/config/i386/gnu-user-common.h
+++ b/gcc/config/i386/gnu-user-common.h
@@ -66,7 +66,8 @@ along with GCC; see the file COPYING3.  If not see
 #define STACK_CHECK_STATIC_BUILTIN 1
 
 /* We only build the -fsplit-stack support in libgcc if the
-   assembler has full support for the CFI directives.  */
-#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE
+   assembler has full support for the CFI directives.  Also
+   we only support -fsplit-stack on glibc targets.  */
+#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE && defined(OPTION_GLIBC_P)
 #define TARGET_CAN_SPLIT_STACK
 #endif
diff --git a/gcc/config/i386/gnu.h b/gcc/config/i386/gnu.h
index 401e60c9a02..92a29149b2e 100644
--- a/gcc/config/i386/gnu.h
+++ b/gcc/config/i386/gnu.h
@@ -41,8 +41,9 @@ along with GCC.  If not, see .
 #define TARGET_THREAD_SSP_OFFSET0x14
 
 /* We only build the -fsplit-stack support in libgcc if the
-   assembler has full support for the CFI directives.  */
-#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE
+   assembler has full support for the CFI directives.  Also
+   we only support -fsplit-stack on glibc targets.  */
+#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE && defined(OPTION_GLIBC_P)
 #define TARGET_CAN_SPLIT_STACK
 #endif
 /* We steal the last transactional memory word.  */


[PATCH v3] Disable -fsplit-stack support on non-glibc targets

2022-01-21 Thread soeren--- via Gcc-patches
From: Sören Tempel 

The -fsplit-stack option requires the pthread_t TCB definition in the
libc to provide certain struct fields at specific hardcoded offsets. As
far as I know, only glibc provides these fields at the required offsets.
Most notably, musl libc does not have these fields. However, since gcc
accesses the fields using a fixed offset, this does not cause a
compile-time error, but instead results in a silent memory corruption at
run-time with musl libc. For example, on s390x libgcc's
__stack_split_initialize CTOR will overwrite the cancel field in the
pthread_t TCB on musl.

The -fsplit-stack option is used within the gcc code base itself by
gcc-go (if available). On musl-based systems with split-stack support
(i.e. s390x or x86) this causes Go programs compiled with gcc-go to
misbehave at run-time.

This patch fixes gcc-go on musl by disabling -fsplit-stack in gcc itself
since it is not supported on non-glibc targets anyhow. This is achieved
by checking if gcc targets a glibc-based system. This check has been
added for x86 and s390x, the rs6000 config already checks for
TARGET_GLIBC_MAJOR. Other architectures do not have split-stack
support. With this patch applied, the gcc-go configure script will
detect that -fsplit-stack support is not available and will not use it.

See https://www.openwall.com/lists/musl/2012/10/16/12

This patch was written under the assumption that glibc is the only libc
implementation which supports the required fields at the required
offsets in the pthread_t TCB. The patch has been tested on Alpine Linux
Edge on the s390x and x86 architectures by bootstrapping Google's Go
implementation with gcc-go.

Signed-off-by: Sören Tempel 

gcc/ChangeLog:

* common/config/s390/s390-common.c (s390_supports_split_stack):
Only support split-stack on glibc targets.
* config/i386/gnu-user-common.h (STACK_CHECK_STATIC_BUILTIN): Ditto.
* config/i386/gnu.h (defined): Ditto.
---
This version of the patch fixes a few codingstyle violations pointed out
to me by Richard Sandiford, it does not include any functional changes
compared to previous versions of this patch.

 gcc/common/config/s390/s390-common.cc | 14 ++
 gcc/config/i386/gnu-user-common.h |  5 +++--
 gcc/config/i386/gnu.h |  5 -
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/gcc/common/config/s390/s390-common.cc 
b/gcc/common/config/s390/s390-common.cc
index 6ed2f89f3d0..547b0826f93 100644
--- a/gcc/common/config/s390/s390-common.cc
+++ b/gcc/common/config/s390/s390-common.cc
@@ -116,13 +116,19 @@ s390_handle_option (struct gcc_options *opts 
ATTRIBUTE_UNUSED,
 
 /* -fsplit-stack uses a field in the TCB, available with glibc-2.23.
We don't verify it, since earlier versions just have padding at
-   its place, which works just as well.  */
+   its place, which works just as well.  For other libc implementations
+   we disable the feature entirely to avoid corrupting the TCB.  */
 
 static bool
-s390_supports_split_stack (bool report ATTRIBUTE_UNUSED,
-  struct gcc_options *opts ATTRIBUTE_UNUSED)
+s390_supports_split_stack (bool report,
+  struct gcc_options *opts)
 {
-  return true;
+  if (opts->x_linux_libc == LIBC_GLIBC)
+return true;
+
+  if (report)
+error ("%<-fsplit-stack%> currently only supported on GNU/Linux");
+  return false;
 }
 
 #undef TARGET_DEFAULT_TARGET_FLAGS
diff --git a/gcc/config/i386/gnu-user-common.h 
b/gcc/config/i386/gnu-user-common.h
index 23b54c5be52..7525f788a9c 100644
--- a/gcc/config/i386/gnu-user-common.h
+++ b/gcc/config/i386/gnu-user-common.h
@@ -66,7 +66,8 @@ along with GCC; see the file COPYING3.  If not see
 #define STACK_CHECK_STATIC_BUILTIN 1
 
 /* We only build the -fsplit-stack support in libgcc if the
-   assembler has full support for the CFI directives.  */
-#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE
+   assembler has full support for the CFI directives and
+   targets glibc.  */
+#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE && OPTION_GLIBC
 #define TARGET_CAN_SPLIT_STACK
 #endif
diff --git a/gcc/config/i386/gnu.h b/gcc/config/i386/gnu.h
index 401e60c9a02..daa505a5d45 100644
--- a/gcc/config/i386/gnu.h
+++ b/gcc/config/i386/gnu.h
@@ -35,7 +35,10 @@ along with GCC.  If not, see .
crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
 #endif
 
-#ifdef TARGET_LIBC_PROVIDES_SSP
+/* -fsplit-stack uses a field in the TCB at a fixed offset. This
+   field is only available for glibc.  Disable -fsplit-stack for
+   other libc implementations to avoid silent TCB corruptions.  */
+#if defined (TARGET_LIBC_PROVIDES_SSP) && OPTION_GLIBC
 
 /* i386 glibc provides __stack_chk_guard in %gs:0x14.  */
 #define TARGET_THREAD_SSP_OFFSET0x14


[PATCH] libgo: include asm/ptrace.h for pt_regs definition on PowerPC

2022-01-02 Thread soeren--- via Gcc-patches
From: Sören Tempel 

Both glibc and musl libc declare pt_regs as an incomplete type. This
type has to be completed by inclusion of another header. On Linux, the
asm/ptrace.h header file provides this type definition. Without
including this header file, it is not possible to access the regs member
of the mcontext_t struct as done in libgo/runtime/go-signal.c. On glibc,
other headers (e.g. sys/user.h) include asm/ptrace.h but on musl
asm/ptrace.h is not included by other headers and thus the
aforementioned files do not compile without an explicit include of
asm/ptrace.h:

libgo/runtime/go-signal.c: In function 'getSiginfo':
libgo/runtime/go-signal.c:227:63: error: invalid use of undefined type 
'struct pt_regs'
  227 | ret.sigpc = 
((ucontext_t*)(context))->uc_mcontext.regs->nip;
  |

See also:

* 
https://git.musl-libc.org/cgit/musl/commit/?id=c2518a8efb6507f1b41c3b12e03b06f8f2317a1f
* https://github.com/kaniini/libucontext/issues/36

Signed-off-by: Sören Tempel 

ChangeLog:

* libgo/runtime/go-signal.c: Include asm/ptrace.h for the
  definition of pt_regs (used by mcontext_t) on PowerPC.
---
 libgo/runtime/go-signal.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
index d30d1603adc..fc01e04e4a1 100644
--- a/libgo/runtime/go-signal.c
+++ b/libgo/runtime/go-signal.c
@@ -10,6 +10,12 @@
 #include 
 #include 
 
+// On PowerPC, ucontext.h uses a pt_regs struct as an incomplete
+// type. This type must be completed by including asm/ptrace.h.
+#ifdef __PPC__
+#include 
+#endif
+
 #include "runtime.h"
 
 #ifndef SA_RESTART


[PATCH v2] Disable -fsplit-stack support on non-glibc targets

2021-12-18 Thread soeren--- via Gcc-patches
From: Sören Tempel 

The -fsplit-stack option requires the pthread_t TCB definition in the
libc to provide certain struct fields at specific hardcoded offsets. As
far as I know, only glibc provides these fields at the required offsets.
Most notably, musl libc does not have these fields. However, since gcc
accesses the fields using a fixed offset, this does not cause a
compile-time error, but instead results in a silent memory corruption at
run-time with musl libc. For example, on s390x libgcc's
__stack_split_initialize CTOR will overwrite the cancel field in the
pthread_t TCB on musl.

The -fsplit-stack option is used within the gcc code base itself by
gcc-go (if available). On musl-based systems with split-stack support
(i.e. s390x or x86) this causes Go programs compiled with gcc-go to
misbehave at run-time.

This patch fixes gcc-go on musl by disabling -fsplit-stack in gcc itself
since it is not supported on non-glibc targets anyhow. This is achieved
by checking if gcc targets a glibc-based system. This check has been
added for x86 and s390x, the rs6000 config already checks for
TARGET_GLIBC_MAJOR. Other architectures do not have split-stack
support. With this patch applied, the gcc-go configure script will
detect that -fsplit-stack support is not available and will not use it.

See https://www.openwall.com/lists/musl/2012/10/16/12

This patch was written under the assumption that glibc is the only libc
implementation which supports the required fields at the required
offsets in the pthread_t TCB. The patch has been tested on Alpine Linux
Edge on the s390x and x86 architectures by bootstrapping Google's Go
implementation with gcc-go.

Signed-off-by: Sören Tempel 

gcc/ChangeLog:

* common/config/s390/s390-common.c (s390_supports_split_stack):
Only support split-stack on glibc targets.
* config/i386/gnu-user-common.h (STACK_CHECK_STATIC_BUILTIN): Ditto.
* config/i386/gnu.h (defined): Ditto.
---
This version of the patch addresses feedback by Andrew Pinski and uses
OPTION_GLIBC as well as opts->x_linux_libc == LIBC_GLIBC to detect glibc
targets (instead of relying on TARGET_GLIBC_MAJOR).

 gcc/common/config/s390/s390-common.c | 11 +--
 gcc/config/i386/gnu-user-common.h|  5 +++--
 gcc/config/i386/gnu.h|  6 +-
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/gcc/common/config/s390/s390-common.c 
b/gcc/common/config/s390/s390-common.c
index b6bc8501742..fc86e0bc5e7 100644
--- a/gcc/common/config/s390/s390-common.c
+++ b/gcc/common/config/s390/s390-common.c
@@ -116,13 +116,20 @@ s390_handle_option (struct gcc_options *opts 
ATTRIBUTE_UNUSED,
 
 /* -fsplit-stack uses a field in the TCB, available with glibc-2.23.
We don't verify it, since earlier versions just have padding at
-   its place, which works just as well.  */
+   its place, which works just as well. For other libc implementations
+   we disable the feature entirely to avoid corrupting the TCB.  */
 
 static bool
 s390_supports_split_stack (bool report ATTRIBUTE_UNUSED,
   struct gcc_options *opts ATTRIBUTE_UNUSED)
 {
-  return true;
+  if (opts->x_linux_libc == LIBC_GLIBC) {
+return true;
+  } else {
+if (report)
+  error("%<-fsplit-stack%> currently only supported on GNU/Linux");
+return false;
+  }
 }
 
 #undef TARGET_DEFAULT_TARGET_FLAGS
diff --git a/gcc/config/i386/gnu-user-common.h 
b/gcc/config/i386/gnu-user-common.h
index 00226f5a455..6e13315b5a3 100644
--- a/gcc/config/i386/gnu-user-common.h
+++ b/gcc/config/i386/gnu-user-common.h
@@ -66,7 +66,8 @@ along with GCC; see the file COPYING3.  If not see
 #define STACK_CHECK_STATIC_BUILTIN 1
 
 /* We only build the -fsplit-stack support in libgcc if the
-   assembler has full support for the CFI directives.  */
-#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE
+   assembler has full support for the CFI directives and
+   targets glibc.  */
+#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE && OPTION_GLIBC
 #define TARGET_CAN_SPLIT_STACK
 #endif
diff --git a/gcc/config/i386/gnu.h b/gcc/config/i386/gnu.h
index 25fbc07f58c..adfe817201e 100644
--- a/gcc/config/i386/gnu.h
+++ b/gcc/config/i386/gnu.h
@@ -35,7 +35,11 @@ along with GCC.  If not, see .
crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
 #endif
 
-#ifdef TARGET_LIBC_PROVIDES_SSP
+/* -fsplit-stack uses a field in the TCB at a fixed offset. This
+   field is only available for glibc. Disable -fsplit-stack for
+   other libc implementation to avoid silent TCB corruptions.  */
+
+#if defined (TARGET_LIBC_PROVIDES_SSP) && OPTION_GLIBC
 
 /* i386 glibc provides __stack_chk_guard in %gs:0x14.  */
 #define TARGET_THREAD_SSP_OFFSET0x14


[PATCH] Disable -fsplit-stack support on non-glibc targets

2021-12-18 Thread soeren--- via Gcc-patches
From: Sören Tempel 

The -fsplit-stack option requires the pthread_t TCB definition in the
libc to provide certain struct fields at specific hardcoded offsets. As
far as I know, only glibc provides these fields at the required offsets.
Most notably, musl libc does not have these fields. However, since gcc
accesses the fields using a fixed offset, this does not cause a
compile-time error, but instead results in a silent memory corruption at
run-time with musl libc. For example, on s390x libgcc's
__stack_split_initialize CTOR will overwrite the cancel field in the
pthread_t TCB on musl.

The -fsplit-stack option is used within the gcc code base itself by
gcc-go (if available). On musl-based systems with split-stack support
(i.e. s390x or x86) this causes Go programs compiled with gcc-go to
misbehave at run-time.

This patch fixes gcc-go on musl by disabling -fsplit-stack in gcc itself
since it is not supported on non-glibc targets anyhow. This is achieved
by checking if TARGET_GLIBC_MAJOR is defined to a non-zero value (it
defaults to zero on non-glibc systems). The check has been added for x86
and s390x, the rs6000 config already checks for TARGET_GLIBC_MAJOR.
Other architectures do not have split-stack support. With this patch
applied, the gcc-go configure script will detect that -fsplit-stack
support is not available and will not use it.

See https://www.openwall.com/lists/musl/2012/10/16/12

This patch has been tested on Alpine Linux Edge on the s390x and x86
architectures by bootstrapping Google's Go implementation with gcc-go.

Signed-off-by: Sören Tempel 

gcc/ChangeLog:

* common/config/s390/s390-common.c (s390_supports_split_stack):
Only support split-stack on glibc targets.
* config/i386/gnu-user-common.h (STACK_CHECK_STATIC_BUILTIN): Ditto.
* config/i386/gnu.h (defined): Ditto.
---
 gcc/common/config/s390/s390-common.c | 9 -
 gcc/config/i386/gnu-user-common.h| 5 +++--
 gcc/config/i386/gnu.h| 6 +-
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/gcc/common/config/s390/s390-common.c 
b/gcc/common/config/s390/s390-common.c
index b6bc8501742..afbd8d3fe66 100644
--- a/gcc/common/config/s390/s390-common.c
+++ b/gcc/common/config/s390/s390-common.c
@@ -116,13 +116,20 @@ s390_handle_option (struct gcc_options *opts 
ATTRIBUTE_UNUSED,
 
 /* -fsplit-stack uses a field in the TCB, available with glibc-2.23.
We don't verify it, since earlier versions just have padding at
-   its place, which works just as well.  */
+   its place, which works just as well. For other libc implementations
+   we disable the feature entirely to avoid corrupting the TCB.  */
 
 static bool
 s390_supports_split_stack (bool report ATTRIBUTE_UNUSED,
   struct gcc_options *opts ATTRIBUTE_UNUSED)
 {
+#if TARGET_GLIBC_MAJOR
   return true;
+#else
+  if (report)
+error("%<-fsplit-stack%> currently only supported on GNU/Linux");
+  return false;
+#endif
 }
 
 #undef TARGET_DEFAULT_TARGET_FLAGS
diff --git a/gcc/config/i386/gnu-user-common.h 
b/gcc/config/i386/gnu-user-common.h
index 00226f5a455..69f2d7415ad 100644
--- a/gcc/config/i386/gnu-user-common.h
+++ b/gcc/config/i386/gnu-user-common.h
@@ -66,7 +66,8 @@ along with GCC; see the file COPYING3.  If not see
 #define STACK_CHECK_STATIC_BUILTIN 1
 
 /* We only build the -fsplit-stack support in libgcc if the
-   assembler has full support for the CFI directives.  */
-#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE
+   assembler has full support for the CFI directives and
+   targets glibc.  */
+#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE && TARGET_GLIBC_MAJOR
 #define TARGET_CAN_SPLIT_STACK
 #endif
diff --git a/gcc/config/i386/gnu.h b/gcc/config/i386/gnu.h
index 25fbc07f58c..895a7369816 100644
--- a/gcc/config/i386/gnu.h
+++ b/gcc/config/i386/gnu.h
@@ -35,7 +35,11 @@ along with GCC.  If not, see .
crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
 #endif
 
-#ifdef TARGET_LIBC_PROVIDES_SSP
+/* -fsplit-stack uses a field in the TCB at a fixed offset. This
+   field is only available for glibc. Disable -fsplit-stack for
+   other libc implementation to avoid silent TCB corruptions.  */
+
+#if defined (TARGET_LIBC_PROVIDES_SSP) && TARGET_GLIBC_MAJOR
 
 /* i386 glibc provides __stack_chk_guard in %gs:0x14.  */
 #define TARGET_THREAD_SSP_OFFSET0x14


[PATCH] stddef.h: add support for musl typedef macro guards

2021-11-26 Thread soeren--- via Gcc-patches
From: Sören Tempel 

The stddef.h header checks/sets various hardcoded toolchain/os specific
macro guards to prevent redefining types such as ptrdiff_t, wchar_t, or
size_t. However, without this patch, the file does not check/set the
typedef macro guards for musl libc. This causes types such as size_t to
be defined twice for files which include both musl's stddef.h as well as
GCC's ginclude/stddef.h. This is, for example, the case for
libgo/sysinfo.c. If libgo/sysinfo.c has multiple typedefs for size_t
this confuses -fdump-go-spec and causes size_t not to be included in the
generated type definitions thereby causing a gcc-go compilation failure
on Alpine Linux Edge (which uses musl libc) with the following error:

sysinfo.go:7765:13: error: use of undefined type '_size_t'
 7765 | type Size_t _size_t
  | ^
libcall_posix.go:49:35: error: non-integer len argument in make
   49 | b := make([]byte, len)
  |

This commit fixes this issue by ensuring that ptrdiff_t, wchar_t, and size_t
are only defined once in the pre-processed libgo/sysinfo.c file by enhancing
gcc/ginclude/stddef.h with musl-specific typedef macro guards.

gcc/ChangeLog:

* ginclude/stddef.h (__DEFINED_ptrdiff_t): Add support for musl
libc typedef macro guard.
(__DEFINED_size_t): Ditto.
(__DEFINED_wchar_t): Ditto.
---
 gcc/ginclude/stddef.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h
index 9d67eac4947..770a6d321b3 100644
--- a/gcc/ginclude/stddef.h
+++ b/gcc/ginclude/stddef.h
@@ -128,6 +128,7 @@ _TYPE_wchar_t;
 #ifndef ___int_ptrdiff_t_h
 #ifndef _GCC_PTRDIFF_T
 #ifndef _PTRDIFF_T_DECLARED /* DragonFly */
+#ifndef __DEFINED_ptrdiff_t /* musl libc */
 #define _PTRDIFF_T
 #define _T_PTRDIFF_
 #define _T_PTRDIFF
@@ -137,10 +138,12 @@ _TYPE_wchar_t;
 #define ___int_ptrdiff_t_h
 #define _GCC_PTRDIFF_T
 #define _PTRDIFF_T_DECLARED
+#define __DEFINED_ptrdiff_t
 #ifndef __PTRDIFF_TYPE__
 #define __PTRDIFF_TYPE__ long int
 #endif
 typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#endif /* __DEFINED_ptrdiff_t */
 #endif /* _PTRDIFF_T_DECLARED */
 #endif /* _GCC_PTRDIFF_T */
 #endif /* ___int_ptrdiff_t_h */
@@ -174,6 +177,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
 #ifndef _SIZE_T_DEFINED
 #ifndef _BSD_SIZE_T_DEFINED_   /* Darwin */
 #ifndef _SIZE_T_DECLARED   /* FreeBSD 5 */
+#ifndef __DEFINED_size_t   /* musl libc */
 #ifndef ___int_size_t_h
 #ifndef _GCC_SIZE_T
 #ifndef _SIZET_
@@ -191,6 +195,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
 #define _SIZE_T_DEFINED
 #define _BSD_SIZE_T_DEFINED_   /* Darwin */
 #define _SIZE_T_DECLARED   /* FreeBSD 5 */
+#define __DEFINED_size_t   /* musl libc */
 #define ___int_size_t_h
 #define _GCC_SIZE_T
 #define _SIZET_
@@ -215,6 +220,7 @@ typedef long ssize_t;
 #endif /* _SIZET_ */
 #endif /* _GCC_SIZE_T */
 #endif /* ___int_size_t_h */
+#endif /* __DEFINED_size_t */
 #endif /* _SIZE_T_DECLARED */
 #endif /* _BSD_SIZE_T_DEFINED_ */
 #endif /* _SIZE_T_DEFINED */
@@ -251,6 +257,7 @@ typedef long ssize_t;
 #ifndef _BSD_WCHAR_T_DEFINED_/* Darwin */
 #ifndef _BSD_RUNE_T_DEFINED_   /* Darwin */
 #ifndef _WCHAR_T_DECLARED /* FreeBSD 5 */
+#ifndef __DEFINED_wchar_t /* musl libc */
 #ifndef _WCHAR_T_DEFINED_
 #ifndef _WCHAR_T_DEFINED
 #ifndef _WCHAR_T_H
@@ -272,6 +279,7 @@ typedef long ssize_t;
 #define __INT_WCHAR_T_H
 #define _GCC_WCHAR_T
 #define _WCHAR_T_DECLARED
+#define __DEFINED_wchar_t
 
 /* On BSD/386 1.1, at least, machine/ansi.h defines _BSD_WCHAR_T_
instead of _WCHAR_T_, and _BSD_RUNE_T_ (which, unlike the other
@@ -326,6 +334,7 @@ typedef __WCHAR_TYPE__ wchar_t;
 #endif
 #endif
 #endif
+#endif /* __DEFINED_wchar_t */
 #endif /* _WCHAR_T_DECLARED */
 #endif /* _BSD_RUNE_T_DEFINED_ */
 #endif