From 31629873e63dfb89a14875fde7c2e9af54459af2 Mon Sep 17 00:00:00 2001 From: swcompiler Date: Wed, 30 Apr 2025 15:42:26 +0800 Subject: [PATCH] Add Sw64 ISA support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为glibc增加SW64架构的支持 包括配置文件增加SW64架构分支,SW64架构特定的基础库实现以及SW64操作系统接口的实现。 --- ...Sw64-Add-Sw64-entries-to-config.h.in.patch | 26 + ...ions-and-ELF-flags-to-elf.h-and-scri.patch | 173 + 0003-Sw64-ABI-Implementation.patch | 2732 ++++++ 0004-Sw64-Thread-Local-Storage-Support.patch | 356 + ...-Generic-math.h-and-soft-fp-Routines.patch | 356 + ...64-Atomic-and-Locking-Implementation.patch | 1123 +++ 0007-Sw64-Linux-Syscall-Interface.patch | 1143 +++ 0008-Sw64-Linux-ABI.patch | 7444 ++++++++++++++ 0009-Sw64-Add-ABI-Lists.patch | 4918 ++++++++++ 0010-Sw64-Build-Infrastructure.patch | 706 ++ 0011-Sw64-Integer-Operation-Support.patch | 7988 +++++++++++++++ ...w64-Memory-and-String-Implementation.patch | 8641 +++++++++++++++++ 0013-Sw64-math-support.patch | 5002 ++++++++++ 0014-Sw64-float128-Implementation.patch | 725 ++ 0015-Sw64-Add-get_rounding_mode.patch | 54 + 0016-Sw64-Add-specific-math-difinitons.patch | 63 + ...lf-initfini.h-and-ELF_INITFINI-for-s.patch | 40 + ...64-Type-definitions-for-nscd-on-sw64.patch | 40 + 0019-Sw64-GCC-frame-desciption-for-sw64.patch | 40 + 0020-Sw64-Update-libm-test-ulps.patch | 1854 ++++ ...test_numdouble.h-and-test_numfloat.h.patch | 233 + ...-posix-tst-glob_lstat_compat-on-sw64.patch | 25 + 0023-Sw64-add-getopt-weak-alias.patch | 32 + glibc.spec | 157 +- 24 files changed, 43865 insertions(+), 6 deletions(-) create mode 100644 0001-Sw64-Add-Sw64-entries-to-config.h.in.patch create mode 100644 0002-Sw64-Add-relocations-and-ELF-flags-to-elf.h-and-scri.patch create mode 100644 0003-Sw64-ABI-Implementation.patch create mode 100644 0004-Sw64-Thread-Local-Storage-Support.patch create mode 100644 0005-Sw64-Generic-math.h-and-soft-fp-Routines.patch create mode 100644 0006-Sw64-Atomic-and-Locking-Implementation.patch create mode 100644 0007-Sw64-Linux-Syscall-Interface.patch create mode 100644 0008-Sw64-Linux-ABI.patch create mode 100644 0009-Sw64-Add-ABI-Lists.patch create mode 100644 0010-Sw64-Build-Infrastructure.patch create mode 100644 0011-Sw64-Integer-Operation-Support.patch create mode 100644 0012-Sw64-Memory-and-String-Implementation.patch create mode 100644 0013-Sw64-math-support.patch create mode 100644 0014-Sw64-float128-Implementation.patch create mode 100644 0015-Sw64-Add-get_rounding_mode.patch create mode 100644 0016-Sw64-Add-specific-math-difinitons.patch create mode 100644 0017-Sw64-Introduce-elf-initfini.h-and-ELF_INITFINI-for-s.patch create mode 100644 0018-Sw64-Type-definitions-for-nscd-on-sw64.patch create mode 100644 0019-Sw64-GCC-frame-desciption-for-sw64.patch create mode 100644 0020-Sw64-Update-libm-test-ulps.patch create mode 100644 0021-Sw64-Add-test_numdouble.h-and-test_numfloat.h.patch create mode 100644 0022-Sw64-Fix-posix-tst-glob_lstat_compat-on-sw64.patch create mode 100644 0023-Sw64-add-getopt-weak-alias.patch diff --git a/0001-Sw64-Add-Sw64-entries-to-config.h.in.patch b/0001-Sw64-Add-Sw64-entries-to-config.h.in.patch new file mode 100644 index 0000000..130b9b1 --- /dev/null +++ b/0001-Sw64-Add-Sw64-entries-to-config.h.in.patch @@ -0,0 +1,26 @@ +From 7c6998e5e80b9690bf770ec093c7ae6a4a41a088 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Fri, 29 Nov 2024 13:39:15 +0800 +Subject: [PATCH 01/23] Sw64: Add Sw64 entries to config.h.in + +--- + config.h.in | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/config.h.in b/config.h.in +index 0dedc124..dbc566e5 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -29,6 +29,9 @@ + /* On powerpc*, define if scv should be used for syscalls (when available). */ + #undef USE_PPC_SCV + ++/* Sw64 new Libc version */ ++#undef HAVE_SW64_NEW_LIBCVERSION ++ + /* Define if _Unwind_Find_FDE should be exported from glibc. */ + #undef EXPORT_UNWIND_FIND_FDE + +-- +2.25.1 + diff --git a/0002-Sw64-Add-relocations-and-ELF-flags-to-elf.h-and-scri.patch b/0002-Sw64-Add-relocations-and-ELF-flags-to-elf.h-and-scri.patch new file mode 100644 index 0000000..3a1c592 --- /dev/null +++ b/0002-Sw64-Add-relocations-and-ELF-flags-to-elf.h-and-scri.patch @@ -0,0 +1,173 @@ +From 2abad8896fef244c5513d266184a1bfa32a5f509 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Fri, 29 Nov 2024 13:39:58 +0800 +Subject: [PATCH 02/23] Sw64: Add relocations and ELF flags to elf.h and + script/glibcelf.py + +--- + elf/elf.h | 79 +++++++++++++++++++++++++++++++++++++++++++++ + scripts/glibcelf.py | 10 ++++++ + 2 files changed, 89 insertions(+) + +diff --git a/elf/elf.h b/elf/elf.h +index 89fc8021..33a5e97b 100644 +--- a/elf/elf.h ++++ b/elf/elf.h +@@ -371,6 +372,10 @@ typedef struct + chances of collision with official or non-GNU unofficial values. */ + + #define EM_ALPHA 0x9026 ++#define EM_SW_64 0x9916 ++ ++ ++ + + /* Legal values for e_version (version). */ + +@@ -2426,6 +2431,80 @@ enum + /* Legal values for d_tag of Elf64_Dyn. */ + #define DT_ALPHA_PLTRO (DT_LOPROC + 0) + #define DT_ALPHA_NUM 1 ++/* SW_64 specific definitions. */ ++ ++/* Legal values for e_flags field of Elf64_Ehdr. */ ++ ++#define EF_SW_64_32BIT 1 /* All addresses must be < 2GB. */ ++#define EF_SW_64_CANRELAX 2 /* Relocations for relaxing exist. */ ++ ++/* Legal values for sh_type field of Elf64_Shdr. */ ++ ++/* These two are primerily concerned with ECOFF debugging info. */ ++#define SHT_SW_64_DEBUG 0x70000001 ++#define SHT_SW_64_REGINFO 0x70000002 ++ ++/* Legal values for sh_flags field of Elf64_Shdr. */ ++ ++#define SHF_SW_64_GPREL 0x10000000 ++ ++/* Legal values for st_other field of Elf64_Sym. */ ++#define STO_SW_64_NOPV 0x80 /* No PV required. */ ++#define STO_SW_64_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ ++ ++/* SW_64 relocs. */ ++ ++#define R_SW_64_NONE 0 /* No reloc */ ++#define R_SW_64_REFLONG 1 /* Direct 32 bit */ ++#define R_SW_64_REFQUAD 2 /* Direct 64 bit */ ++#define R_SW_64_GPREL32 3 /* GP relative 32 bit */ ++#define R_SW_64_LITERAL 4 /* GP relative 16 bit w/optimization */ ++#define R_SW_64_LITUSE 5 /* Optimization hint for LITERAL */ ++#define R_SW_64_GPDISP 6 /* Add displacement to GP */ ++#define R_SW_64_BRADDR 7 /* PC+4 relative 23 bit shifted */ ++#define R_SW_64_HINT 8 /* PC+4 relative 16 bit shifted */ ++#define R_SW_64_SREL16 9 /* PC relative 16 bit */ ++#define R_SW_64_SREL32 10 /* PC relative 32 bit */ ++#define R_SW_64_SREL64 11 /* PC relative 64 bit */ ++#define R_SW_64_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ ++#define R_SW_64_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ ++#define R_SW_64_GPREL16 19 /* GP relative 16 bit */ ++#define R_SW_64_COPY 24 /* Copy symbol at runtime */ ++#define R_SW_64_GLOB_DAT 25 /* Create GOT entry */ ++#define R_SW_64_JMP_SLOT 26 /* Create PLT entry */ ++#define R_SW_64_RELATIVE 27 /* Adjust by program base */ ++#define R_SW_64_TLS_GD_HI 28 ++#define R_SW_64_TLSGD 29 ++#define R_SW_64_TLS_LDM 30 ++#define R_SW_64_DTPMOD64 31 ++#define R_SW_64_GOTDTPREL 32 ++#define R_SW_64_DTPREL64 33 ++#define R_SW_64_DTPRELHI 34 ++#define R_SW_64_DTPRELLO 35 ++#define R_SW_64_DTPREL16 36 ++#define R_SW_64_GOTTPREL 37 ++#define R_SW_64_TPREL64 38 ++#define R_SW_64_TPRELHI 39 ++#define R_SW_64_TPRELLO 40 ++#define R_SW_64_TPREL16 41 ++/* Keep this the last entry. */ ++#define R_SW_64_NUM 46 ++ ++/* Magic values of the LITUSE relocation addend. */ ++#define LITUSE_SW_64_ADDR 0 ++#define LITUSE_SW_64_BASE 1 ++#define LITUSE_SW_64_BYTOFF 2 ++#define LITUSE_SW_64_JSR 3 ++#define LITUSE_SW_64_TLS_GD 4 ++#define LITUSE_SW_64_TLS_LDM 5 ++ ++/* Legal values for d_tag of Elf64_Dyn. */ ++#define DT_SW_64_PLTRO (DT_LOPROC + 0) ++#define DT_SW_64_NUM 1 ++ ++ ++ ++ + + /* PowerPC specific declarations */ + +diff --git a/scripts/glibcelf.py b/scripts/glibcelf.py +index b52e83d6..2c191afa 100644 +--- a/scripts/glibcelf.py ++++ b/scripts/glibcelf.py +@@ -304,6 +304,8 @@ class Sht(_TypedConstant): + prefix = 'SHT_' + class ShtALPHA(Sht): + """Supplemental SHT_* constants for EM_ALPHA.""" ++class ShtSW_64(Sht): ++ """Supplemental SHT_* constants for EM_SW_64.""" + class ShtARC(Sht): + """Supplemental SHT_* constants for EM_ARC.""" + class ShtARM(Sht): +@@ -319,6 +321,7 @@ class ShtPARISC(Sht): + class ShtRISCV(Sht): + """Supplemental SHT_* constants for EM_RISCV.""" + _register_elf_h(ShtALPHA, prefix='SHT_ALPHA_', parent=Sht) ++_register_elf_h(ShtSW_64, prefix='SHT_SW_64_', parent=Sht) + _register_elf_h(ShtARC, prefix='SHT_ARC_', parent=Sht) + _register_elf_h(ShtARM, prefix='SHT_ARM_', parent=Sht) + _register_elf_h(ShtCSKY, prefix='SHT_CSKY_', parent=Sht) +@@ -354,6 +357,8 @@ class Shf(_FlagConstant): + prefix = 'SHF_' + class ShfALPHA(Shf): + """Supplemental SHF_* constants for EM_ALPHA.""" ++class ShfSW_64(Shf): ++ """Supplemental SHF_* constants for EM_SW_64.""" + class ShfARM(Shf): + """Supplemental SHF_* constants for EM_ARM.""" + class ShfIA_64(Shf): +@@ -363,6 +368,7 @@ class ShfMIPS(Shf): + class ShfPARISC(Shf): + """Supplemental SHF_* constants for EM_PARISC.""" + _register_elf_h(ShfALPHA, prefix='SHF_ALPHA_', parent=Shf) ++_register_elf_h(ShfSW_64, prefix='SHF_SW_64_', parent=Shf) + _register_elf_h(ShfARM, prefix='SHF_ARM_', parent=Shf) + _register_elf_h(ShfIA_64, prefix='SHF_IA_64_', parent=Shf) + _register_elf_h(ShfMIPS, prefix='SHF_MIPS_', parent=Shf) +@@ -425,6 +431,8 @@ class DtAARCH64(Dt): + """Supplemental DT_* constants for EM_AARCH64.""" + class DtALPHA(Dt): + """Supplemental DT_* constants for EM_ALPHA.""" ++class DtSW_64(Dt): ++ """Supplemental DT_* constants for EM_SW_64.""" + class DtALTERA_NIOS2(Dt): + """Supplemental DT_* constants for EM_ALTERA_NIOS2.""" + class DtIA_64(Dt): +@@ -446,6 +454,7 @@ DT_VALRNGLO DT_VALRNGHI DT_VALNUM + DT_VERSIONTAGNUM DT_EXTRANUM + DT_AARCH64_NUM + DT_ALPHA_NUM ++DT_SW_64_NUM + DT_IA_64_NUM + DT_MIPS_NUM + DT_PPC_NUM +@@ -454,6 +463,7 @@ DT_SPARC_NUM + '''.strip().split() + _register_elf_h(DtAARCH64, prefix='DT_AARCH64_', skip=_dt_skip, parent=Dt) + _register_elf_h(DtALPHA, prefix='DT_ALPHA_', skip=_dt_skip, parent=Dt) ++_register_elf_h(DtSW_64, prefix='DT_SW_64_', skip=_dt_skip, parent=Dt) + _register_elf_h(DtALTERA_NIOS2, prefix='DT_NIOS2_', skip=_dt_skip, parent=Dt) + _register_elf_h(DtIA_64, prefix='DT_IA_64_', skip=_dt_skip, parent=Dt) + _register_elf_h(DtMIPS, prefix='DT_MIPS_', skip=_dt_skip, parent=Dt) +-- +2.25.1 + diff --git a/0003-Sw64-ABI-Implementation.patch b/0003-Sw64-ABI-Implementation.patch new file mode 100644 index 0000000..59ebb75 --- /dev/null +++ b/0003-Sw64-ABI-Implementation.patch @@ -0,0 +1,2732 @@ +From 42be1f29f1f08ca9a38bbc0fe3b4bf75c3b43eed Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Fri, 29 Nov 2024 13:52:33 +0800 +Subject: [PATCH 03/23] Sw64: ABI Implementation + +--- + sysdeps/sw_64/__longjmp.S | 64 +++ + sysdeps/sw_64/_mcount.S | 105 ++++ + sysdeps/sw_64/bits/endianness.h | 11 + + sysdeps/sw_64/bits/link.h | 64 +++ + sysdeps/sw_64/bits/setjmp.h | 61 ++ + sysdeps/sw_64/bsd-_setjmp.S | 1 + + sysdeps/sw_64/bsd-setjmp.S | 1 + + sysdeps/sw_64/crti.S | 101 ++++ + sysdeps/sw_64/crtn.S | 49 ++ + sysdeps/sw_64/dl-dtprocnum.h | 3 + + sysdeps/sw_64/dl-machine.h | 463 +++++++++++++++ + sysdeps/sw_64/dl-procinfo.c | 63 ++ + sysdeps/sw_64/dl-procinfo.h | 58 ++ + sysdeps/sw_64/dl-sysdep.h | 23 + + sysdeps/sw_64/dl-trampoline.S | 540 ++++++++++++++++++ + sysdeps/sw_64/ffs.S | 91 +++ + sysdeps/sw_64/ffsll.S | 1 + + sysdeps/sw_64/jmpbuf-offsets.h | 35 ++ + sysdeps/sw_64/jmpbuf-unwind.h | 45 ++ + sysdeps/sw_64/ldsodefs.h | 40 ++ + sysdeps/sw_64/machine-gmon.h | 24 + + sysdeps/sw_64/nptl/pthread-offsets.h | 3 + + sysdeps/sw_64/nptl/pthreaddef.h | 31 + + sysdeps/sw_64/setjmp.S | 121 ++++ + sysdeps/sw_64/sotruss-lib.c | 48 ++ + sysdeps/sw_64/start.S | 103 ++++ + sysdeps/sw_64/sw8a/nptl/pthread-offsets.h | 3 + + sysdeps/sw_64/sw8a/nptl/pthreaddef.h | 31 + + sysdeps/sw_64/sw8a/nptl/tcb-offsets.sym | 13 + + sysdeps/sw_64/tls-macros.h | 36 ++ + sysdeps/sw_64/tst-audit.h | 24 + + sysdeps/sw_64/tst-file-align.h | 20 + + sysdeps/sw_64/unwind-arch.h | 28 + + .../unix/sysv/linux/sw_64/____longjmp_chk.S | 145 +++++ + 34 files changed, 2449 insertions(+) + create mode 100644 sysdeps/sw_64/__longjmp.S + create mode 100644 sysdeps/sw_64/_mcount.S + create mode 100644 sysdeps/sw_64/bits/endianness.h + create mode 100644 sysdeps/sw_64/bits/link.h + create mode 100644 sysdeps/sw_64/bits/setjmp.h + create mode 100644 sysdeps/sw_64/bsd-_setjmp.S + create mode 100644 sysdeps/sw_64/bsd-setjmp.S + create mode 100644 sysdeps/sw_64/crti.S + create mode 100644 sysdeps/sw_64/crtn.S + create mode 100644 sysdeps/sw_64/dl-dtprocnum.h + create mode 100644 sysdeps/sw_64/dl-machine.h + create mode 100644 sysdeps/sw_64/dl-procinfo.c + create mode 100644 sysdeps/sw_64/dl-procinfo.h + create mode 100644 sysdeps/sw_64/dl-sysdep.h + create mode 100644 sysdeps/sw_64/dl-trampoline.S + create mode 100644 sysdeps/sw_64/ffs.S + create mode 100644 sysdeps/sw_64/ffsll.S + create mode 100644 sysdeps/sw_64/jmpbuf-offsets.h + create mode 100644 sysdeps/sw_64/jmpbuf-unwind.h + create mode 100644 sysdeps/sw_64/ldsodefs.h + create mode 100644 sysdeps/sw_64/machine-gmon.h + create mode 100644 sysdeps/sw_64/nptl/pthread-offsets.h + create mode 100644 sysdeps/sw_64/nptl/pthreaddef.h + create mode 100644 sysdeps/sw_64/setjmp.S + create mode 100644 sysdeps/sw_64/sotruss-lib.c + create mode 100644 sysdeps/sw_64/start.S + create mode 100644 sysdeps/sw_64/sw8a/nptl/pthread-offsets.h + create mode 100644 sysdeps/sw_64/sw8a/nptl/pthreaddef.h + create mode 100644 sysdeps/sw_64/sw8a/nptl/tcb-offsets.sym + create mode 100644 sysdeps/sw_64/tls-macros.h + create mode 100644 sysdeps/sw_64/tst-audit.h + create mode 100644 sysdeps/sw_64/tst-file-align.h + create mode 100644 sysdeps/sw_64/unwind-arch.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/____longjmp_chk.S + +diff --git a/sysdeps/sw_64/__longjmp.S b/sysdeps/sw_64/__longjmp.S +new file mode 100644 +index 00000000..1321350e +--- /dev/null ++++ b/sysdeps/sw_64/__longjmp.S +@@ -0,0 +1,64 @@ ++/* Copyright (C) 1992-2023 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 ++ . */ ++ ++#define __ASSEMBLY__ ++ ++#include ++#include ++#include ++ ++ ++ENTRY(__longjmp) ++#ifdef PROF ++ ldgp gp, 0(pv) ++ .set noat ++ ldi AT, _mcount ++ call AT, (AT), _mcount ++ .set at ++ .prologue 1 ++#else ++ .prologue 0 ++#endif ++ ++ mov a1, v0 ++ ldl s0, JB_S0*8(a0) ++ ldl s1, JB_S1*8(a0) ++ ldl s2, JB_S2*8(a0) ++ ldl s3, JB_S3*8(a0) ++ ldl s4, JB_S4*8(a0) ++ ldl s5, JB_S5*8(a0) ++ ldl ra, JB_PC*8(a0) ++ ldl fp, JB_FP*8(a0) ++ ldl t0, JB_SP*8(a0) ++ fldd $f2, JB_F2*8(a0) ++ fldd $f3, JB_F3*8(a0) ++ fldd $f4, JB_F4*8(a0) ++ fldd $f5, JB_F5*8(a0) ++ fldd $f6, JB_F6*8(a0) ++ fldd $f7, JB_F7*8(a0) ++ fldd $f8, JB_F8*8(a0) ++ fldd $f9, JB_F9*8(a0) ++#ifdef PTR_DEMANGLE ++ PTR_DEMANGLE(ra, t1) ++ PTR_DEMANGLE2(t0, t1) ++ PTR_DEMANGLE2(fp, t1) ++#endif ++ seleq v0, 1, v0, v0 ++ mov t0, sp ++ ret ++ ++END(__longjmp) +diff --git a/sysdeps/sw_64/_mcount.S b/sysdeps/sw_64/_mcount.S +new file mode 100644 +index 00000000..44871413 +--- /dev/null ++++ b/sysdeps/sw_64/_mcount.S +@@ -0,0 +1,105 @@ ++/* Machine-specific calling sequence for `mcount' profiling function. sw_64 ++ Copyright (C) 1995-2023 Free Software Foundation, Inc. ++ Contributed by David Mosberger (davidm@cs.arizona.edu). ++ 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 ++ . */ ++ ++/* Assembly stub to invoke _mcount(). Compiler generated code calls ++ this stub after executing a function's prologue and without saving any ++ registers. It is therefore necessary to preserve a0..a5 as they may ++ contain function arguments. To work correctly with frame- less ++ functions, it is also necessary to preserve ra. Finally, division ++ routines are invoked with a special calling convention and the ++ compiler treats those calls as if they were instructions. In ++ particular, it doesn't save any of the temporary registers (caller ++ saved registers). It is therefore necessary to preserve all ++ caller-saved registers as well. ++ ++ Upon entering _mcount, register $at hoflds the return address and ra ++ hoflds the return address of the function's caller (selfpc and frompc, ++ respectively in gmon.c language...). */ ++ ++#include ++ ++ .set noat ++ .set noreorder ++ ++LEAF(_mcount, 0xb0) ++ subl sp, 0xb0, sp ++ .prologue 0 ++ stl a0, 0x00(sp) ++ mov ra, a0 # a0 = caller-pc ++ stl a1, 0x08(sp) ++ mov $at, a1 # a1 = self-pc ++ stl $at, 0x10(sp) ++ ++ stl a2, 0x18(sp) ++ stl a3, 0x20(sp) ++ stl a4, 0x28(sp) ++ stl a5, 0x30(sp) ++ stl ra, 0x38(sp) ++ stl gp, 0x40(sp) ++ ++ br gp, 1f ++1: ldgp gp, 0(gp) ++ ++ stl t0, 0x48(sp) ++ stl t1, 0x50(sp) ++ stl t2, 0x58(sp) ++ stl t3, 0x60(sp) ++ stl t4, 0x68(sp) ++ stl t5, 0x70(sp) ++ stl t6, 0x78(sp) ++ ++ stl t7, 0x80(sp) ++ stl t8, 0x88(sp) ++ stl t9, 0x90(sp) ++ stl t10, 0x98(sp) ++ stl t11, 0xa0(sp) ++ stl v0, 0xa8(sp) ++ ++ call ra, __mcount ++ ++ ldl a0, 0x00(sp) ++ ldl a1, 0x08(sp) ++ ldl $at, 0x10(sp) # restore self-pc ++ ldl a2, 0x18(sp) ++ ldl a3, 0x20(sp) ++ ldl a4, 0x28(sp) ++ ldl a5, 0x30(sp) ++ ldl ra, 0x38(sp) ++ ldl gp, 0x40(sp) ++ mov $at, pv # make pv point to return address ++ ldl t0, 0x48(sp) # this is important under OSF/1 to ++ ldl t1, 0x50(sp) # ensure that the code that we return ++ ldl t2, 0x58(sp) # can correctly compute its gp ++ ldl t3, 0x60(sp) ++ ldl t4, 0x68(sp) ++ ldl t5, 0x70(sp) ++ ldl t6, 0x78(sp) ++ ldl t7, 0x80(sp) ++ ldl t8, 0x88(sp) ++ ldl t9, 0x90(sp) ++ ldl t10, 0x98(sp) ++ ldl t11, 0xa0(sp) ++ ldl v0, 0xa8(sp) ++ ++ addl sp, 0xb0, sp ++ ret zero,($at),1 ++ ++ END(_mcount) ++ ++weak_alias (_mcount, mcount) +diff --git a/sysdeps/sw_64/bits/endianness.h b/sysdeps/sw_64/bits/endianness.h +new file mode 100644 +index 00000000..2c226169 +--- /dev/null ++++ b/sysdeps/sw_64/bits/endianness.h +@@ -0,0 +1,11 @@ ++#ifndef _BITS_ENDIANNESS_H ++#define _BITS_ENDIANNESS_H 1 ++ ++#ifndef _BITS_ENDIAN_H ++# error "Never use directly; include instead." ++#endif ++ ++/* Sw_64 is little-endian. */ ++#define __BYTE_ORDER __LITTLE_ENDIAN ++ ++#endif /* bits/endianness.h */ +diff --git a/sysdeps/sw_64/bits/link.h b/sysdeps/sw_64/bits/link.h +new file mode 100644 +index 00000000..312d8550 +--- /dev/null ++++ b/sysdeps/sw_64/bits/link.h +@@ -0,0 +1,64 @@ ++/* Copyright (C) 2005-2023 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 _LINK_H ++# error "Never include directly; use instead." ++#endif ++ ++/* Registers for entry into PLT on Sw_64. */ ++typedef struct La_sw_64_regs ++{ ++ uint64_t lr_r26; ++ uint64_t lr_sp; ++ uint64_t lr_r16; ++ uint64_t lr_r17; ++ uint64_t lr_r18; ++ uint64_t lr_r19; ++ uint64_t lr_r20; ++ uint64_t lr_r21; ++ double lr_f16; ++ double lr_f17; ++ double lr_f18; ++ double lr_f19; ++ double lr_f20; ++ double lr_f21; ++} La_sw_64_regs; ++ ++/* Return values for calls from PLT on Sw_64. */ ++typedef struct La_sw_64_retval ++{ ++ uint64_t lrv_r0; ++ uint64_t lrv_r1; ++ double lrv_f0; ++ double lrv_f1; ++} La_sw_64_retval; ++ ++__BEGIN_DECLS ++ ++extern Elf64_Addr ++la_sw_64_gnu_pltenter (Elf64_Sym *__sym, unsigned int __ndx, ++ uintptr_t *__refcook, uintptr_t *__defcook, ++ La_sw_64_regs *__regs, unsigned int *__flags, ++ const char *__symname, long int *__framesizep); ++extern unsigned int la_sw_64_gnu_pltexit (Elf64_Sym *__sym, unsigned int __ndx, ++ uintptr_t *__refcook, ++ uintptr_t *__defcook, ++ const La_sw_64_regs *__inregs, ++ La_sw_64_retval *__outregs, ++ const char *symname); ++ ++__END_DECLS +diff --git a/sysdeps/sw_64/bits/setjmp.h b/sysdeps/sw_64/bits/setjmp.h +new file mode 100644 +index 00000000..f8488a2f +--- /dev/null ++++ b/sysdeps/sw_64/bits/setjmp.h +@@ -0,0 +1,61 @@ ++/* Define the machine-dependent type `jmp_buf'. Sw_64 version. ++ Copyright (C) 1992-2023 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_SETJMP_H ++#define _BITS_SETJMP_H 1 ++ ++#if !defined _SETJMP_H && !defined _PTHREAD_H ++# error "Never include directly; use instead." ++#endif ++ ++/* The previous bits/setjmp.h had __jmp_buf defined as a structure. ++ We use an array of 'long int' instead, to make writing the ++ assembler easier. Naturally, user code should not depend on ++ either representation. */ ++ ++/* ++ * Integer registers: ++ * $0 is the return value (va); ++ * $1-$8, $22-$25, $28 are call-used (t0-t7, t8-t11, at); ++ * $9-$14 we save here (s0-s5); ++ * $15 is the FP and we save it here (fp or s6); ++ * $16-$21 are input arguments (call-used) (a0-a5); ++ * $26 is the return PC and we save it here (ra); ++ * $27 is the procedure value (i.e., the address of __setjmp) (pv or t12); ++ * $29 is the global pointer, which the caller will reconstruct ++ * from the return address restored in $26 (gp); ++ * $30 is the stack pointer and we save it here (sp); ++ * $31 is always zero (zero). ++ * ++ * Floating-point registers: ++ * $f0 is the floating return value; ++ * $f1, $f10-$f15, $f22-$f30 are call-used; ++ * $f2-$f9 we save here; ++ * $f16-$21 are input args (call-used); ++ * $f31 is always zero. ++ * ++ * Note that even on Sw_64 hardware that does not have an FPU (there ++ * isn't such a thing currently) it is required to implement the FP ++ * registers. ++ */ ++ ++#ifndef __ASSEMBLY__ ++typedef long int __jmp_buf[17]; ++#endif ++ ++#endif /* bits/setjmp.h */ +diff --git a/sysdeps/sw_64/bsd-_setjmp.S b/sysdeps/sw_64/bsd-_setjmp.S +new file mode 100644 +index 00000000..4e6a2da5 +--- /dev/null ++++ b/sysdeps/sw_64/bsd-_setjmp.S +@@ -0,0 +1 @@ ++/* _setjmp is in setjmp.S */ +diff --git a/sysdeps/sw_64/bsd-setjmp.S b/sysdeps/sw_64/bsd-setjmp.S +new file mode 100644 +index 00000000..1da848d2 +--- /dev/null ++++ b/sysdeps/sw_64/bsd-setjmp.S +@@ -0,0 +1 @@ ++/* setjmp is in setjmp.S */ +diff --git a/sysdeps/sw_64/crti.S b/sysdeps/sw_64/crti.S +new file mode 100644 +index 00000000..29cf51ec +--- /dev/null ++++ b/sysdeps/sw_64/crti.S +@@ -0,0 +1,101 @@ ++/* Special .init and .fini section support for Sw_64. ++ Copyright (C) 2001-2023 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. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file with other ++ programs, and to distribute those programs without any restriction ++ coming from the use of this file. (The GNU Lesser General Public ++ License restrictions do apply in other respects; for example, they ++ cover modification of the file, and distribution when not linked ++ into another program.) ++ ++ Note that people who make modified versions of this file are not ++ obligated to grant this special exception for their modified ++ versions; it is their choice whether to do so. The GNU Lesser ++ General Public License gives permission to release a modified ++ version without this exception; this exception also makes it ++ possible to release a modified version which carries forward this ++ exception. ++ ++ 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 ++ . */ ++ ++/* crti.S puts a function prologue at the beginning of the .init and ++ .fini sections and defines global symbols for those addresses, so ++ they can be called as functions. The symbols _init and _fini are ++ magic and cause the linker to emit DT_INIT and DT_FINI. ++ ++ This differs from what would be generated for ordinary code in that ++ we save and restore the GP within the function. In order for linker ++ relaxation to work, the value in the GP register on exit from a function ++ must be valid for the function entry point. Normally, a function is ++ contained within one object file and this is not an issue, provided ++ that the function reloads the gp after making any function calls. ++ However, _init and _fini are constructed from pieces of many object ++ files, all of which may have different GP values. So we must reload ++ the GP value from crti.o in crtn.o. */ ++ ++#include ++#include ++ ++#ifndef PREINIT_FUNCTION ++# define PREINIT_FUNCTION __gmon_start__ ++#endif ++ ++#ifndef PREINIT_FUNCTION_WEAK ++# define PREINIT_FUNCTION_WEAK 1 ++#endif ++ ++#if PREINIT_FUNCTION_WEAK ++ weak_extern (PREINIT_FUNCTION) ++#else ++ .hidden PREINIT_FUNCTION ++#endif ++ ++ .section .init, "ax", @progbits ++ .globl _init ++ .hidden _init ++ .type _init, @function ++ .usepv _init, std ++_init: ++ ldgp $29, 0($27) ++ subl $30, 16, $30 ++#if PREINIT_FUNCTION_WEAK ++ ldi $27, PREINIT_FUNCTION ++#endif ++ stl $26, 0($30) ++ stl $29, 8($30) ++#if PREINIT_FUNCTION_WEAK ++ beq $27, 1f ++ call $26, ($27), PREINIT_FUNCTION ++ ldl $29, 8($30) ++1: ++#else ++ bsr $26, PREINIT_FUNCTION !samegp ++#endif ++ .p2align 3 ++ ++ .section .fini, "ax", @progbits ++ .globl _fini ++ .hidden _fini ++ .type _fini,@function ++ .usepv _fini,std ++_fini: ++ ldgp $29, 0($27) ++ subl $30, 16, $30 ++ stl $26, 0($30) ++ stl $29, 8($30) ++ .p2align 3 +diff --git a/sysdeps/sw_64/crtn.S b/sysdeps/sw_64/crtn.S +new file mode 100644 +index 00000000..4de241a9 +--- /dev/null ++++ b/sysdeps/sw_64/crtn.S +@@ -0,0 +1,49 @@ ++/* Special .init and .fini section support for Sw_64. ++ Copyright (C) 2001-2023 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. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file with other ++ programs, and to distribute those programs without any restriction ++ coming from the use of this file. (The GNU Lesser General Public ++ License restrictions do apply in other respects; for example, they ++ cover modification of the file, and distribution when not linked ++ into another program.) ++ ++ Note that people who make modified versions of this file are not ++ obligated to grant this special exception for their modified ++ versions; it is their choice whether to do so. The GNU Lesser ++ General Public License gives permission to release a modified ++ version without this exception; this exception also makes it ++ possible to release a modified version which carries forward this ++ exception. ++ ++ 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 ++ . */ ++ ++/* crtn.S puts function epilogues in the .init and .fini sections ++ corresponding to the prologues in crti.S. */ ++ ++ .section .init, "ax", @progbits ++ ldl $26, 0($30) ++ ldl $29, 8($30) ++ addl $30, 16, $30 ++ ret ++ ++ .section .fini, "ax", @progbits ++ ldl $26, 0($30) ++ ldl $29, 8($30) ++ addl $30, 16, $30 ++ ret +diff --git a/sysdeps/sw_64/dl-dtprocnum.h b/sysdeps/sw_64/dl-dtprocnum.h +new file mode 100644 +index 00000000..05777c06 +--- /dev/null ++++ b/sysdeps/sw_64/dl-dtprocnum.h +@@ -0,0 +1,3 @@ ++/* Number of extra dynamic section entries for this architecture. By ++ default there are none. */ ++#define DT_THISPROCNUM DT_SW_64_NUM +diff --git a/sysdeps/sw_64/dl-machine.h b/sysdeps/sw_64/dl-machine.h +new file mode 100644 +index 00000000..54822f12 +--- /dev/null ++++ b/sysdeps/sw_64/dl-machine.h +@@ -0,0 +1,463 @@ ++/* Machine-dependent ELF dynamic relocation inline functions. Sw_64 version. ++ Copyright (C) 1996-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson . ++ ++ 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 ++ . */ ++ ++/* This was written in the absence of an ABI -- don't expect ++ it to remain unchanged. */ ++ ++#ifndef dl_machine_h ++#define dl_machine_h 1 ++ ++#define ELF_MACHINE_NAME "sw_64" ++ ++#include ++#include ++#include ++ ++/* Mask identifying addresses reserved for the user program, ++ where the dynamic linker should not map anything. */ ++#define ELF_MACHINE_USER_ADDRESS_MASK 0x120000000UL ++ ++/* Translate a processor specific dynamic tag to the index in l_info array. */ ++#define DT_SW_64(x) (DT_SW_64_##x - DT_LOPROC + DT_NUM) ++ ++/* Return nonzero iff ELF header is compatible with the running host. */ ++static inline int ++elf_machine_matches_host (const Elf64_Ehdr *ehdr) ++{ ++ return ehdr->e_machine == EM_SW_64; ++} ++ ++/* Return the link-time address of _DYNAMIC. The multiple-got-capable ++ linker no longer allocates the first .got entry for this. But not to ++ worry, no special tricks are needed. */ ++static inline Elf64_Addr ++elf_machine_dynamic (void) ++{ ++#ifndef NO_AXP_MULTI_GOT_LD ++ return (Elf64_Addr) &_DYNAMIC; ++#else ++ register Elf64_Addr *gp __asm__ ("$29"); ++ return gp[-4096]; ++#endif ++} ++ ++/* Return the run-time load address of the shared object. */ ++ ++static inline Elf64_Addr ++elf_machine_load_address (void) ++{ ++ /* This relies on the compiler using gp-relative addresses for static ++ * symbols. */ ++ static void *dot = ˙ ++ return (void *) &dot - dot; ++} ++ ++/* Set up the loaded object described by L so its unrelocated PLT ++ entries will jump to the on-demand fixup code in dl-runtime.c. */ ++ ++static inline int ++elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[], ++ int lazy, int profile) ++{ ++ extern char _dl_runtime_resolve_new[] attribute_hidden; ++ extern char _dl_runtime_profile_new[] attribute_hidden; ++ extern char _dl_runtime_resolve_old[] attribute_hidden; ++ extern char _dl_runtime_profile_old[] attribute_hidden; ++ ++ struct pltgot ++ { ++ char *resolve; ++ struct link_map *link; ++ }; ++ ++ struct pltgot *pg; ++ long secureplt; ++ char *resolve; ++ ++ if (map->l_info[DT_JMPREL] == 0 || !lazy) ++ return lazy; ++ ++ /* Check to see if we're using the read-only plt form. */ ++ secureplt = map->l_info[DT_SW_64 (PLTRO)] != 0; ++ ++ /* If the binary uses the read-only secure plt format, PG points to ++ the .got.plt section, which is the right place for ld.so to place ++ its hooks. Otherwise, PG is currently pointing at the start of ++ the plt; the hooks go at offset 16. */ ++ pg = (struct pltgot *) D_PTR (map, l_info[DT_PLTGOT]); ++ pg += !secureplt; ++ ++ /* This function will be called to perform the relocation. They're ++ not declared as functions to convince the compiler to use gp ++ relative relocations for them. */ ++ if (secureplt) ++ resolve = _dl_runtime_resolve_new; ++ else ++ resolve = _dl_runtime_resolve_old; ++ ++ if (__builtin_expect (profile, 0)) ++ { ++ if (secureplt) ++ resolve = _dl_runtime_profile_new; ++ else ++ resolve = _dl_runtime_profile_old; ++ ++ if (GLRO (dl_profile) && _dl_name_match_p (GLRO (dl_profile), map)) ++ { ++ /* This is the object we are looking for. Say that we really ++ want profiling and the timers are started. */ ++ GL (dl_profile_map) = map; ++ } ++ } ++ ++ pg->resolve = resolve; ++ pg->link = map; ++ ++ return lazy; ++} ++ ++/* Initial entry point code for the dynamic linker. ++ The C function `_dl_start' is the real entry point; ++ its return value is the user program's entry point. */ ++ ++#define RTLD_START \ ++ asm("\ ++ .section .text \n\ ++ .set at \n\ ++ .globl _start \n\ ++ .ent _start \n\ ++_start: \n\ ++ .frame $31,0,$31,0 \n\ ++ br $gp, 0f \n\ ++0: ldgp $gp, 0($gp) \n\ ++ .prologue 0 \n\ ++ /* Pass pointer to argument block to _dl_start. */ \n\ ++ mov $sp, $16 \n\ ++ bsr $26, _dl_start !samegp \n\ ++ .end _start \n\ ++ /* FALLTHRU */ \n\ ++ .globl _dl_start_user \n\ ++ .ent _dl_start_user \n\ ++_dl_start_user: \n\ ++ .frame $31,0,$31,0 \n\ ++ .prologue 0 \n\ ++ /* Save the user entry point address in s0. */ \n\ ++ mov $0, $9 \n\ ++ /* The special initializer gets called with the stack \n\ ++ just as the application's entry point will see it; \n\ ++ it can switch stacks if it moves these contents \n\ ++ over. */ \n\ ++" RTLD_START_SPECIAL_INIT " \n\ ++ /* Call _dl_init(_dl_loaded, argc, argv, envp) to run \n\ ++ initializers. */ \n\ ++ ldih $16, _rtld_local($gp) !gprelhigh \n\ ++ ldl $16, _rtld_local($16) !gprellow \n\ ++ ldl $17, 0($sp) \n\ ++ ldi $18, 8($sp) \n\ ++ s8addl $17, 8, $19 \n\ ++ addl $19, $18, $19 \n\ ++ bsr $26, _dl_init !samegp \n\ ++ /* Pass our finalizer function to the user in $0. */ \n\ ++ ldih $0, _dl_fini($gp) !gprelhigh \n\ ++ ldi $0, _dl_fini($0) !gprellow \n\ ++ /* Jump to the user's entry point. */ \n\ ++ mov $9, $27 \n\ ++ jmp ($9) \n\ ++ .end _dl_start_user \n\ ++ .set noat \n\ ++.previous"); ++ ++#ifndef RTLD_START_SPECIAL_INIT ++# define RTLD_START_SPECIAL_INIT /* nothing */ ++#endif ++ ++/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry ++ or TLS variables, so undefined references should not be allowed ++ to define the value. ++ ++ ELF_RTYPE_CLASS_COPY iff TYPE should not be allowed to resolve ++ to one of the main executable's symbols, as for a COPY reloc. ++ This is unused on Sw_64. */ ++ ++#define elf_machine_type_class(type) \ ++ (((type) == R_SW_64_JMP_SLOT || (type) == R_SW_64_DTPMOD64 \ ++ || (type) == R_SW_64_DTPREL64 || (type) == R_SW_64_TPREL64) \ ++ * ELF_RTYPE_CLASS_PLT) ++ ++/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ ++#define ELF_MACHINE_JMP_SLOT R_SW_64_JMP_SLOT ++ ++/* The sw_64 never uses Elf64_Rel relocations. */ ++/*#define ELF_MACHINE_NO_REL 1 ++#define ELF_MACHINE_NO_RELA 0 ++*/ ++/* We define an initialization functions. This is called very early in ++ * _dl_sysdep_start. */ ++#define DL_PLATFORM_INIT dl_platform_init () ++ ++static inline void __attribute__ ((unused)) dl_platform_init (void) ++{ ++ if (GLRO (dl_platform) != NULL && *GLRO (dl_platform) == '\0') ++ /* Avoid an empty string which would disturb us. */ ++ GLRO (dl_platform) = NULL; ++} ++ ++/* Fix up the instructions of a PLT entry to invoke the function ++ rather than the dynamic linker. */ ++static inline Elf64_Addr ++elf_machine_fixup_plt (struct link_map *map, lookup_t t, ++ const ElfW (Sym) * refsym, const ElfW (Sym) * sym, ++ const Elf64_Rela *reloc, Elf64_Addr *got_addr, ++ Elf64_Addr value) ++{ ++ const Elf64_Rela *rela_plt; ++ Elf64_Word *plte; ++ long int edisp; ++ ++ /* Store the value we are going to load. */ ++ *got_addr = value; ++ ++ /* If this binary uses the read-only secure plt format, we're done. */ ++ if (map->l_info[DT_SW_64 (PLTRO)]) ++ return value; ++ ++ /* Otherwise we have to modify the plt entry in place to do the branch. */ ++ ++ /* Recover the PLT entry address by calculating reloc's index into the ++ .rela.plt, and finding that entry in the .plt. */ ++ rela_plt = (const Elf64_Rela *) D_PTR (map, l_info[DT_JMPREL]); ++ plte = (Elf64_Word *) (D_PTR (map, l_info[DT_PLTGOT]) + 32); ++ plte += 3 * (reloc - rela_plt); ++ ++ /* Find the displacement from the plt entry to the function. */ ++ edisp = (long int) (value - (Elf64_Addr) &plte[3]) / 4; ++ ++ if (edisp >= -0x100000 && edisp < 0x100000) ++ { ++ /* If we are in range, use br to perfect branch prediction and ++ elide the dependency on the address load. This case happens, ++ e.g., when a shared library call is resolved to the same library. */ ++ ++ int hi, lo; ++ hi = value - (Elf64_Addr) &plte[0]; ++ lo = (short int) hi; ++ hi = (hi - lo) >> 16; ++ ++ /* Emit "lda $27,lo($27)" */ ++ plte[1] = 0xfb7b0000 | (lo & 0xffff); ++ ++ /* Emit "br $31,function" */ ++ plte[2] = 0x13e00000 | (edisp & 0x1fffff); ++ ++ /* Think about thread-safety -- the previous instructions must be ++ committed to memory before the first is overwritten. */ ++ __asm__ __volatile__("memb" : : : "memory"); ++ ++ /* Emit "ldah $27,hi($27)" */ ++ plte[0] = 0xff7b0000 | (hi & 0xffff); ++ } ++ else ++ { ++ /* Don't bother with the hint since we already know the hint is ++ wrong. Eliding it prevents the wrong page from getting pulled ++ into the cache. */ ++ ++ int hi, lo; ++ hi = (Elf64_Addr) got_addr - (Elf64_Addr) &plte[0]; ++ lo = (short) hi; ++ hi = (hi - lo) >> 16; ++ ++ /* Emit "ldq $27,lo($27)" */ ++ plte[1] = 0x8f7b0000 | (lo & 0xffff); ++ ++ /* Emit "jmp $31,($27)" */ ++ plte[2] = 0x0ffb0000; ++ /* Think about thread-safety -- the previous instructions must be ++ committed to memory before the first is overwritten. */ ++ __asm__ __volatile__("memb" : : : "memory"); ++ ++ /* Emit "ldah $27,hi($27)" */ ++ plte[0] = 0xff7b0000 | (hi & 0xffff); ++ } ++ ++ /* At this point, if we've been doing runtime resolution, Icache is dirty. ++ This will be taken care of in _dl_runtime_resolve. If instead we are ++ doing this as part of non-lazy startup relocation, that bit of code ++ hasn't made it into Icache yet, so there's nothing to clean up. */ ++ ++ return value; ++} ++ ++/* Return the final value of a plt relocation. */ ++static inline Elf64_Addr ++elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, ++ Elf64_Addr value) ++{ ++ return value + reloc->r_addend; ++} ++ ++/* Names of the architecture-specific auditing callback functions. */ ++#define ARCH_LA_PLTENTER sw_64_gnu_pltenter ++#define ARCH_LA_PLTEXIT sw_64_gnu_pltexit ++ ++#endif /* !dl_machine_h */ ++ ++#ifdef RESOLVE_MAP ++ ++/* Perform the relocation specified by RELOC and SYM (which is fully resolved). ++ MAP is the object containing the reloc. */ ++static inline void __attribute__ ((always_inline)) ++elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], ++ const Elf64_Rela *reloc, const Elf64_Sym *sym, ++ const struct r_found_version *version, ++ void *const reloc_addr_arg, int skip_ifunc) ++{ ++ Elf64_Addr *const reloc_addr = reloc_addr_arg; ++ unsigned long int const r_type = ELF64_R_TYPE (reloc->r_info); ++ ++ /* We cannot use a switch here because we cannot locate the switch ++ jump table until we've self-relocated. */ ++ ++#if !defined RTLD_BOOTSTRAP ++ if (__builtin_expect (r_type == R_SW_64_RELATIVE, 0)) ++ { ++ //# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC ++ // /* Already done in dynamic linker. */ ++ Elf64_Addr reloc_addr_val; ++ // if (map != &GL(dl_rtld_map)) ++ //# endif ++ // { ++ /* XXX Make some timings. Maybe it's preferable to test for ++ unaligned access and only do it the complex way if necessary. */ ++ ++ /* Load value without causing unaligned trap. */ ++ memcpy (&reloc_addr_val, reloc_addr_arg, 8); ++ reloc_addr_val += map->l_addr; ++ ++ /* Store value without causing unaligned trap. */ ++ memcpy (reloc_addr_arg, &reloc_addr_val, 8); ++ // } ++ } ++ else ++#endif ++ if (__builtin_expect (r_type == R_SW_64_NONE, 0)) ++ return; ++ else ++ { ++ struct link_map *sym_map ++ = RESOLVE_MAP (map, scope, &sym, version, r_type); ++ Elf64_Addr sym_value; ++ Elf64_Addr sym_raw_value; ++ ++ sym_raw_value = sym_value = reloc->r_addend; ++ if (sym_map) ++ { ++ sym_raw_value += sym->st_value; ++ sym_value += SYMBOL_ADDRESS (sym_map, sym, true); ++ } ++ ++ if (r_type == R_SW_64_GLOB_DAT) ++ *reloc_addr = sym_value; ++ else if (r_type == R_SW_64_JMP_SLOT) ++ elf_machine_fixup_plt (map, 0, 0, 0, reloc, reloc_addr, sym_value); ++#ifndef RTLD_BOOTSTRAP ++ else if (r_type == R_SW_64_REFQUAD) ++ { ++ /* Store value without causing unaligned trap. */ ++ memcpy (reloc_addr_arg, &sym_value, 8); ++ } ++#endif ++ else if (r_type == R_SW_64_DTPMOD64) ++ { ++#ifdef RTLD_BOOTSTRAP ++ /* During startup the dynamic linker is always index 1. */ ++ *reloc_addr = 1; ++#else ++ /* Get the information from the link map returned by the ++ resolv function. */ ++ if (sym_map != NULL) ++ *reloc_addr = sym_map->l_tls_modid; ++#endif ++ } ++ else if (r_type == R_SW_64_DTPREL64) ++ { ++#ifndef RTLD_BOOTSTRAP ++ /* During relocation all TLS symbols are defined and used. ++ Therefore the offset is already correct. */ ++ *reloc_addr = sym_raw_value; ++#endif ++ } ++ else if (r_type == R_SW_64_TPREL64) ++ { ++#ifdef RTLD_BOOTSTRAP ++ *reloc_addr = sym_raw_value + map->l_tls_offset; ++#else ++ if (sym_map) ++ { ++ CHECK_STATIC_TLS (map, sym_map); ++ *reloc_addr = sym_raw_value + sym_map->l_tls_offset; ++ } ++#endif ++ } ++ else ++ _dl_reloc_bad_type (map, r_type, 0); ++ } ++} ++ ++/* Let do-rel.h know that on Sw_64 if l_addr is 0, all RELATIVE relocs ++ can be skipped. */ ++#define ELF_MACHINE_REL_RELATIVE 1 ++ ++static inline void __attribute__ ((always_inline)) ++elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, ++ void *const reloc_addr_arg) ++{ ++ /* XXX Make some timings. Maybe it's preferable to test for ++ unaligned access and only do it the complex way if necessary. */ ++ Elf64_Addr reloc_addr_val; ++ ++ /* Load value without causing unaligned trap. */ ++ memcpy (&reloc_addr_val, reloc_addr_arg, 8); ++ reloc_addr_val += l_addr; ++ ++ /* Store value without causing unaligned trap. */ ++ memcpy (reloc_addr_arg, &reloc_addr_val, 8); ++} ++ ++static inline void __attribute__ ((always_inline)) ++elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ++ Elf64_Addr l_addr, const Elf64_Rela *reloc, ++ int skip_ifunc) ++{ ++ Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); ++ unsigned long int const r_type = ELF64_R_TYPE (reloc->r_info); ++ ++ if (r_type == R_SW_64_JMP_SLOT) ++ { ++ /* Perform a RELATIVE reloc on the .got entry that transfers ++ to the .plt. */ ++ *reloc_addr += l_addr; ++ } ++ else if (r_type == R_SW_64_NONE) ++ return; ++ else ++ _dl_reloc_bad_type (map, r_type, 1); ++} ++ ++#endif /* RESOLVE_MAP */ +diff --git a/sysdeps/sw_64/dl-procinfo.c b/sysdeps/sw_64/dl-procinfo.c +new file mode 100644 +index 00000000..253f3aba +--- /dev/null ++++ b/sysdeps/sw_64/dl-procinfo.c +@@ -0,0 +1,63 @@ ++/* Data for Sw_64 version of processor capability information. ++ Copyright (C) 2008-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Aurelien Jarno , 2008. ++ ++ 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 ++ . */ ++ ++/* This information must be kept in sync with the _DL_PLATFORM_COUNT ++ definitions in procinfo.h. ++ ++ 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 !defined PROCINFO_DECL && defined SHARED ++._dl_sw_64_platforms ++#else ++PROCINFO_CLASS const char _dl_sw_64_platforms[5][5] ++#endif ++#ifndef PROCINFO_DECL ++= { ++ "sw8a", "ev5", "sw6a", "sw6b", "sw6c" ++ } ++#endif ++#if !defined SHARED || defined PROCINFO_DECL ++; ++#else ++ , ++#endif ++ ++#undef PROCINFO_DECL ++#undef PROCINFO_CLASS +diff --git a/sysdeps/sw_64/dl-procinfo.h b/sysdeps/sw_64/dl-procinfo.h +new file mode 100644 +index 00000000..ea9df900 +--- /dev/null ++++ b/sysdeps/sw_64/dl-procinfo.h +@@ -0,0 +1,58 @@ ++/* Sw_64 version of processor capability information handling macros. ++ Copyright (C) 2008-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Aurelien Jarno , 2008. ++ ++ 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 ++ ++/* Mask to filter out platforms. */ ++#define _DL_HWCAP_PLATFORM (-1ULL) ++ ++#define _DL_PLATFORMS_COUNT 5 ++ ++static inline int __attribute__ ((unused, always_inline)) ++_dl_string_platform (const char *str) ++{ ++ int i; ++ ++ if (str != NULL) ++ for (i = 0; i < _DL_PLATFORMS_COUNT; ++i) ++ { ++ if (strcmp (str, GLRO (dl_sw_64_platforms)[i]) == 0) ++ return i; ++ } ++ return -1; ++}; ++ ++/* We cannot provide a general printing function. */ ++#define _dl_procinfo(type, word) -1 ++ ++/* There are no hardware capabilities defined. */ ++#define _dl_hwcap_string(idx) "" ++ ++/* By default there is no important hardware capability. */ ++#define HWCAP_IMPORTANT (0) ++ ++/* We don't have any hardware capabilities. */ ++#define _DL_HWCAP_COUNT 0 ++ ++#define _dl_string_hwcap(str) (-1) ++ ++#endif /* dl-procinfo.h */ +diff --git a/sysdeps/sw_64/dl-sysdep.h b/sysdeps/sw_64/dl-sysdep.h +new file mode 100644 +index 00000000..b3823567 +--- /dev/null ++++ b/sysdeps/sw_64/dl-sysdep.h +@@ -0,0 +1,23 @@ ++/* System-specific settings for dynamic linker code. Sw_64 version. ++ Copyright (C) 2002-2023 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_next ++ ++/* _dl_argv cannot be attribute_relro, because _dl_start_user ++ might write into it after _dl_start returns. */ ++#define DL_ARGV_NOT_RELRO 1 +diff --git a/sysdeps/sw_64/dl-trampoline.S b/sysdeps/sw_64/dl-trampoline.S +new file mode 100644 +index 00000000..72178557 +--- /dev/null ++++ b/sysdeps/sw_64/dl-trampoline.S +@@ -0,0 +1,540 @@ ++/* PLT trampolines. Sw_64 version. ++ Copyright (C) 2005-2023 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 ++ ++ .set noat ++ ++.macro savei regno, offset ++ stl $\regno, \offset($30) ++ cfi_rel_offset(\regno, \offset) ++.endm ++ ++.macro savef regno, offset ++ fstd $f\regno, \offset($30) ++ cfi_rel_offset(\regno+32, \offset) ++.endm ++ ++ .align 4 ++ .globl _dl_runtime_resolve_new ++ .ent _dl_runtime_resolve_new ++ ++#undef FRAMESIZE ++#define FRAMESIZE 14*8 ++ ++_dl_runtime_resolve_new: ++ .frame $30, FRAMESIZE, $26, 0 ++ .mask 0x4000000, 0 ++ ++ ldih $29, 0($27) !gpdisp!1 ++ ldi $30, -FRAMESIZE($30) ++ stl $26, 0*8($30) ++ stl $16, 2*8($30) ++ ++ stl $17, 3*8($30) ++ ldi $29, 0($29) !gpdisp!1 ++ stl $18, 4*8($30) ++ mov $28, $16 /* link_map from .got.plt */ ++ ++ stl $19, 5*8($30) ++ mov $25, $17 /* offset of reloc entry */ ++ stl $20, 6*8($30) ++ mov $26, $18 /* return address */ ++ ++ stl $21, 7*8($30) ++ fstd $f16, 8*8($30) ++ fstd $f17, 9*8($30) ++ fstd $f18, 10*8($30) ++ ++ fstd $f19, 11*8($30) ++ fstd $f20, 12*8($30) ++ fstd $f21, 13*8($30) ++ .prologue 2 ++ ++ bsr $26, _dl_fixup !samegp ++ mov $0, $27 ++ ++ ldl $26, 0*8($30) ++ ldl $16, 2*8($30) ++ ldl $17, 3*8($30) ++ ldl $18, 4*8($30) ++ ldl $19, 5*8($30) ++ ldl $20, 6*8($30) ++ ldl $21, 7*8($30) ++ fldd $f16, 8*8($30) ++ fldd $f17, 9*8($30) ++ fldd $f18, 10*8($30) ++ fldd $f19, 11*8($30) ++ fldd $f20, 12*8($30) ++ fldd $f21, 13*8($30) ++ ldi $30, FRAMESIZE($30) ++ jmp $31, ($27), 0 ++ .end _dl_runtime_resolve_new ++ ++ .globl _dl_runtime_profile_new ++ .type _dl_runtime_profile_new, @function ++ ++#undef FRAMESIZE ++#define FRAMESIZE 20*8 ++ ++ /* We save the registers in a different order than desired by ++ .mask/.fmask, so we have to use explicit cfi directives. */ ++ cfi_startproc ++ ++_dl_runtime_profile_new: ++ ldih $29, 0($27) !gpdisp!2 ++ ldi $30, -FRAMESIZE($30) ++ savei 26, 0*8 ++ stl $16, 2*8($30) ++ ++ stl $17, 3*8($30) ++ ldi $29, 0($29) !gpdisp!2 ++ stl $18, 4*8($30) ++ ldi $1, FRAMESIZE($30) /* incoming sp value */ ++ ++ stl $1, 1*8($30) ++ stl $19, 5*8($30) ++ stl $20, 6*8($30) ++ mov $28, $16 /* link_map from .got.plt */ ++ ++ stl $21, 7*8($30) ++ mov $25, $17 /* offset of reloc entry */ ++ fstd $f16, 8*8($30) ++ mov $26, $18 /* return address */ ++ ++ fstd $f17, 9*8($30) ++ mov $30, $19 /* La_sw_64_regs address */ ++ fstd $f18, 10*8($30) ++ ldi $20, 14*8($30) /* framesize address */ ++ ++ fstd $f19, 11*8($30) ++ fstd $f20, 12*8($30) ++ fstd $f21, 13*8($30) ++ stl $28, 16*8($30) ++ stl $25, 17*8($30) ++ ++ bsr $26, _dl_profile_fixup !samegp ++ mov $0, $27 ++ ++ /* Discover if we're wrapping this call. */ ++ ldl $18, 14*8($30) ++ bge $18, 1f ++ ++ ldl $26, 0*8($30) ++ ldl $16, 2*8($30) ++ ldl $17, 3*8($30) ++ ldl $18, 4*8($30) ++ ldl $19, 5*8($30) ++ ldl $20, 6*8($30) ++ ldl $21, 7*8($30) ++ fldd $f16, 8*8($30) ++ fldd $f17, 9*8($30) ++ fldd $f18, 10*8($30) ++ fldd $f19, 11*8($30) ++ fldd $f20, 12*8($30) ++ fldd $f21, 13*8($30) ++ ldi $30, FRAMESIZE($30) ++ jmp $31, ($27), 0 ++ ++1: ++ /* Create a frame pointer and allocate a new argument frame. */ ++ savei 15, 15*8 ++ mov $30, $15 ++ cfi_def_cfa_register (15) ++ addl $18, 15, $18 ++ bic $18, 15, $18 ++ subl $30, $18, $30 ++ ++ /* Save the call destination around memcpy. */ ++ stl $0, 14*8($30) ++ ++ /* Copy the stack arguments into place. */ ++ ldi $16, 0($30) ++ ldi $17, FRAMESIZE($15) ++ call $26, memcpy ++ ldgp $29, 0($26) ++ ++ /* Reload the argument registers. */ ++ ldl $27, 14*8($30) ++ ldl $16, 2*8($15) ++ ldl $17, 3*8($15) ++ ldl $18, 4*8($15) ++ ldl $19, 5*8($15) ++ ldl $20, 6*8($15) ++ ldl $21, 7*8($15) ++ fldd $f16, 8*8($15) ++ fldd $f17, 9*8($15) ++ fldd $f18, 10*8($15) ++ fldd $f19, 11*8($15) ++ fldd $f20, 12*8($15) ++ fldd $f21, 13*8($15) ++ ++ call $26, ($27), 0 ++ ldgp $29, 0($26) ++ ++ /* Set up for call to _dl_audit_pltexit. */ ++ ldl $16, 16*8($15) ++ ldl $17, 17*8($15) ++ stl $0, 16*8($15) ++ ldi $18, 0($15) ++ stl $1, 17*8($15) ++ ldi $19, 16*8($15) ++ fstd $f0, 18*8($15) ++ fstd $f1, 19*8($15) ++ bsr $26, _dl_audit_pltexit !samegp ++ ++ mov $15, $30 ++ cfi_def_cfa_register (30) ++ ldl $26, 0($30) ++ ldl $15, 15*8($30) ++ ldi $30, FRAMESIZE($30) ++ ret ++ ++ cfi_endproc ++ .size _dl_runtime_profile_new, .-_dl_runtime_profile_new ++ ++ .align 4 ++ .globl _dl_runtime_resolve_old ++ .ent _dl_runtime_resolve_old ++ ++#undef FRAMESIZE ++#define FRAMESIZE 44*8 ++ ++_dl_runtime_resolve_old: ++ ldi $30, -FRAMESIZE($30) ++ .frame $30, FRAMESIZE, $26 ++ /* Preserve all registers that C normally doesn't. */ ++ stl $26, 0*8($30) ++ stl $0, 1*8($30) ++ stl $1, 2*8($30) ++ stl $2, 3*8($30) ++ stl $3, 4*8($30) ++ stl $4, 5*8($30) ++ stl $5, 6*8($30) ++ stl $6, 7*8($30) ++ stl $7, 8*8($30) ++ stl $8, 9*8($30) ++ stl $16, 10*8($30) ++ stl $17, 11*8($30) ++ stl $18, 12*8($30) ++ stl $19, 13*8($30) ++ stl $20, 14*8($30) ++ stl $21, 15*8($30) ++ stl $22, 16*8($30) ++ stl $23, 17*8($30) ++ stl $24, 18*8($30) ++ stl $25, 19*8($30) ++ stl $29, 20*8($30) ++ fstd $f0, 21*8($30) ++ fstd $f1, 22*8($30) ++ fstd $f10, 23*8($30) ++ fstd $f11, 24*8($30) ++ fstd $f12, 25*8($30) ++ fstd $f13, 26*8($30) ++ fstd $f14, 27*8($30) ++ fstd $f15, 28*8($30) ++ fstd $f16, 29*8($30) ++ fstd $f17, 30*8($30) ++ fstd $f18, 31*8($30) ++ fstd $f19, 32*8($30) ++ fstd $f20, 33*8($30) ++ fstd $f21, 34*8($30) ++ fstd $f22, 35*8($30) ++ fstd $f23, 36*8($30) ++ fstd $f24, 37*8($30) ++ fstd $f25, 38*8($30) ++ fstd $f26, 39*8($30) ++ fstd $f27, 40*8($30) ++ fstd $f28, 41*8($30) ++ fstd $f29, 42*8($30) ++ fstd $f30, 43*8($30) ++ .mask 0x27ff01ff, -FRAMESIZE ++ .fmask 0xfffffc03, -FRAMESIZE+21*8 ++ /* Set up our GP. */ ++ br $29, .+4 ++ ldgp $29, 0($29) ++ .prologue 0 ++ /* Set up the arguments for _dl_fixup: ++ $16 = link_map out of plt0 ++ $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24 ++ $18 = return address ++ */ ++ subl $28, $27, $17 ++ ldl $16, 8($27) ++ subl $17, 20, $17 ++ mov $26, $18 ++ addl $17, $17, $17 ++ bsr $26, _dl_fixup !samegp ++ ++ /* Move the destination address into position. */ ++ mov $0, $27 ++ /* Restore program registers. */ ++ ldl $26, 0*8($30) ++ ldl $0, 1*8($30) ++ ldl $1, 2*8($30) ++ ldl $2, 3*8($30) ++ ldl $3, 4*8($30) ++ ldl $4, 5*8($30) ++ ldl $5, 6*8($30) ++ ldl $6, 7*8($30) ++ ldl $7, 8*8($30) ++ ldl $8, 9*8($30) ++ ldl $16, 10*8($30) ++ ldl $17, 11*8($30) ++ ldl $18, 12*8($30) ++ ldl $19, 13*8($30) ++ ldl $20, 14*8($30) ++ ldl $21, 15*8($30) ++ ldl $22, 16*8($30) ++ ldl $23, 17*8($30) ++ ldl $24, 18*8($30) ++ ldl $25, 19*8($30) ++ ldl $29, 20*8($30) ++ fldd $f0, 21*8($30) ++ fldd $f1, 22*8($30) ++ fldd $f10, 23*8($30) ++ fldd $f11, 24*8($30) ++ fldd $f12, 25*8($30) ++ fldd $f13, 26*8($30) ++ fldd $f14, 27*8($30) ++ fldd $f15, 28*8($30) ++ fldd $f16, 29*8($30) ++ fldd $f17, 30*8($30) ++ fldd $f18, 31*8($30) ++ fldd $f19, 32*8($30) ++ fldd $f20, 33*8($30) ++ fldd $f21, 34*8($30) ++ fldd $f22, 35*8($30) ++ fldd $f23, 36*8($30) ++ fldd $f24, 37*8($30) ++ fldd $f25, 38*8($30) ++ fldd $f26, 39*8($30) ++ fldd $f27, 40*8($30) ++ fldd $f28, 41*8($30) ++ fldd $f29, 42*8($30) ++ fldd $f30, 43*8($30) ++ /* Flush the Icache after having modified the .plt code. */ ++ imb ++ /* Clean up and turn control to the destination */ ++ ldi $30, FRAMESIZE($30) ++ jmp $31, ($27) ++ ++ .end _dl_runtime_resolve_old ++ ++ .globl _dl_runtime_profile_old ++ .usepv _dl_runtime_profile_old, no ++ .type _dl_runtime_profile_old, @function ++ ++ /* We save the registers in a different order than desired by ++ .mask/.fmask, so we have to use explicit cfi directives. */ ++ cfi_startproc ++ ++#undef FRAMESIZE ++#define FRAMESIZE 50*8 ++ ++ .align 4 ++_dl_runtime_profile_old: ++ ldi $30, -FRAMESIZE($30) ++ cfi_adjust_cfa_offset (FRAMESIZE) ++ ++ /* Preserve all argument registers. This also constructs the ++ La_sw_64_regs structure. */ ++ savei 26, 0*8 ++ savei 16, 2*8 ++ savei 17, 3*8 ++ savei 18, 4*8 ++ savei 19, 5*8 ++ savei 20, 6*8 ++ savei 21, 7*8 ++ ldi $16, FRAMESIZE($30) ++ savef 16, 8*8 ++ savef 17, 9*8 ++ savef 18, 10*8 ++ savef 19, 11*8 ++ savef 20, 12*8 ++ savef 21, 13*8 ++ stl $16, 1*8($30) ++ ++ /* Preserve all registers that C normally doesn't. */ ++ savei 0, 14*8 ++ savei 1, 15*8 ++ savei 2, 16*8 ++ savei 3, 17*8 ++ savei 4, 18*8 ++ savei 5, 19*8 ++ savei 6, 20*8 ++ savei 7, 21*8 ++ savei 8, 22*8 ++ savei 22, 23*8 ++ savei 23, 24*8 ++ savei 24, 25*8 ++ savei 25, 26*8 ++ savei 29, 27*8 ++ savef 0, 28*8 ++ savef 1, 29*8 ++ savef 10, 30*8 ++ savef 11, 31*8 ++ savef 12, 32*8 ++ savef 13, 33*8 ++ savef 14, 34*8 ++ savef 15, 35*8 ++ savef 22, 36*8 ++ savef 23, 37*8 ++ savef 24, 38*8 ++ savef 25, 39*8 ++ savef 26, 40*8 ++ savef 27, 41*8 ++ savef 28, 42*8 ++ savef 29, 43*8 ++ savef 30, 44*8 ++ ++ /* Set up our GP. */ ++ br $29, .+4 ++ ldgp $29, 0($29) ++ ++ /* Set up the arguments for _dl_profile_fixup: ++ $16 = link_map out of plt0 ++ $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24 ++ $18 = return address ++ $19 = La_sw_64_regs address ++ $20 = framesize address ++ */ ++ subl $28, $27, $17 ++ ldl $16, 8($27) ++ subl $17, 20, $17 ++ mov $26, $18 ++ addl $17, $17, $17 ++ ldi $19, 0($30) ++ ldi $20, 45*8($30) ++ stl $16, 48*8($30) ++ stl $17, 49*8($30) ++ ++ bsr $26, _dl_profile_fixup !samegp ++ ++ /* Discover if we're wrapping this call. */ ++ ldl $18, 45*8($30) ++ bge $18, 1f ++ ++ /* Move the destination address into position. */ ++ mov $0, $27 ++ /* Restore program registers. */ ++ ldl $26, 0*8($30) ++ ldl $16, 2*8($30) ++ ldl $17, 3*8($30) ++ ldl $18, 4*8($30) ++ ldl $19, 5*8($30) ++ ldl $20, 6*8($30) ++ ldl $21, 7*8($30) ++ fldd $f16, 8*8($30) ++ fldd $f17, 9*8($30) ++ fldd $f18, 10*8($30) ++ fldd $f19, 11*8($30) ++ fldd $f20, 12*8($30) ++ fldd $f21, 13*8($30) ++ ldl $0, 14*8($30) ++ ldl $1, 15*8($30) ++ ldl $2, 16*8($30) ++ ldl $3, 17*8($30) ++ ldl $4, 18*8($30) ++ ldl $5, 19*8($30) ++ ldl $6, 20*8($30) ++ ldl $7, 21*8($30) ++ ldl $8, 22*8($30) ++ ldl $22, 23*8($30) ++ ldl $23, 24*8($30) ++ ldl $24, 25*8($30) ++ ldl $25, 26*8($30) ++ ldl $29, 27*8($30) ++ fldd $f0, 28*8($30) ++ fldd $f1, 29*8($30) ++ fldd $f10, 30*8($30) ++ fldd $f11, 31*8($30) ++ fldd $f12, 32*8($30) ++ fldd $f13, 33*8($30) ++ fldd $f14, 34*8($30) ++ fldd $f15, 35*8($30) ++ fldd $f22, 36*8($30) ++ fldd $f23, 37*8($30) ++ fldd $f24, 38*8($30) ++ fldd $f25, 39*8($30) ++ fldd $f26, 40*8($30) ++ fldd $f27, 41*8($30) ++ fldd $f28, 42*8($30) ++ fldd $f29, 43*8($30) ++ fldd $f30, 44*8($30) ++ ++ /* Clean up and turn control to the destination. */ ++ ldi $30, FRAMESIZE($30) ++ jmp $31, ($27) ++ ++1: ++ /* Create a frame pointer and allocate a new argument frame. */ ++ savei 15, 45*8 ++ mov $30, $15 ++ cfi_def_cfa_register (15) ++ addl $18, 15, $18 ++ bic $18, 15, $18 ++ subl $30, $18, $30 ++ ++ /* Save the call destination around memcpy. */ ++ stl $0, 46*8($30) ++ ++ /* Copy the stack arguments into place. */ ++ ldi $16, 0($30) ++ ldi $17, FRAMESIZE($15) ++ call $26, memcpy ++ ldgp $29, 0($26) ++ ++ /* Reload the argument registers. */ ++ ldl $27, 46*8($30) ++ ldl $16, 2*8($15) ++ ldl $17, 3*8($15) ++ ldl $18, 4*8($15) ++ ldl $19, 5*8($15) ++ ldl $20, 6*8($15) ++ ldl $21, 7*8($15) ++ fldd $f16, 8*8($15) ++ fldd $f17, 9*8($15) ++ fldd $f18, 10*8($15) ++ fldd $f19, 11*8($15) ++ fldd $f20, 12*8($15) ++ fldd $f21, 13*8($15) ++ ++ call $26, ($27), 0 ++ ldgp $29, 0($26) ++ ++ /* Set up for call to _dl_audit_pltexit. */ ++ ldl $16, 48*8($15) ++ ldl $17, 49*8($15) ++ stl $0, 46*8($15) ++ ldi $18, 0($15) ++ stl $1, 47*8($15) ++ ldi $19, 46*8($15) ++ fstd $f0, 48*8($15) ++ fstd $f1, 49*8($15) ++ bsr $26, _dl_audit_pltexit !samegp ++ ++ mov $15, $30 ++ cfi_def_cfa_register (30) ++ ldl $26, 0($30) ++ ldl $15, 45*8($30) ++ ldi $30, FRAMESIZE($30) ++ ret ++ ++ cfi_endproc ++ .size _dl_runtime_profile_old, .-_dl_runtime_profile_old +diff --git a/sysdeps/sw_64/ffs.S b/sysdeps/sw_64/ffs.S +new file mode 100644 +index 00000000..f03bf357 +--- /dev/null ++++ b/sysdeps/sw_64/ffs.S +@@ -0,0 +1,91 @@ ++/* Copyright (C) 1996-2023 Free Software Foundation, Inc. ++ Contributed by David Mosberger (davidm@cs.arizona.edu). ++ 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 ++ . */ ++ ++/* Finds the first bit set in an integer. Optimized for the Sw_64 ++ architecture. */ ++ ++#include ++ ++ .set noreorder ++ .set noat ++ ++ ++ENTRY(__ffs) ++#ifdef PROF ++ ldgp gp, 0(pv) ++ ldi AT, _mcount ++ call AT, (AT), _mcount ++ .prologue 1 ++ zap $16, 0xF0, $16 ++ br $ffsl..ng ++#else ++ .prologue 0 ++ zap $16, 0xF0, $16 ++ # FALLTHRU ++#endif ++END(__ffs) ++ ++ .align 4 ++ENTRY(ffsl) ++#ifdef PROF ++ ldgp gp, 0(pv) ++ ldi AT, _mcount ++ call AT, (AT), _mcount ++ .prologue 1 ++$ffsl..ng: ++#else ++ .prologue 0 ++#endif ++ not $16, $1 # e0 : ++ ldi $2, -1 # .. e1 : ++ cmpgeb $1, $2, $3 # e0 : bit N == 1 for byte N == 0 ++ clr $0 # .. e1 : ++ addl $3, 1, $4 # e0 : ++ bic $4, $3, $3 # e1 : bit N == 1 for first byte N != 0 ++ and $3, 0xF0, $4 # e0 : ++ and $3, 0xCC, $5 # .. e1 : ++ and $3, 0xAA, $6 # e0 : ++ selne $4, 4, $0, $0 # .. e1 : ++ selne $5, 2, $5, $5 # e0 : ++ selne $6, 1, $6, $6 # .. e1 : ++ addw $0, $5, $0 # e0 : ++ addw $0, $6, $0 # e1 : $0 == N ++ ext0b $16, $0, $1 # e0 : $1 == byte N ++ ldi $2, 1 # .. e1 : ++ negl $1, $3 # e0 : ++ and $3, $1, $3 # e1 : bit N == least bit set of byte N ++ and $3, 0xF0, $4 # e0 : ++ and $3, 0xCC, $5 # .. e1 : ++ and $3, 0xAA, $6 # e0 : ++ selne $4, 5, $2, $2 # .. e1 : ++ selne $5, 2, $5, $5 # e0 : ++ selne $6, 1, $6, $6 # .. e1 : ++ s8addw $0, $2, $0 # e0 : fmuld byte ofs by 8 and sum ++ addw $5, $6, $5 # .. e1 : ++ addw $0, $5, $0 # e0 : ++ nop # .. e1 : ++ seleq $16, 0, $0, $0 # e0 : trap input == 0 case. ++ ret # .. e1 : 18 ++ ++END(ffsl) ++ ++weak_alias (__ffs, ffs) ++libc_hidden_def (__ffs) ++libc_hidden_builtin_def (ffs) ++weak_extern (ffsl) ++weak_alias (ffsl, ffsll) +diff --git a/sysdeps/sw_64/ffsll.S b/sysdeps/sw_64/ffsll.S +new file mode 100644 +index 00000000..b2f46d89 +--- /dev/null ++++ b/sysdeps/sw_64/ffsll.S +@@ -0,0 +1 @@ ++/* This function is defined in ffs.S. */ +diff --git a/sysdeps/sw_64/jmpbuf-offsets.h b/sysdeps/sw_64/jmpbuf-offsets.h +new file mode 100644 +index 00000000..394ec163 +--- /dev/null ++++ b/sysdeps/sw_64/jmpbuf-offsets.h +@@ -0,0 +1,35 @@ ++/* Private macros for accessing __jmp_buf contents. Sw_64 version. ++ Copyright (C) 2006-2023 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 ++ . */ ++ ++#define JB_S0 0 ++#define JB_S1 1 ++#define JB_S2 2 ++#define JB_S3 3 ++#define JB_S4 4 ++#define JB_S5 5 ++#define JB_PC 6 ++#define JB_FP 7 ++#define JB_SP 8 ++#define JB_F2 9 ++#define JB_F3 10 ++#define JB_F4 11 ++#define JB_F5 12 ++#define JB_F6 13 ++#define JB_F7 14 ++#define JB_F8 15 ++#define JB_F9 16 +diff --git a/sysdeps/sw_64/jmpbuf-unwind.h b/sysdeps/sw_64/jmpbuf-unwind.h +new file mode 100644 +index 00000000..9c3bdff9 +--- /dev/null ++++ b/sysdeps/sw_64/jmpbuf-unwind.h +@@ -0,0 +1,45 @@ ++/* Copyright (C) 2003-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Jakub Jelinek , 2003. ++ ++ 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 ++ ++/* Test if longjmp to JMPBUF would unwind the frame containing a local ++ variable at ADDRESS. */ ++#define _JMPBUF_UNWINDS(_jmpbuf, _address, _demangle) \ ++ ((void *) (_address) < (void *) _demangle ((_jmpbuf)[JB_SP])) ++ ++#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ ++ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) ++ ++static inline uintptr_t __attribute__ ((unused)) _jmpbuf_sp (__jmp_buf regs) ++{ ++ uintptr_t sp = regs[JB_SP]; ++ PTR_DEMANGLE (sp); ++ return sp; ++} ++ ++#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ ++ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) ++ ++/* We use the normal longjmp for unwinding. */ ++#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) +diff --git a/sysdeps/sw_64/ldsodefs.h b/sysdeps/sw_64/ldsodefs.h +new file mode 100644 +index 00000000..e46085a0 +--- /dev/null ++++ b/sysdeps/sw_64/ldsodefs.h +@@ -0,0 +1,40 @@ ++/* Run-time dynamic linker data structures for loaded ELF shared objects. ++ Copyright (C) 2012-2023 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 __LDSODEFS_H ++ ++# include ++ ++struct La_sw_64_regs; ++struct La_sw_64_retval; ++ ++# define ARCH_PLTENTER_MEMBERS \ ++ Elf64_Addr (*sw_64_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *, \ ++ uintptr_t *, struct La_sw_64_regs *, \ ++ unsigned int *, const char *name, \ ++ long int *framesizep); ++ ++# define ARCH_PLTEXIT_MEMBERS \ ++ unsigned int (*sw_64_gnu_pltexit) ( \ ++ Elf64_Sym *, unsigned int, uintptr_t *, uintptr_t *, \ ++ const struct La_sw_64_regs *, struct La_sw_64_retval *, \ ++ const char *); ++ ++# include_next ++ ++#endif +diff --git a/sysdeps/sw_64/machine-gmon.h b/sysdeps/sw_64/machine-gmon.h +new file mode 100644 +index 00000000..3a558bc6 +--- /dev/null ++++ b/sysdeps/sw_64/machine-gmon.h +@@ -0,0 +1,24 @@ ++/* Machine-specific calling sequence for `mcount' profiling function. sw_64 ++ Copyright (C) 1995-2023 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 ++ . */ ++ ++#define _MCOUNT_DECL(from, self) void __mcount (u_long from, u_long self) ++ ++/* Call __mcount with our the return PC for our caller, and the return ++ PC our caller will return to. Empty since we use an assembly stub ++ instead. */ ++#define MCOUNT +diff --git a/sysdeps/sw_64/nptl/pthread-offsets.h b/sysdeps/sw_64/nptl/pthread-offsets.h +new file mode 100644 +index 00000000..370e18ac +--- /dev/null ++++ b/sysdeps/sw_64/nptl/pthread-offsets.h +@@ -0,0 +1,3 @@ ++#define __PTHREAD_MUTEX_KIND_OFFSET 16 ++ ++#define __PTHREAD_RWLOCK_FLAGS_OFFSET 48 +diff --git a/sysdeps/sw_64/nptl/pthreaddef.h b/sysdeps/sw_64/nptl/pthreaddef.h +new file mode 100644 +index 00000000..e1fb46a9 +--- /dev/null ++++ b/sysdeps/sw_64/nptl/pthreaddef.h +@@ -0,0 +1,31 @@ ++/* Copyright (C) 2003-2023 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 ++ . */ ++ ++/* Default stack size. */ ++#define ARCH_STACK_DEFAULT_SIZE (4 * 1024 * 1024) ++ ++/* Minimum guard size. */ ++#define ARCH_MIN_GUARD_SIZE 0 ++ ++/* Required stack pointer alignment at beginning. The ABI requires 16. */ ++#define STACK_ALIGN 16 ++ ++/* Minimal stack size after allocating thread descriptor and guard size. */ ++#define MINIMAL_REST_STACK 4096 ++ ++/* Location of current stack frame. */ ++#define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/sw_64/setjmp.S b/sysdeps/sw_64/setjmp.S +new file mode 100644 +index 00000000..9b0867eb +--- /dev/null ++++ b/sysdeps/sw_64/setjmp.S +@@ -0,0 +1,121 @@ ++/* Copyright (C) 1992-2023 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 ++ . */ ++ ++#define __ASSEMBLY__ ++ ++#include ++#include ++#include ++ ++ .ent __sigsetjmp ++ .global __sigsetjmp ++__sigsetjmp: ++ ldgp gp, 0(pv) ++ ++$sigsetjmp_local: ++#ifndef PIC ++#define FRAME 16 ++ subl sp, FRAME, sp ++ .frame sp, FRAME, ra, 0 ++ stl ra, 0(sp) ++ .mask 0x04000000, -FRAME ++#else ++#define FRAME 0 ++ .frame sp, FRAME, ra, 0 ++#endif ++#ifdef PROF ++ .set noat ++ ldi AT, _mcount ++ call AT, (AT), _mcount ++ .set at ++#endif ++ .prologue 1 ++ ++ stl s0, JB_S0*8(a0) ++ stl s1, JB_S1*8(a0) ++ stl s2, JB_S2*8(a0) ++ stl s3, JB_S3*8(a0) ++ stl s4, JB_S4*8(a0) ++ stl s5, JB_S5*8(a0) ++#ifdef PTR_MANGLE ++ PTR_MANGLE(t1, ra, t0) ++ stl t1, JB_PC*8(a0) ++#else ++ stl ra, JB_PC*8(a0) ++#endif ++#if defined(PTR_MANGLE) && FRAME == 0 ++ PTR_MANGLE2(t1, sp, t0) ++#else ++ addl sp, FRAME, t1 ++# ifdef PTR_MANGLE ++ PTR_MANGLE2(t1, t1, t0) ++# endif ++#endif ++ stl t1, JB_SP*8(a0) ++#ifdef PTR_MANGLE ++ PTR_MANGLE2(t1, fp, t0) ++ stl t1, JB_FP*8(a0) ++#else ++ stl fp, JB_FP*8(a0) ++#endif ++ fstd $f2, JB_F2*8(a0) ++ fstd $f3, JB_F3*8(a0) ++ fstd $f4, JB_F4*8(a0) ++ fstd $f5, JB_F5*8(a0) ++ fstd $f6, JB_F6*8(a0) ++ fstd $f7, JB_F7*8(a0) ++ fstd $f8, JB_F8*8(a0) ++ fstd $f9, JB_F9*8(a0) ++ ++#ifndef PIC ++ /* Call to C to (potentially) save our signal mask. */ ++ call ra, __sigjmp_save ++ ldl ra, 0(sp) ++ addl sp, 16, sp ++ ret ++#elif IS_IN (rtld) ++ /* In ld.so we never save the signal mask. */ ++ mov 0, v0 ++ ret ++#else ++ /* Tailcall to save the signal mask. */ ++ br $31, __sigjmp_save !samegp ++#endif ++ ++END(__sigsetjmp) ++hidden_def (__sigsetjmp) ++ ++/* Put these traditional entry points in the same file so that we can ++ elide much of the nonsense in trying to jmp to the real function. */ ++ ++ENTRY(_setjmp) ++ ldgp gp, 0(pv) ++ .prologue 1 ++ mov 0, a1 ++ br $sigsetjmp_local ++END(_setjmp) ++libc_hidden_def (_setjmp) ++ ++ENTRY(setjmp) ++ ldgp gp, 0(pv) ++ .prologue 1 ++ mov 1, a1 ++ br $sigsetjmp_local ++END(setjmp) ++ ++weak_extern(_setjmp) ++weak_extern(setjmp) +diff --git a/sysdeps/sw_64/sotruss-lib.c b/sysdeps/sw_64/sotruss-lib.c +new file mode 100644 +index 00000000..0cf35da9 +--- /dev/null ++++ b/sysdeps/sw_64/sotruss-lib.c +@@ -0,0 +1,48 @@ ++/* Override generic sotruss-lib.c to define actual functions for Sw_64. ++ Copyright (C) 2012-2023 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 ++ . */ ++ ++#define HAVE_ARCH_PLTENTER ++#define HAVE_ARCH_PLTEXIT ++ ++#include ++ ++ElfW (Addr) la_sw_64_gnu_pltenter (ElfW (Sym) * sym __attribute__ ((unused)), ++ unsigned int ndx __attribute__ ((unused)), ++ uintptr_t *refcook, uintptr_t *defcook, ++ La_sw_64_regs *regs, unsigned int *flags, ++ const char *symname, long int *framesizep) ++{ ++ print_enter (refcook, defcook, symname, regs->lr_r16, regs->lr_r17, ++ regs->lr_r18, *flags); ++ ++ /* No need to copy anything, we will not need the parameters in any case. */ ++ *framesizep = 0; ++ ++ return sym->st_value; ++} ++ ++unsigned int ++la_sw_64_gnu_pltexit (ElfW (Sym) * sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, const struct La_sw_64_regs *inregs, ++ struct La_sw_64_retval *outregs, const char *symname) ++{ ++ print_exit (refcook, defcook, symname, outregs->lrv_r0); ++ ++ return 0; ++} +diff --git a/sysdeps/sw_64/start.S b/sysdeps/sw_64/start.S +new file mode 100644 +index 00000000..a0edc6ce +--- /dev/null ++++ b/sysdeps/sw_64/start.S +@@ -0,0 +1,103 @@ ++/* Startup code for Sw_64/ELF. ++ Copyright (C) 1993-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson ++ ++ 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. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file with other ++ programs, and to distribute those programs without any restriction ++ coming from the use of this file. (The GNU Lesser General Public ++ License restrictions do apply in other respects; for example, they ++ cover modification of the file, and distribution when not linked ++ into another program.) ++ ++ Note that people who make modified versions of this file are not ++ obligated to grant this special exception for their modified ++ versions; it is their choice whether to do so. The GNU Lesser ++ General Public License gives permission to release a modified ++ version without this exception; this exception also makes it ++ possible to release a modified version which carries forward this ++ exception. ++ ++ 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 ++ ++ .text ++ .align 3 ++ .globl _start ++ .ent _start, 0 ++ .type _start,@function ++_start: ++ .frame $15, 0, $15 ++ br gp, 1f ++1: ldgp gp, 0(gp) ++ subl sp, 16, sp ++ mov 0, $15 ++ .prologue 0 ++ ++ rfpcr $f0 ++ fimovd $f0,a1 ++ ldi a2,1($31) ++ sll a2,45,a2 ++ bis a1,a2,a1 ++ ifmovd a1,$f0 ++ wfpcr $f0 ++ ++ /* Load address of the user's main function. */ ++ setfpec1 ++ ldi a0, main ++ ++ ldw a1, 16(sp) /* get argc */ ++ ldi a2, 24(sp) /* get argv */ ++ ++ /* Load address of our own entry points to .fini and .init. */ ++ mov $r31, a3 ++ mov $r31, a4 ++ ++ /* Store address of the shared library termination function. */ ++ mov v0, a5 ++ ++ /* Provide the highest stack address to the user code. */ ++ stl sp, 0(sp) ++ ++/* For 256 simd, we should change the value of $SP to 32 bytes align */ ++ and sp, 0x1f, s0 ++ beq s0, 2f ++ subl sp, 0x10, sp ++2: ++ /* Call the user's main function, and exit with its value. ++ But let the libc call main. */ ++ call ra, __libc_start_main ++ ++/* Reload sp */ ++ beq s0, 3f ++ addl sp, 0x10, sp ++3: ++ /* Die very horribly if exit returns. Call_pal hlt is callable from ++ kernel mode only; this will result in an illegal instruction trap. */ ++ sys_call 0 ++ .end _start ++ ++/* For ECOFF backwards compatibility. */ ++weak_alias (_start, __start) ++ ++/* Define a symbol for the first piece of initialized data. */ ++ .data ++ .globl __data_start ++__data_start: ++ .weak data_start ++ data_start = __data_start +diff --git a/sysdeps/sw_64/sw8a/nptl/pthread-offsets.h b/sysdeps/sw_64/sw8a/nptl/pthread-offsets.h +new file mode 100644 +index 00000000..370e18ac +--- /dev/null ++++ b/sysdeps/sw_64/sw8a/nptl/pthread-offsets.h +@@ -0,0 +1,3 @@ ++#define __PTHREAD_MUTEX_KIND_OFFSET 16 ++ ++#define __PTHREAD_RWLOCK_FLAGS_OFFSET 48 +diff --git a/sysdeps/sw_64/sw8a/nptl/pthreaddef.h b/sysdeps/sw_64/sw8a/nptl/pthreaddef.h +new file mode 100644 +index 00000000..e1fb46a9 +--- /dev/null ++++ b/sysdeps/sw_64/sw8a/nptl/pthreaddef.h +@@ -0,0 +1,31 @@ ++/* Copyright (C) 2003-2023 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 ++ . */ ++ ++/* Default stack size. */ ++#define ARCH_STACK_DEFAULT_SIZE (4 * 1024 * 1024) ++ ++/* Minimum guard size. */ ++#define ARCH_MIN_GUARD_SIZE 0 ++ ++/* Required stack pointer alignment at beginning. The ABI requires 16. */ ++#define STACK_ALIGN 16 ++ ++/* Minimal stack size after allocating thread descriptor and guard size. */ ++#define MINIMAL_REST_STACK 4096 ++ ++/* Location of current stack frame. */ ++#define CURRENT_STACK_FRAME __builtin_frame_address (0) +diff --git a/sysdeps/sw_64/sw8a/nptl/tcb-offsets.sym b/sysdeps/sw_64/sw8a/nptl/tcb-offsets.sym +new file mode 100644 +index 00000000..1005621b +--- /dev/null ++++ b/sysdeps/sw_64/sw8a/nptl/tcb-offsets.sym +@@ -0,0 +1,13 @@ ++#include ++#include ++ ++-- ++ ++-- Abuse tls.h macros to derive offsets relative to the thread register. ++-- # define __builtin_thread_pointer() ((void *) 0) ++-- # define thread_offsetof(mem) ((void *) &THREAD_SELF->mem - (void *) 0) ++-- Ho hum, this doesn't work in gcc4, so Know Things about THREAD_SELF ++#define thread_offsetof(mem) (long)(offsetof(struct pthread, mem) - sizeof(struct pthread)) ++ ++MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) ++TID_OFFSET thread_offsetof (tid) +diff --git a/sysdeps/sw_64/tls-macros.h b/sysdeps/sw_64/tls-macros.h +new file mode 100644 +index 00000000..0e9c7e26 +--- /dev/null ++++ b/sysdeps/sw_64/tls-macros.h +@@ -0,0 +1,36 @@ ++/* Macros to support TLS testing in times of missing compiler support. */ ++ ++extern void *__tls_get_addr (void *); ++ ++#define TLS_GD(x) \ ++ ({ \ ++ register void *__gp asm("$29"); \ ++ void *__result; \ ++ asm ("ldi %0, " #x "($gp) !tlsgd" : "=r"(__result) : "r"(__gp)); \ ++ __tls_get_addr (__result); \ ++ }) ++ ++#define TLS_LD(x) \ ++ ({ \ ++ register void *__gp asm("$29"); \ ++ void *__result; \ ++ asm ("ldi %0, " #x "($gp) !tlsldm" : "=r"(__result) : "r"(__gp)); \ ++ __result = __tls_get_addr (__result); \ ++ asm ("ldi %0, " #x "(%0) !dtprel" : "+r"(__result)); \ ++ __result; \ ++ }) ++ ++#define TLS_IE(x) \ ++ ({ \ ++ register void *__gp asm("$29"); \ ++ long ofs; \ ++ asm ("ldl %0, " #x "($gp) !gottprel" : "=r"(ofs) : "r"(__gp)); \ ++ __builtin_thread_pointer () + ofs; \ ++ }) ++ ++#define TLS_LE(x) \ ++ ({ \ ++ void *__result = __builtin_thread_pointer (); \ ++ asm ("ldi %0, " #x "(%0) !tprel" : "+r"(__result)); \ ++ __result; \ ++ }) +diff --git a/sysdeps/sw_64/tst-audit.h b/sysdeps/sw_64/tst-audit.h +new file mode 100644 +index 00000000..6f9633fd +--- /dev/null ++++ b/sysdeps/sw_64/tst-audit.h +@@ -0,0 +1,24 @@ ++/* Definitions for testing PLT entry/exit auditing. Sw_64 version. ++ Copyright (C) 2012-2023 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 ++ . */ ++ ++#define pltenter la_sw_64_gnu_pltenter ++#define pltexit la_sw_64_gnu_pltexit ++#define La_regs La_sw_64_regs ++#define La_retval La_sw_64_retval ++#define int_retval lrv_r0 +diff --git a/sysdeps/sw_64/tst-file-align.h b/sysdeps/sw_64/tst-file-align.h +new file mode 100644 +index 00000000..2c4847f5 +--- /dev/null ++++ b/sysdeps/sw_64/tst-file-align.h +@@ -0,0 +1,20 @@ ++/* Check file alignment. Sw_64 version. ++ Copyright (C) 2021-2023 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 ++ . */ ++ ++/* This should cover all possible alignments we currently support. */ ++#define ALIGN 0x10000 +diff --git a/sysdeps/sw_64/unwind-arch.h b/sysdeps/sw_64/unwind-arch.h +new file mode 100644 +index 00000000..a64260bd +--- /dev/null ++++ b/sysdeps/sw_64/unwind-arch.h +@@ -0,0 +1,28 @@ ++/* Dynamic loading of the libgcc unwinder. sw_64 customization. ++ Copyright (C) 2023 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 _ARCH_UNWIND_LINK_H ++#define _ARCH_UNWIND_LINK_H ++ ++#define UNWIND_LINK_GETIP 1 ++#define UNWIND_LINK_FRAME_STATE_FOR 1 ++#define UNWIND_LINK_FRAME_ADJUSTMENT 0 ++#define UNWIND_LINK_EXTRA_FIELDS ++#define UNWIND_LINK_EXTRA_INIT ++ ++#endif /* _ARCH_UNWIND_LINK_H */ +diff --git a/sysdeps/unix/sysv/linux/sw_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/sw_64/____longjmp_chk.S +new file mode 100644 +index 00000000..b2c2b539 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/____longjmp_chk.S +@@ -0,0 +1,145 @@ ++/* Copyright (C) 1992-2023 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 ++ ++ ++ .section .rodata.str1.1,"aMS",@progbits,1 ++ .type longjmp_msg,@object ++longjmp_msg: ++ .string "longjmp causes uninitialized stack frame" ++ .size longjmp_msg, .-longjmp_msg ++ ++ ++/* 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 ++ .align 4 ++ .globl ____longjmp_chk ++ .type ____longjmp_chk, @function ++ .usepv ____longjmp_chk, std ++ ++ cfi_startproc ++____longjmp_chk: ++ ldgp gp, 0(pv) ++#ifdef PROF ++ .set noat ++ ldi AT, _mcount ++ call AT, (AT), _mcount ++ .set at ++#endif ++ ++ ldl s2, JB_PC*8(a0) ++ mov a0, s0 ++ ldl fp, JB_FP*8(a0) ++ mov a1, s1 ++ ldl s3, JB_SP*8(a0) ++ seleq s1, 1, s1, s1 ++ ++#ifdef PTR_DEMANGLE ++ PTR_DEMANGLE (s2, t1) ++ PTR_DEMANGLE2 (s3, t1) ++ PTR_DEMANGLE2 (fp, t1) ++#endif ++ /* ??? While this is a proper test for detecting a longjmp to an ++ invalid frame within any given stack, the main thread stack is ++ located *below* almost everything in the address space. Which ++ means that the test at Lfail vs the signal stack will almost ++ certainly never pass. We ought bounds check top and bottom of ++ the current thread's stack. */ ++ cmpule s3, sp, t1 ++ bne t1, $Lfail ++ ++ .align 4 ++$Lok: ++ mov s0, a0 ++ mov s1, v0 ++ mov s3, t0 ++ mov s2, ra ++ cfi_remember_state ++ cfi_def_cfa (a0, 0) ++ cfi_register (sp, t0) ++ cfi_offset (s0, JB_S0*8) ++ cfi_offset (s1, JB_S1*8) ++ cfi_offset (s2, JB_S2*8) ++ cfi_offset (s3, JB_S3*8) ++ cfi_offset (s4, JB_S4*8) ++ cfi_offset (s5, JB_S5*8) ++ cfi_offset (s3, JB_S3*8) ++ cfi_offset ($f2, JB_F2*8) ++ cfi_offset ($f3, JB_F3*8) ++ cfi_offset ($f4, JB_F4*8) ++ cfi_offset ($f5, JB_F5*8) ++ cfi_offset ($f6, JB_F6*8) ++ cfi_offset ($f7, JB_F7*8) ++ cfi_offset ($f8, JB_F8*8) ++ cfi_offset ($f9, JB_F9*8) ++ ldl s0, JB_S0*8(a0) ++ ldl s1, JB_S1*8(a0) ++ ldl s2, JB_S2*8(a0) ++ ldl s3, JB_S3*8(a0) ++ ldl s4, JB_S4*8(a0) ++ ldl s5, JB_S5*8(a0) ++ fldd $f2, JB_F2*8(a0) ++ fldd $f3, JB_F3*8(a0) ++ fldd $f4, JB_F4*8(a0) ++ fldd $f5, JB_F5*8(a0) ++ fldd $f6, JB_F6*8(a0) ++ fldd $f7, JB_F7*8(a0) ++ fldd $f8, JB_F8*8(a0) ++ fldd $f9, JB_F9*8(a0) ++ mov t0, sp ++ ret ++ ++ .align 4 ++$Lfail: ++ cfi_restore_state ++ ldi v0, __NR_sigaltstack ++ ldi a0, 0 ++ ldi a1, -32(sp) ++ ldi sp, -32(sp) ++ cfi_adjust_cfa_offset (32) ++ sys_call 0x83 ++ ldl t0, 0(sp) /* ss_sp */ ++ ldw t1, 8(sp) /* ss_flags */ ++ ldl t2, 16(sp) /* ss_size */ ++ ldi sp, 32(sp) ++ cfi_adjust_cfa_offset (-32) ++ ++ /* Without working sigaltstack we cannot perform the test. */ ++ bne a3, $Lok ++ ++ addl t0, t2, t0 /* t0 = ss_sp + ss_size */ ++ subl t0, s3, t0 /* t0 = (ss_sp + ss_size) - new_sp */ ++ cmpule t2, t0, t0 /* t0 = (t0 >= ss_size) */ ++ and t0, t1, t0 /* t0 = (t0 >= ss_size) & (ss_flags & SS_ONSTACK) */ ++ bne t0, $Lok ++ ++ ldih a0, longjmp_msg(gp) !gprelhigh ++ ldi a0, longjmp_msg(a0) !gprellow ++#ifdef PIC ++ call ra, HIDDEN_JUMPTARGET (__fortify_fail) ++#else ++ bsr ra, HIDDEN_JUMPTARGET (__fortify_fail) !samegp ++#endif ++ sys_call 0x81 ++ ++ cfi_endproc ++ .size ____longjmp_chk, .-____longjmp_chk +-- +2.25.1 + diff --git a/0004-Sw64-Thread-Local-Storage-Support.patch b/0004-Sw64-Thread-Local-Storage-Support.patch new file mode 100644 index 0000000..496178a --- /dev/null +++ b/0004-Sw64-Thread-Local-Storage-Support.patch @@ -0,0 +1,356 @@ +From 20affa072418646ada75247771c28633ac47688c Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Fri, 29 Nov 2024 13:55:34 +0800 +Subject: [PATCH 04/23] Sw64: Thread-Local Storage Support + +--- + sysdeps/sw_64/dl-tls.h | 26 ++++++++ + sysdeps/sw_64/libc-tls.c | 32 ++++++++++ + sysdeps/sw_64/nptl/tls.h | 108 ++++++++++++++++++++++++++++++++++ + sysdeps/sw_64/stackinfo.h | 33 +++++++++++ + sysdeps/sw_64/sw8a/nptl/tls.h | 106 +++++++++++++++++++++++++++++++++ + 5 files changed, 305 insertions(+) + create mode 100644 sysdeps/sw_64/dl-tls.h + create mode 100644 sysdeps/sw_64/libc-tls.c + create mode 100644 sysdeps/sw_64/nptl/tls.h + create mode 100644 sysdeps/sw_64/stackinfo.h + create mode 100644 sysdeps/sw_64/sw8a/nptl/tls.h + +diff --git a/sysdeps/sw_64/dl-tls.h b/sysdeps/sw_64/dl-tls.h +new file mode 100644 +index 00000000..0795a41a +--- /dev/null ++++ b/sysdeps/sw_64/dl-tls.h +@@ -0,0 +1,26 @@ ++/* Thread-local storage handling in the ELF dynamic linker. Sw_64 version. ++ Copyright (C) 2002-2023 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 ++ . */ ++ ++/* Type used for the representation of TLS information in the GOT. */ ++typedef struct ++{ ++ unsigned long int ti_module; ++ unsigned long int ti_offset; ++} tls_index; ++ ++extern void *__tls_get_addr (tls_index *ti); +diff --git a/sysdeps/sw_64/libc-tls.c b/sysdeps/sw_64/libc-tls.c +new file mode 100644 +index 00000000..f268dd08 +--- /dev/null ++++ b/sysdeps/sw_64/libc-tls.c +@@ -0,0 +1,32 @@ ++/* Thread-local storage handling in the ELF dynamic linker. Sw_64 version. ++ Copyright (C) 2003-2023 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 ++ ++/* On Sw_64, linker optimizations are not required, so __tls_get_addr ++ can be called even in statically linked binaries. In this case module ++ must be always 1 and PT_TLS segment exist in the binary, otherwise it ++ would not link. */ ++ ++void * ++__tls_get_addr (tls_index *ti) ++{ ++ dtv_t *dtv = THREAD_DTV (); ++ return (char *) dtv[1].pointer.val + ti->ti_offset; ++} +diff --git a/sysdeps/sw_64/nptl/tls.h b/sysdeps/sw_64/nptl/tls.h +new file mode 100644 +index 00000000..8df86916 +--- /dev/null ++++ b/sysdeps/sw_64/nptl/tls.h +@@ -0,0 +1,108 @@ ++/* Definition for thread-local data handling. NPTL/Sw_64 version. ++ Copyright (C) 2003-2023 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 _TLS_H ++#define _TLS_H 1 ++ ++#include ++ ++#ifndef __ASSEMBLER__ ++# include ++# include ++# include ++# include ++ ++/* 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 ++ ++/* Get the thread descriptor definition. */ ++# include ++ ++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 of the TCB. */ ++# define TLS_TCB_SIZE sizeof (tcbhead_t) ++ ++/* This is the size we need before TCB. */ ++# define TLS_PRE_TCB_SIZE sizeof (struct pthread) ++ ++/* Install the dtv pointer. The pointer passed is to the element with ++ index -1 which contain the length. */ ++# define INSTALL_DTV(tcbp, dtvp) (((tcbhead_t *) (tcbp))->dtv = (dtvp) + 1) ++ ++/* Install new dtv for current thread. */ ++# define INSTALL_NEW_DTV(dtv) (THREAD_DTV () = (dtv)) ++ ++/* Return dtv of given thread descriptor. */ ++# define GET_DTV(tcbp) (((tcbhead_t *) (tcbp))->dtv) ++ ++/* Code to initially initialize the thread pointer. This might need ++ special attention since 'errno' is not yet available and if the ++ operation can cause a failure 'errno' must not be touched. */ ++# define TLS_INIT_TP(tcbp) \ ++ (__builtin_set_thread_pointer ((void *) (tcbp)), true) ++ ++/* Value passed to 'clone' for initialization of the thread register. */ ++# define TLS_DEFINE_INIT_TP(tp, pd) void *tp = (pd) + 1 ++ ++/* 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 ((struct pthread *) __builtin_thread_pointer () - 1) ++ ++/* Magic for libthread_db to know how to do THREAD_SELF. */ ++# define DB_THREAD_SELF REGISTER (64, 64, 32 * 8, -sizeof (struct pthread)) ++ ++# include ++ ++/* Get and set the global scope generation counter in struct pthread. */ ++# define THREAD_GSCOPE_FLAG_UNUSED 0 ++# define THREAD_GSCOPE_FLAG_USED 1 ++# define THREAD_GSCOPE_FLAG_WAIT 2 ++# define THREAD_GSCOPE_RESET_FLAG() \ ++ do \ ++ { \ ++ int __res = atomic_exchange_release ( \ ++ &THREAD_SELF->header.gscope_flag, THREAD_GSCOPE_FLAG_UNUSED); \ ++ if (__res == THREAD_GSCOPE_FLAG_WAIT) \ ++ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \ ++ } \ ++ while (0) ++# define THREAD_GSCOPE_SET_FLAG() \ ++ do \ ++ { \ ++ THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ ++ atomic_write_barrier (); \ ++ } \ ++ while (0) ++ ++#endif /* __ASSEMBLER__ */ ++ ++#endif /* tls.h */ +diff --git a/sysdeps/sw_64/stackinfo.h b/sysdeps/sw_64/stackinfo.h +new file mode 100644 +index 00000000..661a814a +--- /dev/null ++++ b/sysdeps/sw_64/stackinfo.h +@@ -0,0 +1,33 @@ ++/* Copyright (C) 2001-2023 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 ++ . */ ++ ++/* This file contains a bit of information about the stack allocation ++ of the processor. */ ++ ++#ifndef _STACKINFO_H ++#define _STACKINFO_H 1 ++ ++#include ++ ++/* On Sw_64 the stack grows down. */ ++#define _STACK_GROWS_DOWN 1 ++ ++/* Default to an executable stack. PF_X can be overridden if PT_GNU_STACK is ++ * present, but it is presumed absent. */ ++#define DEFAULT_STACK_PERMS (PF_R | PF_W | PF_X) ++ ++#endif /* stackinfo.h */ +diff --git a/sysdeps/sw_64/sw8a/nptl/tls.h b/sysdeps/sw_64/sw8a/nptl/tls.h +new file mode 100644 +index 00000000..d0942c19 +--- /dev/null ++++ b/sysdeps/sw_64/sw8a/nptl/tls.h +@@ -0,0 +1,106 @@ ++/* Definition for thread-local data handling. NPTL/Sw_64 version. ++ Copyright (C) 2003-2023 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 _TLS_H ++#define _TLS_H 1 ++ ++#include ++ ++#ifndef __ASSEMBLER__ ++# include ++# include ++# include ++# include ++ ++/* 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 ++ ++/* Get the thread descriptor definition. */ ++# include ++ ++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 of the TCB. */ ++# define TLS_TCB_SIZE sizeof (tcbhead_t) ++ ++/* This is the size we need before TCB. */ ++# define TLS_PRE_TCB_SIZE sizeof (struct pthread) ++ ++/* Install the dtv pointer. The pointer passed is to the element with ++ index -1 which contain the length. */ ++# define INSTALL_DTV(tcbp, dtvp) (((tcbhead_t *) (tcbp))->dtv = (dtvp) + 1) ++ ++/* Install new dtv for current thread. */ ++# define INSTALL_NEW_DTV(dtv) (THREAD_DTV () = (dtv)) ++ ++/* Return dtv of given thread descriptor. */ ++# define GET_DTV(tcbp) (((tcbhead_t *) (tcbp))->dtv) ++ ++/* Code to initially initialize the thread pointer. This might need ++ special attention since 'errno' is not yet available and if the ++ operation can cause a failure 'errno' must not be touched. */ ++# define TLS_INIT_TP(tcbp) \ ++ (__builtin_set_thread_pointer ((void *) (tcbp)), true) ++ ++/* Value passed to 'clone' for initialization of the thread register. */ ++# define TLS_DEFINE_INIT_TP(tp, pd) void *tp = (pd) + 1 ++ ++/* 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 ((struct pthread *) __builtin_thread_pointer () - 1) ++ ++/* Magic for libthread_db to know how to do THREAD_SELF. */ ++# define DB_THREAD_SELF REGISTER (64, 64, 32 * 8, -sizeof (struct pthread)) ++ ++# include ++# define THREAD_GSCOPE_FLAG_UNUSED 0 ++# define THREAD_GSCOPE_FLAG_USED 1 ++# define THREAD_GSCOPE_FLAG_WAIT 2 ++# define THREAD_GSCOPE_RESET_FLAG() \ ++ do \ ++ { \ ++ int __res = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ ++ THREAD_GSCOPE_FLAG_UNUSED); \ ++ if (__res == THREAD_GSCOPE_FLAG_WAIT) \ ++ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \ ++ } \ ++ while (0) ++# define THREAD_GSCOPE_SET_FLAG() \ ++ do \ ++ { \ ++ THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ ++ atomic_write_barrier (); \ ++ } \ ++ while (0) ++ ++#endif /* __ASSEMBLER__ */ ++ ++#endif /* tls.h */ +-- +2.25.1 + diff --git a/0005-Sw64-Generic-math.h-and-soft-fp-Routines.patch b/0005-Sw64-Generic-math.h-and-soft-fp-Routines.patch new file mode 100644 index 0000000..9c4279f --- /dev/null +++ b/0005-Sw64-Generic-math.h-and-soft-fp-Routines.patch @@ -0,0 +1,356 @@ +From cdac1f3a59bcd4bdad675f7c352aefa03d237f96 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Fri, 29 Nov 2024 14:19:24 +0800 +Subject: [PATCH 05/23] Sw64: Generic and soft-fp Routines + +--- + sysdeps/sw_64/fpu/bits/fenv.h | 140 ++++++++++++++++++++++++++++++++++ + sysdeps/sw_64/local-soft-fp.h | 67 ++++++++++++++++ + sysdeps/sw_64/sfp-machine.h | 105 +++++++++++++++++++++++++ + sysdeps/sw_64/tininess.h | 1 + + 4 files changed, 313 insertions(+) + create mode 100644 sysdeps/sw_64/fpu/bits/fenv.h + create mode 100644 sysdeps/sw_64/local-soft-fp.h + create mode 100644 sysdeps/sw_64/sfp-machine.h + create mode 100644 sysdeps/sw_64/tininess.h + +diff --git a/sysdeps/sw_64/fpu/bits/fenv.h b/sysdeps/sw_64/fpu/bits/fenv.h +new file mode 100644 +index 00000000..ec5dfb8d +--- /dev/null ++++ b/sysdeps/sw_64/fpu/bits/fenv.h +@@ -0,0 +1,140 @@ ++/* Copyright (C) 1997-2023 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 _FENV_H ++# error "Never use directly; include instead." ++#endif ++ ++/* Define the bits representing the exception. ++ ++ Note that these are the bit positions as defined by the OSF/1 ++ ieee_{get,set}_control_word interface and not by the hardware fpcr. ++ ++ See the Sw_64 Architecture Handbook section 4.7.7.3 for details, ++ but in summary, trap shadows mean the hardware register can acquire ++ extra exception bits so for proper IEEE support the tracking has to ++ be done in software -- in this case with kernel support. ++ ++ As to why the system call interface isn't in the same format as ++ the hardware register, only those crazy folks at DEC can tell you. */ ++ ++enum ++{ ++#ifdef __USE_GNU ++ FE_DENORMAL = ++# define FE_DENORMAL (1 << 22) ++ FE_DENORMAL, ++#endif ++ ++ FE_INEXACT = ++#define FE_INEXACT (1 << 21) ++ FE_INEXACT, ++ ++ FE_UNDERFLOW = ++#define FE_UNDERFLOW (1 << 20) ++ FE_UNDERFLOW, ++ ++ FE_OVERFLOW = ++#define FE_OVERFLOW (1 << 19) ++ FE_OVERFLOW, ++ ++ FE_DIVBYZERO = ++#define FE_DIVBYZERO (1 << 18) ++ FE_DIVBYZERO, ++ ++ FE_INVALID = ++#define FE_INVALID (1 << 17) ++ FE_INVALID, ++ ++ FE_ALL_EXCEPT = ++#define FE_ALL_EXCEPT (0x3f << 17) ++ FE_ALL_EXCEPT ++}; ++ ++/* Sw_64 chips support all four defined rouding modes. ++ ++ Note that code must be compiled to use dynamic rounding (/d) instructions ++ to see these changes. For gcc this is -mfp-rounding-mode=d; for DEC cc ++ this is -fprm d. The default for both is static rounding to nearest. ++ ++ These are shifted down 58 bits from the hardware fpcr because the ++ functions are declared to take integers. */ ++ ++enum ++{ ++ FE_TOWARDZERO = ++#define FE_TOWARDZERO 0 ++ FE_TOWARDZERO, ++ ++ FE_DOWNWARD = ++#define FE_DOWNWARD 1 ++ FE_DOWNWARD, ++ ++ FE_TONEAREST = ++#define FE_TONEAREST 2 ++ FE_TONEAREST, ++ ++ FE_UPWARD = ++#define FE_UPWARD 3 ++ FE_UPWARD, ++}; ++ ++#ifdef __USE_GNU ++/* On later hardware, and later kernels for earlier hardware, we can forcibly ++ underflow denormal inputs and outputs. This can speed up certain programs ++ significantly, usually without affecting accuracy. */ ++enum ++{ ++ FE_MAP_DMZ = 1UL << 12, /* Map denorm inputs to zero */ ++# define FE_MAP_DMZ FE_MAP_DMZ ++ ++ FE_MAP_UMZ = 1UL << 13, /* Map underflowed outputs to zero */ ++# define FE_MAP_UMZ FE_MAP_UMZ ++}; ++#endif ++ ++/* Type representing exception flags. */ ++typedef unsigned long int fexcept_t; ++ ++/* Type representing floating-point environment. */ ++typedef unsigned long int fenv_t; ++ ++/* If the default argument is used we use this value. Note that due to ++ architecture-specified page mappings, no user-space pointer will ever ++ have its two high bits set. Co-opt one. */ ++#define FE_DFL_ENV ((const fenv_t *) 0x8800000000000000UL) ++ ++#ifdef __USE_GNU ++/* Floating-point environment where none of the exceptions are masked. */ ++# define FE_NOMASK_ENV ((const fenv_t *) 0x880000000000003eUL) ++ ++/* Floating-point environment with (processor-dependent) non-IEEE floating ++ point. In this case, mapping denormals to zero. */ ++# define FE_NONIEEE_ENV ((const fenv_t *) 0x8800000000003000UL) ++#endif ++ ++/* The system calls to talk to the kernel's FP code. */ ++extern unsigned long int __ieee_get_fp_control (void) __THROW; ++extern void __ieee_set_fp_control (unsigned long int __value) __THROW; ++ ++#if __GLIBC_USE (IEC_60559_BFP_EXT_C2X) ++/* Type representing floating-point control modes. */ ++typedef unsigned long int femode_t; ++ ++/* Default floating-point control modes. */ ++# define FE_DFL_MODE ((const femode_t *) 0x8800000000000000UL) ++#endif +diff --git a/sysdeps/sw_64/local-soft-fp.h b/sysdeps/sw_64/local-soft-fp.h +new file mode 100644 +index 00000000..aab93c30 +--- /dev/null ++++ b/sysdeps/sw_64/local-soft-fp.h +@@ -0,0 +1,67 @@ ++#include ++#include ++#include ++ ++/* Helpers for the Ots functions which receive long double arguments ++ in two integer registers, and return values in $16+$17. */ ++ ++#define AXP_UNPACK_RAW_Q(X, val) \ ++ do \ ++ { \ ++ union _FP_UNION_Q _flo; \ ++ _flo.longs.a = val##l; \ ++ _flo.longs.b = val##h; \ ++ FP_UNPACK_RAW_QP (X, &_flo); \ ++ } \ ++ while (0) ++ ++#define AXP_UNPACK_SEMIRAW_Q(X, val) \ ++ do \ ++ { \ ++ union _FP_UNION_Q _flo; \ ++ _flo.longs.a = val##l; \ ++ _flo.longs.b = val##h; \ ++ FP_UNPACK_SEMIRAW_QP (X, &_flo); \ ++ } \ ++ while (0) ++ ++#define AXP_UNPACK_Q(X, val) \ ++ do \ ++ { \ ++ AXP_UNPACK_RAW_Q (X, val); \ ++ _FP_UNPACK_CANONICAL (Q, 2, X); \ ++ } \ ++ while (0) ++ ++#define AXP_PACK_RAW_Q(val, X) FP_PACK_RAW_QP (&val##_flo, X) ++ ++#define AXP_PACK_SEMIRAW_Q(val, X) \ ++ do \ ++ { \ ++ _FP_PACK_SEMIRAW (Q, 2, X); \ ++ AXP_PACK_RAW_Q (val, X); \ ++ } \ ++ while (0) ++ ++#define AXP_PACK_Q(val, X) \ ++ do \ ++ { \ ++ _FP_PACK_CANONICAL (Q, 2, X); \ ++ AXP_PACK_RAW_Q (val, X); \ ++ } \ ++ while (0) ++ ++#define AXP_DECL_RETURN_Q(X) union _FP_UNION_Q X##_flo ++ ++/* ??? We don't have a real way to tell the compiler that we're wanting ++ to return values in $16+$17. Instead use a volatile asm to make sure ++ that the values are live, and just hope that nothing kills the values ++ in between here and the end of the function. */ ++#define AXP_RETURN_Q(X) \ ++ do \ ++ { \ ++ register long r16 __asm__ ("16") = X##_flo.longs.a; \ ++ register long r17 __asm__ ("17") = X##_flo.longs.b; \ ++ asm volatile ("" : : "r"(r16), "r"(r17)); \ ++ } \ ++ while (0) +diff --git a/sysdeps/sw_64/sfp-machine.h b/sysdeps/sw_64/sfp-machine.h +new file mode 100644 +index 00000000..119e50fc +--- /dev/null ++++ b/sysdeps/sw_64/sfp-machine.h +@@ -0,0 +1,105 @@ ++/* Machine-dependent software floating-point definitions. ++ Sw_64 userland IEEE 128-bit version. ++ Copyright (C) 2004-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com), ++ Jakub Jelinek (jj@ultra.linux.cz) and ++ David S. Miller (davem@redhat.com). ++ ++ 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 ++ ++#define _FP_W_TYPE_SIZE 64 ++#define _FP_W_TYPE unsigned long ++#define _FP_WS_TYPE signed long ++#define _FP_I_TYPE long ++ ++#define _FP_MUL_MEAT_S(R, X, Y) _FP_MUL_MEAT_1_imm (_FP_WFRACBITS_S, R, X, Y) ++#define _FP_MUL_MEAT_D(R, X, Y) \ ++ _FP_MUL_MEAT_1_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm) ++#define _FP_MUL_MEAT_Q(R, X, Y) \ ++ _FP_MUL_MEAT_2_wide (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm) ++ ++#define _FP_DIV_MEAT_S(R, X, Y) \ ++ _FP_DIV_MEAT_1_imm (S, R, X, Y, _FP_DIV_HELP_imm) ++#define _FP_DIV_MEAT_D(R, X, Y) _FP_DIV_MEAT_1_udiv_norm (D, R, X, Y) ++#define _FP_DIV_MEAT_Q(R, X, Y) _FP_DIV_MEAT_2_udiv (Q, R, X, Y) ++ ++#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) ++#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1) ++#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1 ++#define _FP_NANSIGN_S 0 ++#define _FP_NANSIGN_D 0 ++#define _FP_NANSIGN_Q 0 ++ ++#define _FP_KEEPNANFRACP 1 ++#define _FP_QNANNEGATEDP 0 ++ ++/* Sw_64 Architecture Handbook, 4.7.10.4 sez that we should prefer any ++ type of NaN in Fb, then Fa. */ ++#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ ++ do \ ++ { \ ++ R##_s = Y##_s; \ ++ _FP_FRAC_COPY_##wc (R, X); \ ++ R##_c = FP_CLS_NAN; \ ++ } \ ++ while (0) ++ ++/* Rounding mode settings. */ ++#define FP_RND_NEAREST FE_TONEAREST ++#define FP_RND_ZERO FE_TOWARDZERO ++#define FP_RND_PINF FE_UPWARD ++#define FP_RND_MINF FE_DOWNWARD ++ ++/* Obtain the current rounding mode. It's given as an argument to ++ all the Ots functions, with 4 meaning "dynamic". */ ++#define FP_ROUNDMODE _round ++ ++/* Exception flags. */ ++#define FP_EX_INVALID FE_INVALID ++#define FP_EX_OVERFLOW FE_OVERFLOW ++#define FP_EX_UNDERFLOW FE_UNDERFLOW ++#define FP_EX_DIVZERO FE_DIVBYZERO ++#define FP_EX_INEXACT FE_INEXACT ++ ++#define _FP_TININESS_AFTER_ROUNDING 1 ++ ++#define FP_INIT_ROUNDMODE \ ++ do \ ++ { \ ++ if (__builtin_expect (_round == 4, 0)) \ ++ { \ ++ unsigned long t; \ ++ __asm__ __volatile__("excb; rfpcr %0" : "=f"(t)); \ ++ _round = (t >> FPCR_ROUND_SHIFT) & 3; \ ++ } \ ++ } \ ++ while (0) ++ ++/* We copy the libm function into libc for soft-fp. */ ++extern int __feraiseexcept (int __excepts) attribute_hidden; ++ ++#define FP_HANDLE_EXCEPTIONS \ ++ do \ ++ { \ ++ if (__builtin_expect (_fex, 0)) \ ++ __feraiseexcept (_fex); \ ++ } \ ++ while (0) ++ ++#define FP_TRAPPING_EXCEPTIONS \ ++ ((__ieee_get_fp_control () & SWCR_ENABLE_MASK) << SWCR_ENABLE_SHIFT) +diff --git a/sysdeps/sw_64/tininess.h b/sysdeps/sw_64/tininess.h +new file mode 100644 +index 00000000..90956c35 +--- /dev/null ++++ b/sysdeps/sw_64/tininess.h +@@ -0,0 +1 @@ ++#define TININESS_AFTER_ROUNDING 1 +-- +2.25.1 + diff --git a/0006-Sw64-Atomic-and-Locking-Implementation.patch b/0006-Sw64-Atomic-and-Locking-Implementation.patch new file mode 100644 index 0000000..37c7a52 --- /dev/null +++ b/0006-Sw64-Atomic-and-Locking-Implementation.patch @@ -0,0 +1,1123 @@ +From d05ecf05cf6abb524216e0a8416fdd78c3d7e6bf Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Fri, 29 Nov 2024 13:59:09 +0800 +Subject: [PATCH 06/23] Sw64: Atomic and Locking Implementation + +--- + sysdeps/sw_64/atomic-machine.h | 393 ++++++++++++++++++ + sysdeps/sw_64/nptl/bits/struct_rwlock.h | 43 ++ + sysdeps/sw_64/nptl/pthread_spin_lock.S | 55 +++ + sysdeps/sw_64/nptl/pthread_spin_trylock.S | 56 +++ + sysdeps/sw_64/sw8a/atomic-machine.h | 371 +++++++++++++++++ + sysdeps/sw_64/sw8a/nptl/bits/struct_rwlock.h | 43 ++ + sysdeps/sw_64/sw8a/nptl/pthread_spin_lock.S | 43 ++ + .../sw_64/sw8a/nptl/pthread_spin_trylock.S | 44 ++ + 8 files changed, 1048 insertions(+) + create mode 100644 sysdeps/sw_64/atomic-machine.h + create mode 100644 sysdeps/sw_64/nptl/bits/struct_rwlock.h + create mode 100644 sysdeps/sw_64/nptl/pthread_spin_lock.S + create mode 100644 sysdeps/sw_64/nptl/pthread_spin_trylock.S + create mode 100644 sysdeps/sw_64/sw8a/atomic-machine.h + create mode 100644 sysdeps/sw_64/sw8a/nptl/bits/struct_rwlock.h + create mode 100644 sysdeps/sw_64/sw8a/nptl/pthread_spin_lock.S + create mode 100644 sysdeps/sw_64/sw8a/nptl/pthread_spin_trylock.S + +diff --git a/sysdeps/sw_64/atomic-machine.h b/sysdeps/sw_64/atomic-machine.h +new file mode 100644 +index 00000000..7f379fbe +--- /dev/null ++++ b/sysdeps/sw_64/atomic-machine.h +@@ -0,0 +1,393 @@ ++/* Copyright (C) 2003-2023 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 ++ ++typedef int8_t atomic8_t; ++typedef uint8_t uatomic8_t; ++typedef int_fast8_t atomic_fast8_t; ++typedef uint_fast8_t uatomic_fast8_t; ++ ++typedef int16_t atomic16_t; ++typedef uint16_t uatomic16_t; ++typedef int_fast16_t atomic_fast16_t; ++typedef uint_fast16_t uatomic_fast16_t; ++ ++typedef int32_t atomic32_t; ++typedef uint32_t uatomic32_t; ++typedef int_fast32_t atomic_fast32_t; ++typedef uint_fast32_t uatomic_fast32_t; ++ ++typedef int64_t atomic64_t; ++typedef uint64_t uatomic64_t; ++typedef int_fast64_t atomic_fast64_t; ++typedef uint_fast64_t uatomic_fast64_t; ++ ++typedef intptr_t atomicptr_t; ++typedef uintptr_t uatomicptr_t; ++typedef intmax_t atomic_max_t; ++typedef uintmax_t uatomic_max_t; ++ ++#define __HAVE_64B_ATOMICS 1 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ ++/* XXX Is this actually correct? */ ++#define ATOMIC_EXCHANGE_USES_CAS 1 ++ ++#define __MB " memb\n" ++ ++/* Compare and exchange. For all of the "xxx" routines, we expect a ++ "__prev" and a "__cmp" variable to be provided by the enclosing scope, ++ in which values are returned. */ ++// delete memb after the rd_f ++#define __arch_compare_and_exchange_xxx_8_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __snew, __addr64; \ ++ __asm__ __volatile__( \ ++ mb1 " bic %[__addr8],7,%[__addr64]\n" \ ++ " ins0b %[__new],%[__addr8],%[__snew]\n" \ ++ "1: lldl %[__tmp],0(%[__addr64])\n" \ ++ " ext0b %[__tmp],%[__addr8],%[__prev]\n" \ ++ " cmpeq %[__prev],%[__old],%[__cmp]\n" \ ++ " wr_f %[__cmp]\n" \ ++ " mask0b %[__tmp],%[__addr8],%[__tmp]\n" \ ++ " or %[__snew],%[__tmp],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr64])\n" \ ++ " rd_f %[__tmp]\n" \ ++ " beq %[__cmp],2f\n" \ ++ " beq %[__tmp],1b\n" \ ++ "2:" \ ++ : [__prev] "=&r"(__prev), [__snew] "=&r"(__snew), \ ++ [__tmp] "=&r"(__tmp), [__cmp] "=&r"(__cmp), \ ++ [__addr64] "=&r"(__addr64) \ ++ : [__addr8] "r"(mem), \ ++ [__old] "Ir"((uint64_t) (uint8_t) (uint64_t) (old)), \ ++ [__new] "r"(new) \ ++ : "memory"); \ ++ }) ++ ++#define __arch_compare_and_exchange_xxx_16_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __snew, __addr64; \ ++ __asm__ __volatile__( \ ++ mb1 " bic %[__addr16],7,%[__addr64]\n" \ ++ " ins1b %[__new],%[__addr16],%[__snew]\n" \ ++ "1: lldl %[__tmp],0(%[__addr64])\n" \ ++ " ext1b %[__tmp],%[__addr16],%[__prev]\n" \ ++ " cmpeq %[__prev],%[__old],%[__cmp]\n" \ ++ " wr_f %[__cmp]\n" \ ++ " mask1b %[__tmp],%[__addr16],%[__tmp]\n" \ ++ " or %[__snew],%[__tmp],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr64])\n" \ ++ " rd_f %[__tmp]\n" \ ++ " beq %[__cmp],2f\n" \ ++ " beq %[__tmp],1b\n" \ ++ "2:" \ ++ : [__prev] "=&r"(__prev), [__snew] "=&r"(__snew), \ ++ [__tmp] "=&r"(__tmp), [__cmp] "=&r"(__cmp), \ ++ [__addr64] "=&r"(__addr64) \ ++ : [__addr16] "r"(mem), \ ++ [__old] "Ir"((uint64_t) (uint16_t) (uint64_t) (old)), \ ++ [__new] "r"(new) \ ++ : "memory"); \ ++ }) ++#define __arch_compare_and_exchange_xxx_32_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __addr, __tmp; \ ++ __asm__ __volatile__( \ ++ mb1 " ldi %[__addr],%[__mem]\n" \ ++ "1: lldw %[__prev],0(%[__addr])\n" \ ++ " cmpeq %[__prev],%[__old],%[__tmp]\n" \ ++ " wr_f %[__tmp]\n" \ ++ " mov %[__new],%[__cmp]\n" \ ++ " lstw %[__cmp],0(%[__addr])\n" \ ++ " rd_f %[__cmp]\n" \ ++ " beq %[__tmp],2f\n" \ ++ " beq %[__cmp],1b\n" \ ++ "2:" \ ++ : [__prev] "=&r"(__prev), [__cmp] "=&r"(__cmp), [__tmp] "=&r"(__tmp), \ ++ [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), \ ++ [__old] "Ir"((uint64_t) (atomic32_t) (uint64_t) (old)), \ ++ [__new] "Ir"(new) \ ++ : "memory"); \ ++ }) ++ ++#define __arch_compare_and_exchange_xxx_64_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __addr, __tmp; \ ++ __asm__ __volatile__(mb1 " ldi %[__addr],%[__mem]\n" \ ++ "1: lldl %[__prev],0(%[__addr])\n" \ ++ " cmpeq %[__prev],%[__old],%[__tmp]\n" \ ++ " wr_f %[__tmp]\n" \ ++ " mov %[__new],%[__cmp]\n" \ ++ " lstl %[__cmp],0(%[__addr])\n" \ ++ " rd_f %[__cmp]\n" \ ++ " beq %[__tmp],2f\n" \ ++ " beq %[__cmp],1b\n" \ ++ "2:" \ ++ : [__prev] "=&r"(__prev), [__cmp] "=&r"(__cmp), \ ++ [__tmp] "=&r"(__tmp), [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), \ ++ [__old] "Ir"((uint64_t) (old)), [__new] "Ir"(new) \ ++ : "memory"); \ ++ }) ++/* For all "bool" routines, we return FALSE if exchange succesful. */ ++ ++#define __arch_compare_and_exchange_bool_8_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_8_int (mem, new, old, mb1, mb2); \ ++ !__cmp; \ ++ }) ++ ++#define __arch_compare_and_exchange_bool_16_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_16_int (mem, new, old, mb1, mb2); \ ++ !__cmp; \ ++ }) ++ ++#define __arch_compare_and_exchange_bool_32_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_32_int (mem, new, old, mb1, mb2); \ ++ !__cmp; \ ++ }) ++ ++#define __arch_compare_and_exchange_bool_64_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_64_int (mem, new, old, mb1, mb2); \ ++ !__cmp; \ ++ }) ++ ++/* For all "val" routines, return the old value whether exchange ++ successful or not. */ ++ ++#define __arch_compare_and_exchange_val_8_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_8_int (mem, new, old, mb1, mb2); \ ++ (typeof (*mem)) __prev; \ ++ }) ++ ++#define __arch_compare_and_exchange_val_16_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_16_int (mem, new, old, mb1, mb2); \ ++ (typeof (*mem)) __prev; \ ++ }) ++ ++#define __arch_compare_and_exchange_val_32_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_32_int (mem, new, old, mb1, mb2); \ ++ (typeof (*mem)) __prev; \ ++ }) ++ ++#define __arch_compare_and_exchange_val_64_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_64_int (mem, new, old, mb1, mb2); \ ++ (typeof (*mem)) __prev; \ ++ }) ++ ++/* Compare and exchange with "acquire" semantics, ie barrier after. */ ++ ++#define atomic_compare_and_exchange_bool_acq(mem, new, old) \ ++ __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, mem, new, old, \ ++ "", __MB) ++ ++#define atomic_compare_and_exchange_val_acq(mem, new, old) \ ++ __atomic_val_bysize (__arch_compare_and_exchange_val, int, mem, new, old, \ ++ "", __MB) ++ ++/* Compare and exchange with "release" semantics, ie barrier before. */ ++ ++#define atomic_compare_and_exchange_val_rel(mem, new, old) \ ++ __atomic_val_bysize (__arch_compare_and_exchange_val, int, mem, new, old, \ ++ __MB, "") ++ ++/* Atomically store value and return the previous value. */ ++ ++#define __arch_exchange_8_int(mem, value, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __addr64, __sval, __tmp1; \ ++ __typeof (*mem) __ret; \ ++ __asm__ __volatile__( \ ++ mb1 " bic %[__addr8],7,%[__addr64]\n" \ ++ " ins0b %[__value],%[__addr8],%[__sval]\n" \ ++ "1: lldl %[__tmp],0(%[__addr64])\n" \ ++ " ldi %[__tmp1],1\n" \ ++ " wr_f %[__tmp1]\n" \ ++ " ext0b %[__tmp],%[__addr8],%[__ret]\n" \ ++ " mask0b %[__tmp],%[__addr8],%[__tmp]\n" \ ++ " or %[__sval],%[__tmp],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr64])\n" \ ++ " rd_f %[__tmp]\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__sval] "=&r"(__sval), [__tmp] "=&r"(__tmp), \ ++ [__tmp1] "=&r"(__tmp1), [__addr64] "=&r"(__addr64) \ ++ : [__addr8] "r"(mem), [__value] "r"(value) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++ ++#define __arch_exchange_16_int(mem, value, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __addr64, __sval, __tmp1; \ ++ __typeof (*mem) __ret; \ ++ __asm__ __volatile__( \ ++ mb1 " bic %[__addr16],7,%[__addr64]\n" \ ++ " ins1b %[__value],%[__addr16],%[__sval]\n" \ ++ "1: lldl %[__tmp],0(%[__addr64])\n" \ ++ " ldi %[__tmp1],1\n" \ ++ " wr_f %[__tmp1]\n" \ ++ " ext1b %[__tmp],%[__addr16],%[__ret]\n" \ ++ " mask1b %[__tmp],%[__addr16],%[__tmp]\n" \ ++ " or %[__sval],%[__tmp],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr64])\n" \ ++ " rd_f %[__tmp]\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__sval] "=&r"(__sval), [__tmp] "=&r"(__tmp), \ ++ [__tmp1] "=&r"(__tmp1), [__addr64] "=&r"(__addr64) \ ++ : [__addr16] "r"(mem), [__value] "r"(value) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++#define __arch_exchange_32_int(mem, value, mb1, mb2) \ ++ ({ \ ++ signed int __tmp; \ ++ __typeof (*mem) __ret; \ ++ unsigned long __addr; \ ++ __asm__ __volatile__( \ ++ mb1 " ldi %[__addr],%[__mem]\n" \ ++ "1: lldw %[__ret],0(%[__addr])\n" \ ++ " ldi %[__tmp],1\n" \ ++ " wr_f %[__tmp]\n" \ ++ " mov %[__val],%[__tmp]\n" \ ++ " lstw %[__tmp],0(%[__addr])\n" \ ++ " rd_f %[__tmp]\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__tmp] "=&r"(__tmp), [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), [__val] "Ir"(value) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++ ++#define __arch_exchange_64_int(mem, value, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __addr; \ ++ __typeof (*mem) __ret; \ ++ __asm__ __volatile__( \ ++ mb1 " ldi %[__addr],%[__mem]\n" \ ++ "1: lldl %[__ret],0(%[__addr])\n" \ ++ " ldi %[__tmp],1\n" \ ++ " wr_f %[__tmp]\n" \ ++ " mov %[__val],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr])\n" \ ++ " rd_f %[__tmp]\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__tmp] "=&r"(__tmp), [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), [__val] "Ir"(value) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++ ++#define atomic_exchange_acq(mem, value) \ ++ __atomic_val_bysize (__arch_exchange, int, mem, value, "", __MB) ++ ++#define atomic_exchange_rel(mem, value) \ ++ __atomic_val_bysize (__arch_exchange, int, mem, value, __MB, "") ++ ++/* Atomically add value and return the previous (unincremented) value. */ ++ ++#define __arch_exchange_and_add_8_int(mem, value, mb1, mb2) \ ++ ({ \ ++ __builtin_trap (); \ ++ 0; \ ++ }) ++ ++#define __arch_exchange_and_add_16_int(mem, value, mb1, mb2) \ ++ ({ \ ++ __builtin_trap (); \ ++ 0; \ ++ }) ++ ++#define __arch_exchange_and_add_32_int(mem, value, mb1, mb2) \ ++ ({ \ ++ signed int __tmp; \ ++ __typeof (*mem) __ret; \ ++ unsigned long __addr; \ ++ __asm__ __volatile__( \ ++ mb1 " ldi %[__addr],%[__mem]\n" \ ++ "1: lldw %[__ret],0(%[__addr])\n" \ ++ " ldi %[__tmp],1\n" \ ++ " wr_f %[__tmp]\n" \ ++ " addw %[__ret],%[__val],%[__tmp]\n" \ ++ " lstw %[__tmp],0(%[__addr])\n" \ ++ " rd_f %[__tmp]\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__tmp] "=&r"(__tmp), [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), [__val] "Ir"((signed int) (value)) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++ ++#define __arch_exchange_and_add_64_int(mem, value, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __addr; \ ++ __typeof (*mem) __ret; \ ++ __asm__ __volatile__( \ ++ mb1 " ldi %[__addr],%[__mem]\n" \ ++ "1: lldl %[__ret],0(%[__addr])\n" \ ++ " ldi %[__tmp],1\n" \ ++ " wr_f %[__tmp]\n" \ ++ " addl %[__ret],%[__val],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr])\n" \ ++ " rd_f %[__tmp]\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__tmp] "=&r"(__tmp), [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), [__val] "Ir"((unsigned long) (value)) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++ ++/* ??? Barrier semantics for atomic_exchange_and_add appear to be ++ undefined. Use full barrier for now, as that's safe. */ ++#define atomic_exchange_and_add(mem, value) \ ++ __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, __MB, __MB) ++ ++/* ??? Blah, I'm lazy. Implement these later. Can do better than the ++ compare-and-exchange loop provided by generic code. ++ ++#define atomic_decrement_if_positive(mem) ++#define atomic_bit_test_set(mem, bit) ++ ++*/ ++#define atomic_full_barrier() __asm("memb" : : : "memory"); ++#define atomic_read_barrier() __asm("memb" : : : "memory"); ++#define atomic_write_barrier() __asm("memb" : : : "memory"); +diff --git a/sysdeps/sw_64/nptl/bits/struct_rwlock.h b/sysdeps/sw_64/nptl/bits/struct_rwlock.h +new file mode 100644 +index 00000000..8cbeefc1 +--- /dev/null ++++ b/sysdeps/sw_64/nptl/bits/struct_rwlock.h +@@ -0,0 +1,43 @@ ++/* Sw_64 internal rwlock struct definitions. ++ Copyright (C) 2019-2023 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 _RWLOCK_INTERNAL_H ++#define _RWLOCK_INTERNAL_H ++ ++struct __pthread_rwlock_arch_t ++{ ++ unsigned int __readers; ++ unsigned int __writers; ++ unsigned int __wrphase_futex; ++ unsigned int __writers_futex; ++ unsigned int __pad3; ++ unsigned int __pad4; ++ int __cur_writer; ++ int __shared; ++ unsigned long int __pad1; ++ unsigned long int __pad2; ++ /* FLAGS must stay at this position in the structure to maintain ++ binary compatibility. */ ++ unsigned int __flags; ++}; ++ ++#define __PTHREAD_RWLOCK_INITIALIZER(__flags) \ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags ++ ++#endif +diff --git a/sysdeps/sw_64/nptl/pthread_spin_lock.S b/sysdeps/sw_64/nptl/pthread_spin_lock.S +new file mode 100644 +index 00000000..b7e44839 +--- /dev/null ++++ b/sysdeps/sw_64/nptl/pthread_spin_lock.S +@@ -0,0 +1,55 @@ ++/* Copyright (C) 2003-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson , 2003. ++ ++ 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 ++ ++ .text ++ .align 4 ++ ++ .globl __pthread_spin_lock ++ .ent __pthread_spin_lock ++__pthread_spin_lock: ++ .frame $sp, 0, $26, 0 ++ .prologue 0 ++ ++ memb ++0: lldw $1, 0($16) ++ xor $1, 1, $1 ++ ldi $0, 0 ++ wr_f $1 ++ ++ ldi $2, 1 ++ lstw $2, 0($16) ++ rd_f $2 ++ beq $2, 1f ++ ret ++ ++1: ldw $1, 0($16) ++ bne $1, 1b ++ unop ++ br 0b ++ ++ ++ ++ ++ .end __pthread_spin_lock ++versioned_symbol (libc, __pthread_spin_lock, pthread_spin_lock, GLIBC_2_34) ++ ++#if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_2, GLIBC_2_34) ++compat_symbol (libpthread, __pthread_spin_lock, pthread_spin_lock, GLIBC_2_2) ++#endif +diff --git a/sysdeps/sw_64/nptl/pthread_spin_trylock.S b/sysdeps/sw_64/nptl/pthread_spin_trylock.S +new file mode 100644 +index 00000000..8551c34a +--- /dev/null ++++ b/sysdeps/sw_64/nptl/pthread_spin_trylock.S +@@ -0,0 +1,56 @@ ++/* Copyright (C) 2003-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson , 2003. ++ ++ 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 ++ ++#define _ERRNO_H 1 ++#include ++ ++ .text ++ .align 4 ++ ++ .globl __pthread_spin_trylock ++ .ent __pthread_spin_trylock ++__pthread_spin_trylock: ++ .frame $sp, 0, $26, 0 ++ .prologue 0 ++ ++ memb ++0: lldw $1, 0($16) ++ xor $1, 1, $1 ++ ldi $2, 1 ++ ldi $0, EBUSY ++ wr_f $1 ++ ++ lstw $2, 0($16) ++ rd_f $2 ++ beq $1, 1f ++ beq $2, 2f ++ ldi $0, 0 ++ ++1: ret ++2: br 0b ++ ++ .end __pthread_spin_trylock ++versioned_symbol (libc, __pthread_spin_trylock, pthread_spin_trylock, ++ GLIBC_2_34) ++ ++#if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_2, GLIBC_2_34) ++compat_symbol (libpthread, __pthread_spin_trylock, pthread_spin_trylock, ++ GLIBC_2_2) ++#endif +diff --git a/sysdeps/sw_64/sw8a/atomic-machine.h b/sysdeps/sw_64/sw8a/atomic-machine.h +new file mode 100644 +index 00000000..db3320fc +--- /dev/null ++++ b/sysdeps/sw_64/sw8a/atomic-machine.h +@@ -0,0 +1,371 @@ ++/* Copyright (C) 2003-2023 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 ++ ++typedef int8_t atomic8_t; ++typedef uint8_t uatomic8_t; ++typedef int_fast8_t atomic_fast8_t; ++typedef uint_fast8_t uatomic_fast8_t; ++ ++typedef int16_t atomic16_t; ++typedef uint16_t uatomic16_t; ++typedef int_fast16_t atomic_fast16_t; ++typedef uint_fast16_t uatomic_fast16_t; ++ ++typedef int32_t atomic32_t; ++typedef uint32_t uatomic32_t; ++typedef int_fast32_t atomic_fast32_t; ++typedef uint_fast32_t uatomic_fast32_t; ++ ++typedef int64_t atomic64_t; ++typedef uint64_t uatomic64_t; ++typedef int_fast64_t atomic_fast64_t; ++typedef uint_fast64_t uatomic_fast64_t; ++ ++typedef intptr_t atomicptr_t; ++typedef uintptr_t uatomicptr_t; ++typedef intmax_t atomic_max_t; ++typedef uintmax_t uatomic_max_t; ++ ++#define __HAVE_64B_ATOMICS 1 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ ++/* XXX Is this actually correct? */ ++#define ATOMIC_EXCHANGE_USES_CAS 1 ++ ++#ifdef UP ++# define __MB /* nothing */ ++#else ++# define __MB " memb\n" ++#endif ++ ++/* Compare and exchange. For all of the "xxx" routines, we expect a ++ "__prev" and a "__cmp" variable to be provided by the enclosing scope, ++ in which values are returned. */ ++// delete memb after the rd_f ++#define __arch_compare_and_exchange_xxx_8_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __snew, __addr64; \ ++ __asm__ __volatile__( \ ++ " bic %[__addr8],7,%[__addr64]\n" \ ++ " inslb %[__new],%[__addr8],%[__snew]\n" \ ++ "1: lldl %[__tmp],0(%[__addr64])\n" \ ++ " extlb %[__tmp],%[__addr8],%[__prev]\n" \ ++ " cmpeq %[__prev],%[__old],%[__cmp]\n" \ ++ " beq %[__cmp],2f\n" \ ++ " masklb %[__tmp],%[__addr8],%[__tmp]\n" \ ++ " or %[__snew],%[__tmp],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr64])\n" \ ++ " beq %[__tmp],1b\n" \ ++ "2:" \ ++ : [__prev] "=&r"(__prev), [__snew] "=&r"(__snew), \ ++ [__tmp] "=&r"(__tmp), [__cmp] "=&r"(__cmp), \ ++ [__addr64] "=&r"(__addr64) \ ++ : [__addr8] "r"(mem), \ ++ [__old] "Ir"((uint64_t) (uint8_t) (uint64_t) (old)), \ ++ [__new] "r"(new) \ ++ : "memory"); \ ++ }) ++ ++#define __arch_compare_and_exchange_xxx_16_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __snew, __addr64; \ ++ __asm__ __volatile__( \ ++ " bic %[__addr16],7,%[__addr64]\n" \ ++ " inslh %[__new],%[__addr16],%[__snew]\n" \ ++ "1: lldl %[__tmp],0(%[__addr64])\n" \ ++ " extlh %[__tmp],%[__addr16],%[__prev]\n" \ ++ " cmpeq %[__prev],%[__old],%[__cmp]\n" \ ++ " beq %[__cmp],2f\n" \ ++ " masklh %[__tmp],%[__addr16],%[__tmp]\n" \ ++ " or %[__snew],%[__tmp],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr64])\n" \ ++ " beq %[__tmp],1b\n" \ ++ "2:" \ ++ : [__prev] "=&r"(__prev), [__snew] "=&r"(__snew), \ ++ [__tmp] "=&r"(__tmp), [__cmp] "=&r"(__cmp), \ ++ [__addr64] "=&r"(__addr64) \ ++ : [__addr16] "r"(mem), \ ++ [__old] "Ir"((uint64_t) (uint16_t) (uint64_t) (old)), \ ++ [__new] "r"(new) \ ++ : "memory"); \ ++ }) ++#define __arch_compare_and_exchange_xxx_32_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __addr; \ ++ __asm__ __volatile__( \ ++ " ldi %[__addr],%[__mem]\n" \ ++ "1: lldw %[__prev],0(%[__addr])\n" \ ++ " cmpeq %[__prev],%[__old],%[__cmp]\n" \ ++ " beq %[__cmp],2f\n" \ ++ " mov %[__new],%[__cmp]\n" \ ++ " lstw %[__cmp],0(%[__addr])\n" \ ++ " beq %[__cmp],1b\n" \ ++ "2:" \ ++ : \ ++ [__prev] "=&r"(__prev), [__cmp] "=&r"(__cmp), [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), \ ++ [__old] "Ir"((uint64_t) (atomic32_t) (uint64_t) (old)), \ ++ [__new] "Ir"(new) \ ++ : "memory"); \ ++ }) ++ ++#define __arch_compare_and_exchange_xxx_64_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __addr; \ ++ __asm__ __volatile__(" ldi %[__addr],%[__mem]\n" \ ++ "1: lldl %[__prev],0(%[__addr])\n" \ ++ " cmpeq %[__prev],%[__old],%[__cmp]\n" \ ++ " beq %[__cmp],2f\n" \ ++ " mov %[__new],%[__cmp]\n" \ ++ " lstl %[__cmp],0(%[__addr])\n" \ ++ " beq %[__cmp],1b\n" \ ++ "2:" \ ++ : [__prev] "=&r"(__prev), [__cmp] "=&r"(__cmp), \ ++ [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), \ ++ [__old] "Ir"((uint64_t) (old)), [__new] "Ir"(new) \ ++ : "memory"); \ ++ }) ++/* For all "bool" routines, we return FALSE if exchange succesful. */ ++ ++#define __arch_compare_and_exchange_bool_8_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_8_int (mem, new, old, mb1, mb2); \ ++ !__cmp; \ ++ }) ++ ++#define __arch_compare_and_exchange_bool_16_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_16_int (mem, new, old, mb1, mb2); \ ++ !__cmp; \ ++ }) ++ ++#define __arch_compare_and_exchange_bool_32_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_32_int (mem, new, old, mb1, mb2); \ ++ !__cmp; \ ++ }) ++ ++#define __arch_compare_and_exchange_bool_64_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_64_int (mem, new, old, mb1, mb2); \ ++ !__cmp; \ ++ }) ++ ++/* For all "val" routines, return the old value whether exchange ++ successful or not. */ ++ ++#define __arch_compare_and_exchange_val_8_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_8_int (mem, new, old, mb1, mb2); \ ++ (typeof (*mem)) __prev; \ ++ }) ++ ++#define __arch_compare_and_exchange_val_16_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_16_int (mem, new, old, mb1, mb2); \ ++ (typeof (*mem)) __prev; \ ++ }) ++ ++#define __arch_compare_and_exchange_val_32_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_32_int (mem, new, old, mb1, mb2); \ ++ (typeof (*mem)) __prev; \ ++ }) ++ ++#define __arch_compare_and_exchange_val_64_int(mem, new, old, mb1, mb2) \ ++ ({ \ ++ unsigned long __prev; \ ++ int __cmp; \ ++ __arch_compare_and_exchange_xxx_64_int (mem, new, old, mb1, mb2); \ ++ (typeof (*mem)) __prev; \ ++ }) ++ ++/* Compare and exchange with "acquire" semantics, ie barrier after. */ ++ ++#define atomic_compare_and_exchange_bool_acq(mem, new, old) \ ++ __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, mem, new, old, \ ++ "", __MB) ++ ++#define atomic_compare_and_exchange_val_acq(mem, new, old) \ ++ __atomic_val_bysize (__arch_compare_and_exchange_val, int, mem, new, old, \ ++ "", __MB) ++ ++/* Compare and exchange with "release" semantics, ie barrier before. */ ++ ++#define atomic_compare_and_exchange_val_rel(mem, new, old) \ ++ __atomic_val_bysize (__arch_compare_and_exchange_val, int, mem, new, old, \ ++ __MB, "") ++ ++/* Atomically store value and return the previous value. */ ++ ++#define __arch_exchange_8_int(mem, value, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __addr64, __sval; \ ++ __typeof (*mem) __ret; \ ++ __asm__ __volatile__(" bic %[__addr8],7,%[__addr64]\n" \ ++ " inslb %[__value],%[__addr8],%[__sval]\n" \ ++ "1: lldl %[__tmp],0(%[__addr64])\n" \ ++ " extlb %[__tmp],%[__addr8],%[__ret]\n" \ ++ " masklb %[__tmp],%[__addr8],%[__tmp]\n" \ ++ " or %[__sval],%[__tmp],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr64])\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__sval] "=&r"(__sval), \ ++ [__tmp] "=&r"(__tmp), [__addr64] "=&r"(__addr64) \ ++ : [__addr8] "r"(mem), [__value] "r"(value) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++ ++#define __arch_exchange_16_int(mem, value, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __addr64, __sval; \ ++ __typeof (*mem) __ret; \ ++ __asm__ __volatile__(" bic %[__addr16],7,%[__addr64]\n" \ ++ " inslh %[__value],%[__addr16],%[__sval]\n" \ ++ "1: lldl %[__tmp],0(%[__addr64])\n" \ ++ " extlh %[__tmp],%[__addr16],%[__ret]\n" \ ++ " masklh %[__tmp],%[__addr16],%[__tmp]\n" \ ++ " or %[__sval],%[__tmp],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr64])\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__sval] "=&r"(__sval), \ ++ [__tmp] "=&r"(__tmp), [__addr64] "=&r"(__addr64) \ ++ : [__addr16] "r"(mem), [__value] "r"(value) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++#define __arch_exchange_32_int(mem, value, mb1, mb2) \ ++ ({ \ ++ signed int __tmp; \ ++ __typeof (*mem) __ret; \ ++ unsigned long __addr; \ ++ __asm__ __volatile__( \ ++ " ldi %[__addr],%[__mem]\n" \ ++ "1: lldw %[__ret],0(%[__addr])\n" \ ++ " mov %[__val],%[__tmp]\n" \ ++ " lstw %[__tmp],0(%[__addr])\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__tmp] "=&r"(__tmp), [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), [__val] "Ir"(value) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++ ++#define __arch_exchange_64_int(mem, value, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __addr; \ ++ __typeof (*mem) __ret; \ ++ __asm__ __volatile__( \ ++ " ldi %[__addr],%[__mem]\n" \ ++ "1: lldl %[__ret],0(%[__addr])\n" \ ++ " mov %[__val],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr])\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__tmp] "=&r"(__tmp), [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), [__val] "Ir"(value) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++ ++#define atomic_exchange_acq(mem, value) \ ++ __atomic_val_bysize (__arch_exchange, int, mem, value, "", __MB) ++ ++#define atomic_exchange_rel(mem, value) \ ++ __atomic_val_bysize (__arch_exchange, int, mem, value, __MB, "") ++ ++/* Atomically add value and return the previous (unincremented) value. */ ++ ++#define __arch_exchange_and_add_8_int(mem, value, mb1, mb2) \ ++ ({ \ ++ __builtin_trap (); \ ++ 0; \ ++ }) ++ ++#define __arch_exchange_and_add_16_int(mem, value, mb1, mb2) \ ++ ({ \ ++ __builtin_trap (); \ ++ 0; \ ++ }) ++ ++#define __arch_exchange_and_add_32_int(mem, value, mb1, mb2) \ ++ ({ \ ++ signed int __tmp; \ ++ __typeof (*mem) __ret; \ ++ unsigned long __addr; \ ++ __asm__ __volatile__( \ ++ " ldi %[__addr],%[__mem]\n" \ ++ "1: lldw %[__ret],0(%[__addr])\n" \ ++ " addw %[__ret],%[__val],%[__tmp]\n" \ ++ " lstw %[__tmp],0(%[__addr])\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__tmp] "=&r"(__tmp), [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), [__val] "Ir"((signed int) (value)) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++ ++#define __arch_exchange_and_add_64_int(mem, value, mb1, mb2) \ ++ ({ \ ++ unsigned long __tmp, __addr; \ ++ __typeof (*mem) __ret; \ ++ __asm__ __volatile__( \ ++ " ldi %[__addr],%[__mem]\n" \ ++ "1: lldl %[__ret],0(%[__addr])\n" \ ++ " addl %[__ret],%[__val],%[__tmp]\n" \ ++ " lstl %[__tmp],0(%[__addr])\n" \ ++ " beq %[__tmp],1b\n" \ ++ : [__ret] "=&r"(__ret), [__tmp] "=&r"(__tmp), [__addr] "=&r"(__addr) \ ++ : [__mem] "m"(*(mem)), [__val] "Ir"((unsigned long) (value)) \ ++ : "memory"); \ ++ __ret; \ ++ }) ++ ++/* ??? Barrier semantics for atomic_exchange_and_add appear to be ++ undefined. Use full barrier for now, as that's safe. */ ++#define atomic_exchange_and_add(mem, value) \ ++ __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, __MB, __MB) ++ ++/* ??? Blah, I'm lazy. Implement these later. Can do better than the ++ compare-and-exchange loop provided by generic code. ++ ++#define atomic_decrement_if_positive(mem) ++#define atomic_bit_test_set(mem, bit) ++ ++*/ ++# ifndef UP ++# define atomic_full_barrier() __asm ("memb" : : : "memory"); ++# define atomic_read_barrier() __asm ("memb" : : : "memory"); ++# define atomic_write_barrier() __asm ("memb" : : : "memory"); ++# endif +diff --git a/sysdeps/sw_64/sw8a/nptl/bits/struct_rwlock.h b/sysdeps/sw_64/sw8a/nptl/bits/struct_rwlock.h +new file mode 100644 +index 00000000..8cbeefc1 +--- /dev/null ++++ b/sysdeps/sw_64/sw8a/nptl/bits/struct_rwlock.h +@@ -0,0 +1,43 @@ ++/* Sw_64 internal rwlock struct definitions. ++ Copyright (C) 2019-2023 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 _RWLOCK_INTERNAL_H ++#define _RWLOCK_INTERNAL_H ++ ++struct __pthread_rwlock_arch_t ++{ ++ unsigned int __readers; ++ unsigned int __writers; ++ unsigned int __wrphase_futex; ++ unsigned int __writers_futex; ++ unsigned int __pad3; ++ unsigned int __pad4; ++ int __cur_writer; ++ int __shared; ++ unsigned long int __pad1; ++ unsigned long int __pad2; ++ /* FLAGS must stay at this position in the structure to maintain ++ binary compatibility. */ ++ unsigned int __flags; ++}; ++ ++#define __PTHREAD_RWLOCK_INITIALIZER(__flags) \ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags ++ ++#endif +diff --git a/sysdeps/sw_64/sw8a/nptl/pthread_spin_lock.S b/sysdeps/sw_64/sw8a/nptl/pthread_spin_lock.S +new file mode 100644 +index 00000000..ab3408a3 +--- /dev/null ++++ b/sysdeps/sw_64/sw8a/nptl/pthread_spin_lock.S +@@ -0,0 +1,43 @@ ++ ++ ++/* Copyright (C) 2003-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson , 2003. ++ ++ 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 ++ . */ ++ ++/* SHIPS20171102_LOCK_READ_CONDITION_WRITE. */ ++ .text ++ .align 4 ++ ++ .globl pthread_spin_lock ++ .ent pthread_spin_lock ++pthread_spin_lock: ++ .frame $sp, 0, $26, 0 ++ .prologue 0 ++0: lldw $1, 0($16) ++ ldi $2, 1 ++ ldi $0, 0 ++ bne $1, 1f ++ ++ lstw $2, 0($16) ++ beq $2, 1f ++ ret ++ ++1: ldw $1, 0($16) ++ bne $1, 1b ++ unop ++ br 0b ++ .end pthread_spin_lock +diff --git a/sysdeps/sw_64/sw8a/nptl/pthread_spin_trylock.S b/sysdeps/sw_64/sw8a/nptl/pthread_spin_trylock.S +new file mode 100644 +index 00000000..374dccae +--- /dev/null ++++ b/sysdeps/sw_64/sw8a/nptl/pthread_spin_trylock.S +@@ -0,0 +1,44 @@ ++ ++ ++/* Copyright (C) 2003-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson , 2003. ++ ++ 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 ++ . */ ++ ++/* SHIPS20171102_LOCK_READ_CONDITION_WRITE. */ ++#define _ERRNO_H 1 ++#include ++ ++ .text ++ .align 4 ++ ++ .globl pthread_spin_trylock ++ .ent pthread_spin_trylock ++pthread_spin_trylock: ++ .frame $sp, 0, $26, 0 ++ .prologue 0 ++0: lldw $1, 0($16) ++ ldi $2, 1 ++ ldi $0, EBUSY ++ bne $1, 1f ++ ++ lstw $2, 0($16) ++ beq $2, 2f ++ ldi $0, 0 ++ ++1: ret ++2: br 0b ++ .end pthread_spin_trylock +-- +2.25.1 + diff --git a/0007-Sw64-Linux-Syscall-Interface.patch b/0007-Sw64-Linux-Syscall-Interface.patch new file mode 100644 index 0000000..f89245d --- /dev/null +++ b/0007-Sw64-Linux-Syscall-Interface.patch @@ -0,0 +1,1143 @@ +From a48f11d0af793110f1a5289967bcb45a188058c3 Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Fri, 29 Nov 2024 14:04:40 +0800 +Subject: [PATCH 07/23] Sw64: Linux Syscall Interface + +--- + sysdeps/unix/sw_64/Makefile | 4 + + sysdeps/unix/sw_64/pipe.S | 31 ++ + sysdeps/unix/sw_64/rt-sysdep.S | 1 + + sysdeps/unix/sw_64/sysdep.S | 65 ++++ + sysdeps/unix/sysv/linux/sw_64/arch-syscall.h | 376 +++++++++++++++++++ + sysdeps/unix/sysv/linux/sw_64/clone.S | 117 ++++++ + sysdeps/unix/sysv/linux/sw_64/syscall.S | 70 ++++ + sysdeps/unix/sysv/linux/sw_64/sysdep.h | 355 +++++++++++++++++ + sysdeps/unix/sysv/linux/sw_64/vfork.S | 41 ++ + 9 files changed, 1060 insertions(+) + create mode 100644 sysdeps/unix/sw_64/Makefile + create mode 100644 sysdeps/unix/sw_64/pipe.S + create mode 100644 sysdeps/unix/sw_64/rt-sysdep.S + create mode 100644 sysdeps/unix/sw_64/sysdep.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/arch-syscall.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/clone.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/syscall.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/sysdep.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/vfork.S + +diff --git a/sysdeps/unix/sw_64/Makefile b/sysdeps/unix/sw_64/Makefile +new file mode 100644 +index 00000000..0660847f +--- /dev/null ++++ b/sysdeps/unix/sw_64/Makefile +@@ -0,0 +1,4 @@ ++ifeq ($(subdir),rt) ++librt-sysdep_routines += rt-sysdep ++librt-shared-only-routines += rt-sysdep ++endif +diff --git a/sysdeps/unix/sw_64/pipe.S b/sysdeps/unix/sw_64/pipe.S +new file mode 100644 +index 00000000..d851fe17 +--- /dev/null ++++ b/sysdeps/unix/sw_64/pipe.S +@@ -0,0 +1,31 @@ ++/* Copyright (C) 1993-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by David Mosberger (davidm@cs.arizona.edu). ++ ++ 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 ++ . */ ++ ++/* __pipe is a special syscall since it returns two values. */ ++ ++#include ++ ++PSEUDO (__pipe, pipe, 0) ++ stw r0, 0(a0) ++ stw r1, 4(a0) ++ mov zero, v0 ++ ret ++PSEUDO_END(__pipe) ++ ++libc_hidden_def (__pipe) ++weak_alias (__pipe, pipe) +diff --git a/sysdeps/unix/sw_64/rt-sysdep.S b/sysdeps/unix/sw_64/rt-sysdep.S +new file mode 100644 +index 00000000..f966bf1e +--- /dev/null ++++ b/sysdeps/unix/sw_64/rt-sysdep.S +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/unix/sw_64/sysdep.S b/sysdeps/unix/sw_64/sysdep.S +new file mode 100644 +index 00000000..306184c3 +--- /dev/null ++++ b/sysdeps/unix/sw_64/sysdep.S +@@ -0,0 +1,65 @@ ++/* Copyright (C) 1993-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Brendan Kehoe (brendan@zen.org). ++ ++ 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 ++ ++#if defined(PIC) ++ /* Put this at the end of libc's text segment so that all of ++ the direct branches from the syscalls are forward, and ++ thus predicted not taken. */ ++ .section .text.last, "ax", @progbits ++#else ++ .text ++#endif ++ ++#if IS_IN (libc) ++# define SYSCALL_ERROR_ERRNO __libc_errno ++#else ++# define SYSCALL_ERROR_ERRNO errno ++#endif ++ ++ .align 4 ++ .globl __syscall_error ++ .ent __syscall_error ++__syscall_error: ++ /* When building a shared library, we branch here without having ++ loaded the GP. Nor, since it was a direct branch, have we ++ loaded PV with our address. ++ ++ When building a static library, we tail call here from another ++ object file, possibly with a different GP, and must return with ++ the GP of our caller in place so that linker relaxation works. ++ ++ Both issues are solved by computing the GP into T1 instead of ++ clobbering the traditional GP register. */ ++ .prologue 0 ++ mov v0, t0 ++ br t1, 1f ++1: ldih t1, 0(t1) !gpdisp!1 ++ sys_call HMC_rdunique ++ ++ ldi t1, 0(t1) !gpdisp!1 ++ ldl t1, SYSCALL_ERROR_ERRNO(t1) !gottprel ++ addl v0, t1, t1 ++ ldi v0, -1 ++ ++ stw t0, 0(t1) ++ ret ++ ++ .end __syscall_error +diff --git a/sysdeps/unix/sysv/linux/sw_64/arch-syscall.h b/sysdeps/unix/sysv/linux/sw_64/arch-syscall.h +new file mode 100644 +index 00000000..62597a14 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/arch-syscall.h +@@ -0,0 +1,376 @@ ++/* AUTOGENERATED by update-syscall-lists.py. */ ++#define __NR_accept 99 ++#define __NR_accept4 502 ++#define __NR_access 33 ++#define __NR_acct 51 ++#define __NR_add_key 439 ++#define __NR_adjtimex 366 ++#define __NR_afs_syscall 338 ++#define __NR_bdflush 300 ++#define __NR_bind 104 ++#define __NR_bpf 170 ++#define __NR_brk 17 ++#define __NR_cachestat 190 ++#define __NR_capget 368 ++#define __NR_capset 369 ++#define __NR_chdir 12 ++#define __NR_chmod 15 ++#define __NR_chown 16 ++#define __NR_chroot 61 ++#define __NR_clock_adjtime 499 ++#define __NR_clock_getres 421 ++#define __NR_clock_gettime 420 ++#define __NR_clock_nanosleep 422 ++#define __NR_clock_settime 419 ++#define __NR_clone 312 ++#define __NR_clone3 282 ++#define __NR_close 6 ++#define __NR_close_range 283 ++#define __NR_connect 98 ++#define __NR_copy_file_range 515 ++#define __NR_create_module 306 ++#define __NR_delete_module 308 ++#define __NR_dipc 373 ++#define __NR_dup 41 ++#define __NR_dup2 90 ++#define __NR_dup3 487 ++#define __NR_epoll_create 407 ++#define __NR_epoll_create1 486 ++#define __NR_epoll_ctl 408 ++#define __NR_epoll_pwait 474 ++#define __NR_epoll_pwait2 180 ++#define __NR_epoll_wait 409 ++#define __NR_eventfd 478 ++#define __NR_eventfd2 485 ++#define __NR_execve 59 ++#define __NR_execveat 513 ++#define __NR_exit 1 ++#define __NR_exit_group 405 ++#define __NR_faccessat 462 ++#define __NR_faccessat2 286 ++#define __NR_fadvise64 413 ++#define __NR_fallocate 480 ++#define __NR_fanotify_init 494 ++#define __NR_fanotify_mark 495 ++#define __NR_fchdir 13 ++#define __NR_fchmod 124 ++#define __NR_fchmodat 461 ++#define __NR_fchmodat2 191 ++#define __NR_fchown 123 ++#define __NR_fchownat 453 ++#define __NR_fcntl 92 ++#define __NR_fdatasync 447 ++#define __NR_fgetxattr 387 ++#define __NR_finit_module 507 ++#define __NR_flistxattr 390 ++#define __NR_flock 131 ++#define __NR_fork 2 ++#define __NR_fremovexattr 393 ++#define __NR_fsconfig 278 ++#define __NR_fsetxattr 384 ++#define __NR_fsmount 279 ++#define __NR_fsopen 277 ++#define __NR_fspick 280 ++#define __NR_fstat 91 ++#define __NR_fstat64 427 ++#define __NR_fstatat64 455 ++#define __NR_fstatfs 329 ++#define __NR_fstatfs64 230 ++#define __NR_fsync 95 ++#define __NR_ftruncate 130 ++#define __NR_futex 394 ++#define __NR_futex_waitv 188 ++#define __NR_futimesat 454 ++#define __NR_get_kernel_syms 309 ++#define __NR_get_mempolicy 430 ++#define __NR_get_robust_list 467 ++#define __NR_getcpu 473 ++#define __NR_getcwd 367 ++#define __NR_getdents 305 ++#define __NR_getdents64 377 ++#define __NR_getegid 179 ++#define __NR_geteuid 177 ++#define __NR_getgid 178 ++#define __NR_getgroups 79 ++#define __NR_gethostname 87 ++#define __NR_getitimer 361 ++#define __NR_getpeername 141 ++#define __NR_getpgid 233 ++#define __NR_getpgrp 63 ++#define __NR_getpid 174 ++#define __NR_getppid 175 ++#define __NR_getpriority 298 ++#define __NR_getrandom 511 ++#define __NR_getresgid 372 ++#define __NR_getresuid 344 ++#define __NR_getrlimit 144 ++#define __NR_getrusage 364 ++#define __NR_getsid 234 ++#define __NR_getsockname 150 ++#define __NR_getsockopt 118 ++#define __NR_getsysinfo 256 ++#define __NR_gettid 378 ++#define __NR_gettimeofday 359 ++#define __NR_getuid 176 ++#define __NR_getxattr 385 ++#define __NR_getxgid 47 ++#define __NR_getxpid 20 ++#define __NR_getxuid 24 ++#define __NR_init_module 307 ++#define __NR_inotify_add_watch 445 ++#define __NR_inotify_init 444 ++#define __NR_inotify_init1 489 ++#define __NR_inotify_rm_watch 446 ++#define __NR_io_cancel 402 ++#define __NR_io_destroy 399 ++#define __NR_io_getevents 400 ++#define __NR_io_pgetevents 403 ++#define __NR_io_setup 398 ++#define __NR_io_submit 401 ++#define __NR_io_uring_enter 273 ++#define __NR_io_uring_register 274 ++#define __NR_io_uring_setup 272 ++#define __NR_ioctl 54 ++#define __NR_ioprio_get 443 ++#define __NR_ioprio_set 442 ++#define __NR_kcmp 506 ++#define __NR_kexec_load 448 ++#define __NR_keyctl 441 ++#define __NR_kill 37 ++#define __NR_landlock_add_rule 184 ++#define __NR_landlock_create_ruleset 183 ++#define __NR_landlock_restrict_self 185 ++#define __NR_lchown 208 ++#define __NR_lgetxattr 386 ++#define __NR_link 9 ++#define __NR_linkat 458 ++#define __NR_listen 106 ++#define __NR_listxattr 388 ++#define __NR_llistxattr 389 ++#define __NR_lookup_dcookie 406 ++#define __NR_lremovexattr 392 ++#define __NR_lseek 19 ++#define __NR_lsetxattr 383 ++#define __NR_lstat 68 ++#define __NR_lstat64 426 ++#define __NR_madvise 75 ++#define __NR_mbind 429 ++#define __NR_membarrier 172 ++#define __NR_memfd_create 512 ++#define __NR_migrate_pages 449 ++#define __NR_mincore 375 ++#define __NR_mkdir 136 ++#define __NR_mkdirat 451 ++#define __NR_mknod 14 ++#define __NR_mknodat 452 ++#define __NR_mlock 314 ++#define __NR_mlock2 173 ++#define __NR_mlockall 316 ++#define __NR_mmap 71 ++#define __NR_mount 302 ++#define __NR_mount_setattr 181 ++#define __NR_move_mount 276 ++#define __NR_move_pages 472 ++#define __NR_mprotect 74 ++#define __NR_mq_getsetattr 437 ++#define __NR_mq_notify 436 ++#define __NR_mq_open 432 ++#define __NR_mq_timedreceive 435 ++#define __NR_mq_timedsend 434 ++#define __NR_mq_unlink 433 ++#define __NR_mremap 341 ++#define __NR_msgctl 200 ++#define __NR_msgget 201 ++#define __NR_msgrcv 202 ++#define __NR_msgsnd 203 ++#define __NR_msync 217 ++#define __NR_munlock 315 ++#define __NR_munlockall 317 ++#define __NR_munmap 73 ++#define __NR_name_to_handle_at 497 ++#define __NR_nanosleep 340 ++#define __NR_nfsservctl 342 ++#define __NR_odd_getpriority 100 ++#define __NR_odd_sigprocmask 48 ++#define __NR_oldumount 321 ++#define __NR_open 45 ++#define __NR_open_by_handle_at 498 ++#define __NR_open_tree 275 ++#define __NR_openat 450 ++#define __NR_openat2 284 ++#define __NR_pciconfig_iobase 376 ++#define __NR_pciconfig_read 345 ++#define __NR_pciconfig_write 346 ++#define __NR_perf_event_open 493 ++#define __NR_personality 324 ++#define __NR_pidfd_getfd 285 ++#define __NR_pidfd_open 281 ++#define __NR_pidfd_send_signal 271 ++#define __NR_pipe 42 ++#define __NR_pipe2 488 ++#define __NR_pivot_root 374 ++#define __NR_pkey_alloc 289 ++#define __NR_pkey_free 290 ++#define __NR_pkey_mprotect 288 ++#define __NR_poll 94 ++#define __NR_ppoll 464 ++#define __NR_prctl 348 ++#define __NR_pread64 349 ++#define __NR_preadv 490 ++#define __NR_preadv2 516 ++#define __NR_prlimit64 496 ++#define __NR_process_madvise 287 ++#define __NR_process_mrelease 187 ++#define __NR_process_vm_readv 504 ++#define __NR_process_vm_writev 505 ++#define __NR_pselect6 463 ++#define __NR_ptrace 26 ++#define __NR_pwrite64 350 ++#define __NR_pwritev 491 ++#define __NR_pwritev2 517 ++#define __NR_query_module 347 ++#define __NR_quotactl 148 ++#define __NR_quotactl_fd 182 ++#define __NR_read 3 ++#define __NR_readahead 379 ++#define __NR_readlink 58 ++#define __NR_readlinkat 460 ++#define __NR_readv 120 ++#define __NR_reboot 311 ++#define __NR_recv 102 ++#define __NR_recvfrom 125 ++#define __NR_recvmmsg 479 ++#define __NR_recvmsg 113 ++#define __NR_remap_file_pages 410 ++#define __NR_removexattr 391 ++#define __NR_rename 128 ++#define __NR_renameat 457 ++#define __NR_renameat2 510 ++#define __NR_request_key 440 ++#define __NR_restart_syscall 412 ++#define __NR_rmdir 137 ++#define __NR_rseq 404 ++#define __NR_rt_sigaction 352 ++#define __NR_rt_sigpending 354 ++#define __NR_rt_sigprocmask 353 ++#define __NR_rt_sigqueueinfo 356 ++#define __NR_rt_sigreturn 351 ++#define __NR_rt_sigsuspend 357 ++#define __NR_rt_sigtimedwait 355 ++#define __NR_rt_tgsigqueueinfo 492 ++#define __NR_sched_get_priority_max 335 ++#define __NR_sched_get_priority_min 336 ++#define __NR_sched_getaffinity 396 ++#define __NR_sched_getattr 509 ++#define __NR_sched_getparam 331 ++#define __NR_sched_getscheduler 333 ++#define __NR_sched_rr_get_interval 337 ++#define __NR_sched_setaffinity 395 ++#define __NR_sched_setattr 508 ++#define __NR_sched_setparam 330 ++#define __NR_sched_setscheduler 332 ++#define __NR_sched_yield 334 ++#define __NR_seccomp 514 ++#define __NR_select 358 ++#define __NR_semctl 204 ++#define __NR_semget 205 ++#define __NR_semop 206 ++#define __NR_semtimedop 423 ++#define __NR_send 101 ++#define __NR_sendfile 370 ++#define __NR_sendmmsg 503 ++#define __NR_sendmsg 114 ++#define __NR_sendto 133 ++#define __NR_set_mempolicy 431 ++#define __NR_set_mempolicy_home_node 189 ++#define __NR_set_robust_list 466 ++#define __NR_set_tid_address 411 ++#define __NR_setdomainname 166 ++#define __NR_setfsgid 326 ++#define __NR_setfsuid 325 ++#define __NR_setgid 132 ++#define __NR_setgroups 80 ++#define __NR_sethostname 88 ++#define __NR_setitimer 362 ++#define __NR_setns 501 ++#define __NR_setpgid 39 ++#define __NR_setpgrp 82 ++#define __NR_setpriority 96 ++#define __NR_setregid 127 ++#define __NR_setresgid 371 ++#define __NR_setresuid 343 ++#define __NR_setreuid 126 ++#define __NR_setrlimit 145 ++#define __NR_setsid 147 ++#define __NR_setsockopt 105 ++#define __NR_setsysinfo 257 ++#define __NR_settimeofday 360 ++#define __NR_setuid 23 ++#define __NR_setxattr 382 ++#define __NR_shmat 209 ++#define __NR_shmctl 210 ++#define __NR_shmdt 211 ++#define __NR_shmget 212 ++#define __NR_shutdown 134 ++#define __NR_sigaction 156 ++#define __NR_sigaltstack 235 ++#define __NR_signalfd 476 ++#define __NR_signalfd4 484 ++#define __NR_sigpending 52 ++#define __NR_sigprocmask 299 ++#define __NR_sigreturn 103 ++#define __NR_sigsuspend 111 ++#define __NR_socket 97 ++#define __NR_socketcall 119 ++#define __NR_socketpair 135 ++#define __NR_splice 468 ++#define __NR_stat 67 ++#define __NR_stat64 425 ++#define __NR_statfs 328 ++#define __NR_statfs64 229 ++#define __NR_statx 518 ++#define __NR_swapoff 304 ++#define __NR_swapon 322 ++#define __NR_symlink 57 ++#define __NR_symlinkat 459 ++#define __NR_sync 36 ++#define __NR_sync_file_range 469 ++#define __NR_syncfs 500 ++#define __NR_sysfs 254 ++#define __NR_sysinfo 318 ++#define __NR_syslog 310 ++#define __NR_tee 470 ++#define __NR_tgkill 424 ++#define __NR_timer_create 414 ++#define __NR_timer_delete 418 ++#define __NR_timer_getoverrun 417 ++#define __NR_timer_gettime 416 ++#define __NR_timer_settime 415 ++#define __NR_timerfd 477 ++#define __NR_timerfd_create 481 ++#define __NR_timerfd_gettime 483 ++#define __NR_timerfd_settime 482 ++#define __NR_times 323 ++#define __NR_tkill 381 ++#define __NR_truncate 129 ++#define __NR_tuxcall 397 ++#define __NR_umask 60 ++#define __NR_umount 22 ++#define __NR_umount2 22 ++#define __NR_uname 339 ++#define __NR_unlink 10 ++#define __NR_unlinkat 456 ++#define __NR_unshare 465 ++#define __NR_uselib 313 ++#define __NR_userfaultfd 171 ++#define __NR_ustat 327 ++#define __NR_utimensat 475 ++#define __NR_utimes 363 ++#define __NR_vfork 66 ++#define __NR_vhangup 76 ++#define __NR_vmsplice 471 ++#define __NR_vserver 428 ++#define __NR_wait4 365 ++#define __NR_waitid 438 ++#define __NR_write 4 ++#define __NR_writev 121 +diff --git a/sysdeps/unix/sysv/linux/sw_64/clone.S b/sysdeps/unix/sysv/linux/sw_64/clone.S +new file mode 100644 +index 00000000..6f08adae +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/clone.S +@@ -0,0 +1,117 @@ ++/* Copyright (C) 1996-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson , 1996. ++ ++ 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 ++ . */ ++ ++/* clone() is even more special than fork() as it mucks with stacks ++ and invokes a function in the right context after its all over. */ ++ ++#include ++#define _ERRNO_H 1 ++#include ++ ++/* int clone(int (*fn)(void *arg), void *child_stack, int flags, ++ void *arg, pid_t *ptid, void *tls, pid_t *ctid); ++ ++ Note that everything past ARG is technically optional, based ++ on FLAGS, and that CTID is arg 7, and thus is on the stack. ++ However, since a load from top-of-stack better be legal always, ++ we don't bother checking FLAGS. */ ++ ++ .text ++ .align 4 ++ .globl __clone ++ .ent __clone ++ .usepv __clone, USEPV_PROF ++ ++ cfi_startproc ++__clone: ++#ifdef PROF ++ .set noat ++ ldgp gp,0(pv) ++ ldi AT, _mcount ++ call AT, (AT), _mcount ++ .set at ++#endif ++ ++ /* Sanity check arguments. */ ++ ldi v0, EINVAL ++ beq a0, SYSCALL_ERROR_LABEL /* no NULL function pointers */ ++ bic a1, 0xf,a1 /*Align sp. By zyl */ ++ beq a1, SYSCALL_ERROR_LABEL /* no NULL stack pointers */ ++ ++ /* Save the fn ptr and arg on the new stack. */ ++ subl a1, 32, a1 ++ stl a0, 0(a1) ++ stl a3, 8(a1) ++ stl a2, 16(a1) ++ ++ /* The syscall is of the form clone(flags, usp, ptid, ctid, tls). ++ Shift the flags, ptid, ctid, tls arguments into place; the ++ child_stack argument is already correct. */ ++ mov a2, a0 ++ mov a4, a2 ++ ldl a3, 0(sp) ++ mov a5, a4 ++ ++ /* Do the system call. */ ++ ldi v0, __NR_clone ++ sys_call HMC_callsys ++ ++ bne a3, SYSCALL_ERROR_LABEL ++ beq v0, thread_start ++ ++ /* Successful return from the parent. */ ++ ret ++ ++PSEUDO_END(__clone) ++ cfi_endproc ++ ++/* Load up the arguments to the function. Put this block of code in ++ its own function so that we can terminate the stack trace with our ++ debug info. */ ++ ++ .align 4 ++ .ent thread_start ++ cfi_startproc ++thread_start: ++ mov 0, fp ++ cfi_def_cfa_register(fp) ++ cfi_undefined(ra) ++ ++ /* Load up the arguments. */ ++ ldl pv, 0(sp) ++ ldl a0, 8(sp) ++ addl sp, 32, sp ++ ++ /* Call the user's function. */ ++ call ra, (pv) ++ ldgp gp, 0(ra) ++ ++ mov v0, a0 ++ ldi v0, __NR_exit ++ sys_call HMC_callsys ++ ++ /* Die horribly. */ ++ .align 4 ++ halt ++ ++ .align 4 ++ cfi_endproc ++ .end thread_start ++ ++libc_hidden_def (__clone) ++weak_alias (__clone, clone) +diff --git a/sysdeps/unix/sysv/linux/sw_64/syscall.S b/sysdeps/unix/sysv/linux/sw_64/syscall.S +new file mode 100644 +index 00000000..286b9925 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/syscall.S +@@ -0,0 +1,70 @@ ++/* Copyright (C) 1996-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by David Mosberger , 1996. ++ ++ 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 for COMPATIBILITY with Linux/x86 only. Linux/Sw_64 system ++ * calls return an error indication in a3. This allows arbitrary 64bit ++ * values to be returned in v0 (because negative values are not ++ * mistaken as error numbers). However, C allows only one value to ++ * be returned, so the interface below foflds the error indication passed in ++ * a3 back into v0: it sets v0 to -errno if an error occurs. Thus, ++ * no negative 64bit numbers can be returned. To avoid this problem, ++ * use assembly stubs wherever possible/convenient. ++ * ++ * Usage: ++ * ++ * long syscall(syscall_number, arg1, arg2, arg3, arg4, arg5, arg6) ++ * ++ * syscall_number = the index of the system call we're invoking ++ * arg1-arg6 = up to 6 integer arguments to the system call ++ * ++ * We need to do some arg shifting: the kernel expects the ++ * syscall number in v0 and the first six args in a0-a5. ++ * ++ */ ++ ++ ++LEAF(__syscall, 0) ++#ifdef PROF ++ ldgp gp, 0(pv) ++ .set noat ++ ldi AT, _mcount ++ call AT, (AT), _mcount ++ .set at ++ .prologue 1 ++#else ++ .prologue 0 ++#endif ++ ++ mov a0, v0 /* Syscall number -> v0 */ ++ mov a1, a0 /* arg1-arg5 -> a0-a4 */ ++ mov a2, a1 ++ mov a3, a2 ++ mov a4, a3 ++ mov a5, a4 ++ ldl a5,0(sp) /* arg6 -> a5 */ ++ ++ sys_call HMC_callsys /* Invoke system call */ ++ bne a3, SYSCALL_ERROR_LABEL ++ ret ++ ++PSEUDO_END(__syscall) ++ ++weak_alias (__syscall, syscall) +diff --git a/sysdeps/unix/sysv/linux/sw_64/sysdep.h b/sysdeps/unix/sysv/linux/sw_64/sysdep.h +new file mode 100644 +index 00000000..f047c609 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/sysdep.h +@@ -0,0 +1,355 @@ ++/* Copyright (C) 1992-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Ulrich Drepper, , August 1995. ++ ++ 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 _LINUX_SW_64_SYSDEP_H ++#define _LINUX_SW_64_SYSDEP_H 1 ++ ++/* There is some commonality. */ ++#include ++#include ++#include /* Defines RTLD_PRIVATE_ERRNO. */ ++ ++#include ++ ++/* For Linux we can use the system call table in the header file ++ /usr/include/asm/unistd.h ++ of the kernel. But these symbols do not follow the SYS_* syntax ++ so we have to redefine the `SYS_ify' macro here. */ ++#undef SYS_ify ++#define SYS_ify(syscall_name) __NR_##syscall_name ++ ++#define SINGLE_THREAD_BY_GLOBAL 1 ++ ++#ifdef __ASSEMBLER__ ++# include ++# include ++ ++# define __LABEL(x) x##: ++ ++# define LEAF(name, framesize) \ ++ .globl name; \ ++ .align 4; \ ++ .ent name, 0; \ ++ __LABEL (name).frame sp, framesize, ra ++ ++# define ENTRY(name) \ ++ .globl name; \ ++ .align 4; \ ++ .ent name, 0; \ ++ __LABEL (name).frame sp, 0, ra ++ ++/* Mark the end of function SYM. */ ++# undef END ++# define END(sym) .end sym ++ ++# ifdef PROF ++# define PSEUDO_PROF \ ++ .set noat; \ ++ ldi AT, _mcount; \ ++ call AT, (AT), _mcount; \ ++ .set at ++# else ++# define PSEUDO_PROF ++# endif ++ ++# ifdef PROF ++# define PSEUDO_PROLOGUE \ ++ .frame sp, 0, ra; \ ++ ldgp gp, 0(pv); \ ++ PSEUDO_PROF; \ ++ .prologue 1 ++# elif defined PIC ++# define PSEUDO_PROLOGUE \ ++ .frame sp, 0, ra; \ ++ .prologue 0 ++# else ++# define PSEUDO_PROLOGUE \ ++ .frame sp, 0, ra; \ ++ ldgp gp, 0(pv); \ ++ .prologue 1 ++# endif /* PROF */ ++ ++# ifdef PROF ++# define USEPV_PROF std ++# else ++# define USEPV_PROF no ++# endif ++ ++# undef SYSCALL_ERROR_LABEL ++# if RTLD_PRIVATE_ERRNO ++# define SYSCALL_ERROR_LABEL $syscall_error ++# define SYSCALL_ERROR_HANDLER \ ++ $syscall_error: \ ++ stw v0, rtld_errno (gp) !gprel; \ ++ ldi v0, -1; \ ++ ret ++# define SYSCALL_ERROR_FALLTHRU ++# elif defined(PIC) ++# define SYSCALL_ERROR_LABEL __syscall_error !samegp ++# define SYSCALL_ERROR_HANDLER ++# define SYSCALL_ERROR_FALLTHRU br SYSCALL_ERROR_LABEL ++# else ++# define SYSCALL_ERROR_LABEL $syscall_error ++# define SYSCALL_ERROR_HANDLER \ ++ $syscall_error: \ ++ jmp $31, __syscall_error ++# define SYSCALL_ERROR_FALLTHRU ++# endif /* RTLD_PRIVATE_ERRNO */ ++ ++/* Overridden by specific syscalls. */ ++# undef PSEUDO_PREPARE_ARGS ++# define PSEUDO_PREPARE_ARGS /* Nothing. */ ++ ++# define PSEUDO(name, syscall_name, args) \ ++ .globl name; \ ++ .align 4; \ ++ .ent name, 0; \ ++ __LABEL (name) \ ++ PSEUDO_PROLOGUE; \ ++ PSEUDO_PREPARE_ARGS \ ++ ldi v0, SYS_ify (syscall_name); \ ++ sys_call HMC_callsys; \ ++ bne a3, SYSCALL_ERROR_LABEL ++ ++# undef PSEUDO_END ++# define PSEUDO_END(sym) \ ++ SYSCALL_ERROR_HANDLER; \ ++ END (sym) ++ ++# define PSEUDO_NOERRNO(name, syscall_name, args) \ ++ .globl name; \ ++ .align 4; \ ++ .ent name, 0; \ ++ __LABEL (name) \ ++ PSEUDO_PROLOGUE; \ ++ PSEUDO_PREPARE_ARGS \ ++ ldi v0, SYS_ify (syscall_name); \ ++ sys_call HMC_callsys; ++ ++# undef PSEUDO_END_NOERRNO ++# define PSEUDO_END_NOERRNO(sym) END (sym) ++ ++# define ret_NOERRNO ret ++ ++# define PSEUDO_ERRVAL(name, syscall_name, args) \ ++ .globl name; \ ++ .align 4; \ ++ .ent name, 0; \ ++ __LABEL (name) \ ++ PSEUDO_PROLOGUE; \ ++ PSEUDO_PREPARE_ARGS \ ++ ldi v0, SYS_ify (syscall_name); \ ++ sys_call HMC_callsys; ++ ++# undef PSEUDO_END_ERRVAL ++# define PSEUDO_END_ERRVAL(sym) END (sym) ++ ++# define ret_ERRVAL ret ++ ++# define r0 v0 ++# define r1 a4 ++ ++# define MOVE(x, y) mov x, y ++ ++#else /* !ASSEMBLER */ ++ ++#define HAVE_CLOCK_GETTIME_VSYSCALL "__vdso_clock_gettime" ++#define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime64" ++ ++#define INTERNAL_SYSCALL(name, nr, args...) \ ++ internal_syscall##nr(__NR_##name, args) ++ ++# define INTERNAL_SYSCALL_NCS(name, nr, args...) \ ++ internal_syscall##nr (name, args) ++ ++/* The normal Sw_64 calling convention sign-extends 32-bit quantties ++ no matter what the "real" sign of the 32-bit type. We want to ++ preserve that when filling in values for the kernel. */ ++# define syscall_promote(arg) \ ++ (sizeof (arg) == 4 ? (long int) (int) (long int) (arg) : (long int) (arg)) ++ ++# define internal_syscall_clobbers \ ++ "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$22", "$23", "$24", \ ++ "$25", "$27", "$28", "memory" ++ ++/* It is moderately important optimization-wise to limit the lifetime ++ of the hard-register variables as much as possible. Thus we copy ++ in/out as close to the asm as possible. */ ++ ++# define internal_syscall0(name, args...) \ ++ ({ \ ++ register long int _sc_19 __asm__("$19"); \ ++ register long int _sc_0 = name; \ ++ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2" \ ++ : "+v"(_sc_0), "=r"(_sc_19) \ ++ : \ ++ : internal_syscall_clobbers, "$16", "$17", "$18", \ ++ "$20", "$21"); \ ++ _sc_19 != 0 ? -_sc_0 : _sc_0; \ ++ }) ++ ++# define internal_syscall1(name, arg1) \ ++ ({ \ ++ register long int _tmp_16 = syscall_promote (arg1); \ ++ register long int _sc_0 = name; \ ++ register long int _sc_16 __asm__("$16") = _tmp_16; \ ++ register long int _sc_19 __asm__("$19"); \ ++ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3" \ ++ : "+v"(_sc_0), "=r"(_sc_19), "+r"(_sc_16) \ ++ : \ ++ : internal_syscall_clobbers, "$17", "$18", "$20", \ ++ "$21"); \ ++ _sc_19 != 0 ? -_sc_0 : _sc_0; \ ++ }) ++ ++# define internal_syscall2(name, arg1, arg2) \ ++ ({ \ ++ register long int _tmp_16 = syscall_promote (arg1); \ ++ register long int _tmp_17 = syscall_promote (arg2); \ ++ register long int _sc_0 = name; \ ++ register long int _sc_16 __asm__("$16") = _tmp_16; \ ++ register long int _sc_17 __asm__("$17") = _tmp_17; \ ++ register long int _sc_19 __asm__("$19"); \ ++ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3 %4" \ ++ : "+v"(_sc_0), "=r"(_sc_19), "+r"(_sc_16), \ ++ "+r"(_sc_17) \ ++ : \ ++ : internal_syscall_clobbers, "$18", "$20", "$21"); \ ++ _sc_19 != 0 ? -_sc_0 : _sc_0; \ ++ }) ++ ++# define internal_syscall3(name, arg1, arg2, arg3) \ ++ ({ \ ++ register long int _tmp_16 = syscall_promote (arg1); \ ++ register long int _tmp_17 = syscall_promote (arg2); \ ++ register long int _tmp_18 = syscall_promote (arg3); \ ++ register long int _sc_0 = name; \ ++ register long int _sc_16 __asm__("$16") = _tmp_16; \ ++ register long int _sc_17 __asm__("$17") = _tmp_17; \ ++ register long int _sc_18 __asm__("$18") = _tmp_18; \ ++ register long int _sc_19 __asm__("$19"); \ ++ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3 %4 %5" \ ++ : "+v"(_sc_0), "=r"(_sc_19), "+r"(_sc_16), \ ++ "+r"(_sc_17), "+r"(_sc_18) \ ++ : \ ++ : internal_syscall_clobbers, "$20", "$21"); \ ++ _sc_19 != 0 ? -_sc_0 : _sc_0; \ ++ }) ++ ++# define internal_syscall4(name, arg1, arg2, arg3, arg4) \ ++ ({ \ ++ register long int _tmp_16 = syscall_promote (arg1); \ ++ register long int _tmp_17 = syscall_promote (arg2); \ ++ register long int _tmp_18 = syscall_promote (arg3); \ ++ register long int _tmp_19 = syscall_promote (arg4); \ ++ register long int _sc_0 = name; \ ++ register long int _sc_16 __asm__("$16") = _tmp_16; \ ++ register long int _sc_17 __asm__("$17") = _tmp_17; \ ++ register long int _sc_18 __asm__("$18") = _tmp_18; \ ++ register long int _sc_19 __asm__("$19") = _tmp_19; \ ++ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3 %4 %5 %6" \ ++ : "+v"(_sc_0), "+r"(_sc_19), "+r"(_sc_16), \ ++ "+r"(_sc_17), "+r"(_sc_18) \ ++ : \ ++ : internal_syscall_clobbers, "$20", "$21"); \ ++ _sc_19 != 0 ? -_sc_0 : _sc_0; \ ++ }) ++ ++# define internal_syscall5(name, arg1, arg2, arg3, arg4, arg5) \ ++ ({ \ ++ register long int _tmp_16 = syscall_promote (arg1); \ ++ register long int _tmp_17 = syscall_promote (arg2); \ ++ register long int _tmp_18 = syscall_promote (arg3); \ ++ register long int _tmp_19 = syscall_promote (arg4); \ ++ register long int _tmp_20 = syscall_promote (arg5); \ ++ register long int _sc_0 = name; \ ++ register long int _sc_16 __asm__("$16") = _tmp_16; \ ++ register long int _sc_17 __asm__("$17") = _tmp_17; \ ++ register long int _sc_18 __asm__("$18") = _tmp_18; \ ++ register long int _sc_19 __asm__("$19") = _tmp_19; \ ++ register long int _sc_20 __asm__("$20") = _tmp_20; \ ++ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3 %4 %5 %6 %7" \ ++ : "+v"(_sc_0), "+r"(_sc_19), "+r"(_sc_16), \ ++ "+r"(_sc_17), "+r"(_sc_18), "+r"(_sc_20) \ ++ : \ ++ : internal_syscall_clobbers, "$21"); \ ++ _sc_19 != 0 ? -_sc_0 : _sc_0; \ ++ }) ++ ++# define internal_syscall6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ ++ ({ \ ++ register long int _tmp_16 = syscall_promote (arg1); \ ++ register long int _tmp_17 = syscall_promote (arg2); \ ++ register long int _tmp_18 = syscall_promote (arg3); \ ++ register long int _tmp_19 = syscall_promote (arg4); \ ++ register long int _tmp_20 = syscall_promote (arg5); \ ++ register long int _tmp_21 = syscall_promote (arg6); \ ++ register long int _sc_0 = name; \ ++ register long int _sc_16 __asm__("$16") = _tmp_16; \ ++ register long int _sc_17 __asm__("$17") = _tmp_17; \ ++ register long int _sc_18 __asm__("$18") = _tmp_18; \ ++ register long int _sc_19 __asm__("$19") = _tmp_19; \ ++ register long int _sc_20 __asm__("$20") = _tmp_20; \ ++ register long int _sc_21 __asm__("$21") = _tmp_21; \ ++ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3 %4 %5 %6 %7 %8" \ ++ : "+v"(_sc_0), "+r"(_sc_19), "+r"(_sc_16), \ ++ "+r"(_sc_17), "+r"(_sc_18), "+r"(_sc_20), \ ++ "+r"(_sc_21) \ ++ : \ ++ : internal_syscall_clobbers); \ ++ _sc_19 != 0 ? -_sc_0 : _sc_0; \ ++ }) ++#endif /* ASSEMBLER */ ++ ++/* Pointer mangling support. Note that tls access is slow enough that ++ we don't deoptimize things by placing the pointer check value there. */ ++ ++#ifdef __ASSEMBLER__ ++# if IS_IN(rtld) ++# define PTR_MANGLE(dst, src, tmp) \ ++ ldih tmp, __pointer_chk_guard_local ($29) !gprelhigh; \ ++ ldl tmp, __pointer_chk_guard_local (tmp) !gprellow; \ ++ xor src, tmp, dst ++# define PTR_MANGLE2(dst, src, tmp) xor src, tmp, dst ++# elif defined SHARED ++# define PTR_MANGLE(dst, src, tmp) \ ++ ldl tmp, __pointer_chk_guard; \ ++ xor src, tmp, dst ++# else ++# define PTR_MANGLE(dst, src, tmp) \ ++ ldl tmp, __pointer_chk_guard_local; \ ++ xor src, tmp, dst ++# endif ++# define PTR_MANGLE2(dst, src, tmp) xor src, tmp, dst ++# define PTR_DEMANGLE(dst, tmp) PTR_MANGLE (dst, dst, tmp) ++# define PTR_DEMANGLE2(dst, tmp) PTR_MANGLE2 (dst, dst, tmp) ++#else ++# include ++# if (IS_IN(rtld) || (!defined SHARED && (IS_IN(libc) || IS_IN(libpthread)))) ++extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; ++# define PTR_MANGLE(var) \ ++ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) ++# else ++extern uintptr_t __pointer_chk_guard attribute_relro; ++# define PTR_MANGLE(var) \ ++ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) ++# endif ++# define PTR_DEMANGLE(var) PTR_MANGLE (var) ++#endif /* ASSEMBLER */ ++ ++#endif /* _LINUX_SW_64_SYSDEP_H */ +diff --git a/sysdeps/unix/sysv/linux/sw_64/vfork.S b/sysdeps/unix/sysv/linux/sw_64/vfork.S +new file mode 100644 +index 00000000..a79eb93a +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/vfork.S +@@ -0,0 +1,41 @@ ++/* Copyright (C) 2004-2023 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 ++ ++ENTRY(__libc_vfork) ++ PSEUDO_PROLOGUE ++ ++ /* Load the thread pointer value in A1 across the vfork. */ ++ sys_call 0x9e ++ mov v0, a1 ++ ++ ldi v0, SYS_ify(vfork) ++ sys_call HMC_callsys ++ ++ /* Normal error check and return. */ ++ bne a3, SYSCALL_ERROR_LABEL ++ ret ++ ++PSEUDO_END (__libc_vfork) ++ ++#if IS_IN (libc) ++weak_alias (__libc_vfork, vfork) ++strong_alias (__libc_vfork, __vfork) ++libc_hidden_def (__vfork) ++#endif +-- +2.25.1 + diff --git a/0008-Sw64-Linux-ABI.patch b/0008-Sw64-Linux-ABI.patch new file mode 100644 index 0000000..267e241 --- /dev/null +++ b/0008-Sw64-Linux-ABI.patch @@ -0,0 +1,7444 @@ +From e69e2ce0e9ed2962c6e0fed8ed1d6d291d0a2b4f Mon Sep 17 00:00:00 2001 +From: swcompiler +Date: Fri, 29 Nov 2024 14:09:04 +0800 +Subject: [PATCH 08/23] Sw64: Linux ABI + +--- + sysdeps/unix/sysv/linux/sw_64/a.out.h | 197 ++++ + sysdeps/unix/sysv/linux/sw_64/adjtime.c | 22 + + sysdeps/unix/sysv/linux/sw_64/adjtimex.c | 22 + + sysdeps/unix/sysv/linux/sw_64/aio_cancel.c | 35 + + sysdeps/unix/sysv/linux/sw_64/bits/a.out.h | 9 + + sysdeps/unix/sysv/linux/sw_64/bits/dirent.h | 57 ++ + sysdeps/unix/sysv/linux/sw_64/bits/elfclass.h | 14 + + sysdeps/unix/sysv/linux/sw_64/bits/epoll.h | 27 + + sysdeps/unix/sysv/linux/sw_64/bits/errno.h | 53 ++ + sysdeps/unix/sysv/linux/sw_64/bits/eventfd.h | 32 + + sysdeps/unix/sysv/linux/sw_64/bits/fcntl.h | 87 ++ + sysdeps/unix/sysv/linux/sw_64/bits/inotify.h | 30 + + sysdeps/unix/sysv/linux/sw_64/bits/ioctls.h | 36 + + sysdeps/unix/sysv/linux/sw_64/bits/mman.h | 67 ++ + sysdeps/unix/sysv/linux/sw_64/bits/netdb.h | 33 + + .../sysv/linux/sw_64/bits/procfs-prregset.h | 26 + + sysdeps/unix/sysv/linux/sw_64/bits/procfs.h | 38 + + .../sysv/linux/sw_64/bits/pthread_stack_min.h | 20 + + sysdeps/unix/sysv/linux/sw_64/bits/resource.h | 223 +++++ + .../unix/sysv/linux/sw_64/bits/sigaction.h | 82 ++ + sysdeps/unix/sysv/linux/sw_64/bits/signalfd.h | 30 + + .../unix/sysv/linux/sw_64/bits/signum-arch.h | 67 ++ + sysdeps/unix/sysv/linux/sw_64/bits/sigstack.h | 32 + + .../sysv/linux/sw_64/bits/socket-constants.h | 51 ++ + .../unix/sysv/linux/sw_64/bits/socket_type.h | 56 ++ + sysdeps/unix/sysv/linux/sw_64/bits/statfs.h | 64 ++ + .../unix/sysv/linux/sw_64/bits/struct_stat.h | 119 +++ + .../unix/sysv/linux/sw_64/bits/termios-baud.h | 47 + + .../unix/sysv/linux/sw_64/bits/termios-c_cc.h | 41 + + .../sysv/linux/sw_64/bits/termios-c_cflag.h | 39 + + .../sysv/linux/sw_64/bits/termios-c_iflag.h | 39 + + .../sysv/linux/sw_64/bits/termios-c_lflag.h | 43 + + .../sysv/linux/sw_64/bits/termios-c_oflag.h | 67 ++ + .../sysv/linux/sw_64/bits/termios-struct.h | 38 + + sysdeps/unix/sysv/linux/sw_64/bits/timerfd.h | 30 + + .../unix/sysv/linux/sw_64/bits/typesizes.h | 87 ++ + sysdeps/unix/sysv/linux/sw_64/bits/wordsize.h | 19 + + sysdeps/unix/sysv/linux/sw_64/brk_call.h | 27 + + sysdeps/unix/sysv/linux/sw_64/dl-auxv.h | 40 + + sysdeps/unix/sysv/linux/sw_64/dl-support.c | 2 + + sysdeps/unix/sysv/linux/sw_64/dl-sysdep.c | 5 + + .../unix/sysv/linux/sw_64/errlist-compat.c | 43 + + sysdeps/unix/sysv/linux/sw_64/fraiseexcpt.S | 58 ++ + sysdeps/unix/sysv/linux/sw_64/fstatfs.c | 29 + + sysdeps/unix/sysv/linux/sw_64/fxstat64.c | 45 + + sysdeps/unix/sysv/linux/sw_64/fxstatat64.c | 32 + + sysdeps/unix/sysv/linux/sw_64/getclktck.c | 2 + + sysdeps/unix/sysv/linux/sw_64/getcontext.S | 440 +++++++++ + sysdeps/unix/sysv/linux/sw_64/getdents.c | 18 + + sysdeps/unix/sysv/linux/sw_64/getdents64.c | 10 + + sysdeps/unix/sysv/linux/sw_64/getegid.S | 26 + + sysdeps/unix/sysv/linux/sw_64/geteuid.S | 26 + + sysdeps/unix/sysv/linux/sw_64/gethostname.c | 45 + + sysdeps/unix/sysv/linux/sw_64/getppid.S | 26 + + sysdeps/unix/sysv/linux/sw_64/getrlimit64.c | 54 ++ + sysdeps/unix/sysv/linux/sw_64/gettimeofday.c | 26 + + .../unix/sysv/linux/sw_64/glob-lstat-compat.c | 2 + + sysdeps/unix/sysv/linux/sw_64/globfree.c | 36 + + .../sysv/linux/sw_64/ieee_get_fp_control.S | 50 + + .../sysv/linux/sw_64/ieee_set_fp_control.S | 46 + + sysdeps/unix/sysv/linux/sw_64/ioperm.c | 853 ++++++++++++++++++ + sysdeps/unix/sysv/linux/sw_64/ipc_priv.h | 21 + + .../unix/sysv/linux/sw_64/jmp_buf-macros.h | 6 + + .../unix/sysv/linux/sw_64/kernel-features.h | 53 ++ + .../sysv/linux/sw_64/kernel_rt_sigframe.h | 25 + + .../unix/sysv/linux/sw_64/kernel_sigaction.h | 10 + + sysdeps/unix/sysv/linux/sw_64/kernel_stat.h | 91 ++ + .../unix/sysv/linux/sw_64/kernel_sysinfo.h | 6 + + .../unix/sysv/linux/sw_64/kernel_termios.h | 43 + + sysdeps/unix/sysv/linux/sw_64/librt-compat.c | 24 + + sysdeps/unix/sysv/linux/sw_64/localplt.data | 33 + + sysdeps/unix/sysv/linux/sw_64/lxstat64.c | 46 + + sysdeps/unix/sysv/linux/sw_64/makecontext.S | 164 ++++ + sysdeps/unix/sysv/linux/sw_64/nldbl-abi.h | 8 + + sysdeps/unix/sysv/linux/sw_64/oldglob.c | 96 ++ + sysdeps/unix/sysv/linux/sw_64/osf_adjtime.c | 139 +++ + sysdeps/unix/sysv/linux/sw_64/osf_getitimer.c | 42 + + sysdeps/unix/sysv/linux/sw_64/osf_getrusage.c | 39 + + .../unix/sysv/linux/sw_64/osf_gettimeofday.c | 47 + + sysdeps/unix/sysv/linux/sw_64/osf_setitimer.c | 51 ++ + .../unix/sysv/linux/sw_64/osf_settimeofday.c | 48 + + sysdeps/unix/sysv/linux/sw_64/osf_utimes.c | 36 + + sysdeps/unix/sysv/linux/sw_64/osf_wait4.c | 40 + + sysdeps/unix/sysv/linux/sw_64/pipe.S | 1 + + sysdeps/unix/sysv/linux/sw_64/pointer_guard.h | 57 ++ + sysdeps/unix/sysv/linux/sw_64/register-dump.h | 239 +++++ + sysdeps/unix/sysv/linux/sw_64/rt_sigaction.S | 87 ++ + sysdeps/unix/sysv/linux/sw_64/select.c | 52 ++ + sysdeps/unix/sysv/linux/sw_64/setcontext.S | 34 + + sysdeps/unix/sysv/linux/sw_64/setfpucw.c | 56 ++ + sysdeps/unix/sysv/linux/sw_64/setrlimit64.c | 52 ++ + sysdeps/unix/sysv/linux/sw_64/settimeofday.c | 22 + + sysdeps/unix/sysv/linux/sw_64/shlib-versions | 20 + + .../unix/sysv/linux/sw_64/sigcontextinfo.h | 30 + + sysdeps/unix/sysv/linux/sw_64/sizes.h | 23 + + sysdeps/unix/sysv/linux/sw_64/statfs.c | 29 + + sysdeps/unix/sysv/linux/sw_64/sw_64/ptrace.h | 18 + + sysdeps/unix/sysv/linux/sw_64/sw_64/regdef.h | 44 + + sysdeps/unix/sysv/linux/sw_64/swapcontext.S | 50 + + sysdeps/unix/sysv/linux/sw_64/sys/acct.h | 62 ++ + sysdeps/unix/sysv/linux/sw_64/sys/io.h | 90 ++ + sysdeps/unix/sysv/linux/sw_64/sys/ucontext.h | 92 ++ + sysdeps/unix/sysv/linux/sw_64/sys/user.h | 52 ++ + sysdeps/unix/sysv/linux/sw_64/syscalls.list | 27 + + sysdeps/unix/sysv/linux/sw_64/sysconf.c | 126 +++ + .../sysv/linux/sw_64/timer_t_was_int_compat.h | 19 + + .../sysv/linux/sw_64/ucontext-offsets.sym | 28 + + sysdeps/unix/sysv/linux/sw_64/wait4.c | 28 + + sysdeps/unix/sysv/linux/sw_64/wordexp.c | 1 + + sysdeps/unix/sysv/linux/sw_64/xstat64.c | 46 + + sysdeps/unix/sysv/linux/sw_64/xstatconv.c | 120 +++ + sysdeps/unix/sysv/linux/sw_64/xstatconv.h | 22 + + sysdeps/unix/sysv/linux/sw_64/xstatver.h | 14 + + 113 files changed, 6529 insertions(+) + create mode 100644 sysdeps/unix/sysv/linux/sw_64/a.out.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/adjtime.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/adjtimex.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/aio_cancel.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/a.out.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/dirent.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/elfclass.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/epoll.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/errno.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/eventfd.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/fcntl.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/inotify.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/ioctls.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/mman.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/netdb.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/procfs-prregset.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/procfs.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/pthread_stack_min.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/resource.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/sigaction.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/signalfd.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/signum-arch.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/sigstack.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/socket-constants.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/socket_type.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/statfs.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/struct_stat.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/termios-baud.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/termios-c_cc.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/termios-c_cflag.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/termios-c_iflag.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/termios-c_lflag.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/termios-c_oflag.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/termios-struct.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/timerfd.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/typesizes.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/bits/wordsize.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/brk_call.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/dl-auxv.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/dl-support.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/dl-sysdep.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/errlist-compat.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/fraiseexcpt.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/fstatfs.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/fxstat64.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/fxstatat64.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/getclktck.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/getcontext.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/getdents.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/getdents64.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/getegid.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/geteuid.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/gethostname.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/getppid.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/getrlimit64.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/gettimeofday.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/glob-lstat-compat.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/globfree.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/ieee_get_fp_control.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/ieee_set_fp_control.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/ioperm.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/ipc_priv.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/jmp_buf-macros.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/kernel-features.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/kernel_rt_sigframe.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/kernel_sigaction.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/kernel_stat.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/kernel_sysinfo.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/kernel_termios.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/librt-compat.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/localplt.data + create mode 100644 sysdeps/unix/sysv/linux/sw_64/lxstat64.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/makecontext.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/nldbl-abi.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/oldglob.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/osf_adjtime.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/osf_getitimer.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/osf_getrusage.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/osf_gettimeofday.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/osf_setitimer.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/osf_settimeofday.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/osf_utimes.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/osf_wait4.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/pipe.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/pointer_guard.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/register-dump.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/rt_sigaction.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/select.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/setcontext.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/setfpucw.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/setrlimit64.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/settimeofday.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/shlib-versions + create mode 100644 sysdeps/unix/sysv/linux/sw_64/sigcontextinfo.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/sizes.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/statfs.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/sw_64/ptrace.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/sw_64/regdef.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/swapcontext.S + create mode 100644 sysdeps/unix/sysv/linux/sw_64/sys/acct.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/sys/io.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/sys/ucontext.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/sys/user.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/syscalls.list + create mode 100644 sysdeps/unix/sysv/linux/sw_64/sysconf.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/timer_t_was_int_compat.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/ucontext-offsets.sym + create mode 100644 sysdeps/unix/sysv/linux/sw_64/wait4.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/wordexp.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/xstat64.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/xstatconv.c + create mode 100644 sysdeps/unix/sysv/linux/sw_64/xstatconv.h + create mode 100644 sysdeps/unix/sysv/linux/sw_64/xstatver.h + +diff --git a/sysdeps/unix/sysv/linux/sw_64/a.out.h b/sysdeps/unix/sysv/linux/sw_64/a.out.h +new file mode 100644 +index 00000000..2004d974 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/a.out.h +@@ -0,0 +1,197 @@ ++#ifndef __A_OUT_GNU_H__ ++#define __A_OUT_GNU_H__ ++ ++#include ++ ++#define __GNU_EXEC_MACROS__ ++ ++/* ++ * OSF/1 ECOFF header structs. ECOFF files consist of: ++ * - a file header (struct filehdr), ++ * - an a.out header (struct aouthdr), ++ * - one or more section headers (struct scnhdr). ++ * The filhdr's "f_nscns" field contains the ++ * number of section headers. ++ */ ++ ++struct filehdr ++{ ++ /* OSF/1 "file" header */ ++ unsigned short f_magic, f_nscns; ++ unsigned int f_timdat; ++ unsigned long f_symptr; ++ unsigned int f_nsyms; ++ unsigned short f_opthdr, f_flags; ++}; ++ ++struct aouthdr ++{ ++ unsigned long info; /* After that it looks quite normal.. */ ++ unsigned long tsize; ++ unsigned long dsize; ++ unsigned long bsize; ++ unsigned long entry; ++ unsigned long ++ text_start; /* With a few additions that actually make sense. */ ++ unsigned long data_start; ++ unsigned long bss_start; ++ unsigned int gprmask, ++ fprmask; /* Bitmask of general & floating point regs used in binary. */ ++ unsigned long gpvalue; ++}; ++ ++struct scnhdr ++{ ++ char s_name[8]; ++ unsigned long s_paddr; ++ unsigned long s_vaddr; ++ unsigned long s_size; ++ unsigned long s_scnptr; ++ unsigned long s_relptr; ++ unsigned long s_lnnoptr; ++ unsigned short s_nreloc; ++ unsigned short s_nlnno; ++ unsigned int s_flags; ++}; ++ ++struct exec ++{ ++ /* OSF/1 "file" header */ ++ struct filehdr fh; ++ struct aouthdr ah; ++}; ++ ++#define a_info ah.info ++#define a_text ah.tsize ++#define a_data ah.dsize ++#define a_bss ah.bsize ++#define a_entry ah.entry ++#define a_textstart ah.text_start ++#define a_datastart ah.data_start ++#define a_bssstart ah.bss_start ++#define a_gprmask ah.gprmask ++#define a_fprmask ah.fprmask ++#define a_gpvalue ah.gpvalue ++ ++#define AOUTHSZ sizeof (struct aouthdr) ++#define SCNHSZ sizeof (struct scnhdr) ++#define SCNROUND 16 ++ ++enum machine_type ++{ ++ M_OLDSUN2 = 0, ++ M_68010 = 1, ++ M_68020 = 2, ++ M_SPARC = 3, ++ M_386 = 100, ++ M_MIPS1 = 151, ++ M_MIPS2 = 152 ++}; ++ ++#define N_MAGIC(exec) ((exec).a_info & 0xffff) ++#define N_MACHTYPE(exec) ((enum machine_type) (((exec).a_info >> 16) & 0xff)) ++#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff) ++#define N_SET_INFO(exec, magic, type, flags) \ ++ ((exec).a_info = ((magic) &0xffff) | (((int) (type) &0xff) << 16) \ ++ | (((flags) &0xff) << 24)) ++#define N_SET_MAGIC(exec, magic) \ ++ ((exec).a_info = ((exec).a_info & 0xffff0000) | ((magic) &0xffff)) ++#define N_SET_MACHTYPE(exec, machtype) \ ++ ((exec).a_info \ ++ = ((exec).a_info & 0xff00ffff) | ((((int) (machtype)) & 0xff) << 16)) ++#define N_SET_FLAGS(exec, flags) \ ++ ((exec).a_info = ((exec).a_info & 0x00ffffff) | (((flags) &0xff) << 24)) ++ ++/* Code indicating object file or impure executable. */ ++#define OMAGIC 0407 ++/* Code indicating pure executable. */ ++#define NMAGIC 0410 ++/* Code indicating demand-paged executable. */ ++#define ZMAGIC 0413 ++/* This indicates a demand-paged executable with the header in the text. ++ The first page is unmapped to help trap NULL pointer references. */ ++#define QMAGIC 0314 ++/* Code indicating core file. */ ++#define CMAGIC 0421 ++ ++#define N_TRSIZE(x) 0 ++#define N_DRSIZE(x) 0 ++#define N_SYMSIZE(x) 0 ++#define N_BADMAG(x) \ ++ (N_MAGIC (x) != OMAGIC && N_MAGIC (x) != NMAGIC && N_MAGIC (x) != ZMAGIC \ ++ && N_MAGIC (x) != QMAGIC) ++#define _N_HDROFF(x) (1024 - sizeof (struct exec)) ++#define N_TXTOFF(x) \ ++ ((long) N_MAGIC (x) == ZMAGIC \ ++ ? 0 \ ++ : ((sizeof (struct exec) + (x).fh.f_nscns * SCNHSZ + SCNROUND - 1) \ ++ & ~(SCNROUND - 1))) ++ ++#define N_DATOFF(x) (N_TXTOFF (x) + (x).a_text) ++#define N_TRELOFF(x) (N_DATOFF (x) + (x).a_data) ++#define N_DRELOFF(x) (N_TRELOFF (x) + N_TRSIZE (x)) ++#define N_SYMOFF(x) (N_DRELOFF (x) + N_DRSIZE (x)) ++#define N_STROFF(x) (N_SYMOFF (x) + N_SYMSIZE (x)) ++ ++/* Address of text segment in memory after it is loaded. */ ++#define N_TXTADDR(x) ((x).a_textstart) ++ ++/* Address of data segment in memory after it is loaded. */ ++#define SEGMENT_SIZE 1024 ++ ++#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1)) ++#define _N_TXTENDADDR(x) (N_TXTADDR (x) + (x).a_text) ++ ++#define N_DATADDR(x) ((x).a_datastart) ++#define N_BSSADDR(x) ((x).a_bssstart) ++ ++#if !defined(N_NLIST_DECLARED) ++struct nlist ++{ ++ union ++ { ++ char *n_name; ++ struct nlist *n_next; ++ long n_strx; ++ } n_un; ++ unsigned char n_type; ++ char n_other; ++ short n_desc; ++ unsigned long n_value; ++}; ++#endif /* no N_NLIST_DECLARED. */ ++ ++#define N_UNDF 0 ++#define N_ABS 2 ++#define N_TEXT 4 ++#define N_DATA 6 ++#define N_BSS 8 ++#define N_FN 15 ++#define N_EXT 1 ++#define N_TYPE 036 ++#define N_STAB 0340 ++#define N_INDR 0xa ++#define N_SETA 0x14 /* Absolute set element symbol. */ ++#define N_SETT 0x16 /* Text set element symbol. */ ++#define N_SETD 0x18 /* Data set element symbol. */ ++#define N_SETB 0x1A /* Bss set element symbol. */ ++#define N_SETV 0x1C /* Pointer to set vector in data area. */ ++ ++#if !defined(N_RELOCATION_INFO_DECLARED) ++/* This structure describes a single relocation to be performed. ++ The text-relocation section of the file is a vector of these structures, ++ all of which apply to the text section. ++ Likewise, the data-relocation section applies to the data section. */ ++ ++struct relocation_info ++{ ++ int r_address; ++ unsigned int r_symbolnum : 24; ++ unsigned int r_pcrel : 1; ++ unsigned int r_length : 2; ++ unsigned int r_extern : 1; ++ unsigned int r_pad : 4; ++}; ++#endif /* no N_RELOCATION_INFO_DECLARED. */ ++ ++#endif /* __A_OUT_GNU_H__ */ +diff --git a/sysdeps/unix/sysv/linux/sw_64/adjtime.c b/sysdeps/unix/sysv/linux/sw_64/adjtime.c +new file mode 100644 +index 00000000..6b64d1b9 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/adjtime.c +@@ -0,0 +1,22 @@ ++/* adjtime -- Adjust the current time of day. Linux/Sw_64/tv64 version. ++ Copyright (C) 2019-2023 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 ++ . */ ++ ++/* We can use the generic Linux implementation, but we have to override its ++ default symbol version. */ ++#define VERSION_adjtime GLIBC_2.1 ++#include +diff --git a/sysdeps/unix/sysv/linux/sw_64/adjtimex.c b/sysdeps/unix/sysv/linux/sw_64/adjtimex.c +new file mode 100644 +index 00000000..2e3d8d49 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/adjtimex.c +@@ -0,0 +1,22 @@ ++/* adjtimex -- Adjust the current time of day. Linux/Sw_64/tv64 version. ++ Copyright (C) 2019-2023 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 ++ . */ ++ ++/* We can use the generic Linux implementation, but we have to override its ++ default symbol version. */ ++#define VERSION_adjtimex GLIBC_2.1 ++#include +diff --git a/sysdeps/unix/sysv/linux/sw_64/aio_cancel.c b/sysdeps/unix/sysv/linux/sw_64/aio_cancel.c +new file mode 100644 +index 00000000..222126ea +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/aio_cancel.c +@@ -0,0 +1,35 @@ ++#include ++ ++#define aio_cancel64 XXX ++#include ++#undef aio_cancel64 ++#include ++ ++extern __typeof (aio_cancel) __new_aio_cancel; ++extern __typeof (aio_cancel) __old_aio_cancel; ++ ++#define __aio_cancel __new_aio_cancel ++ ++#include ++ ++#undef __aio_cancel ++versioned_symbol (libc, __new_aio_cancel, aio_cancel, GLIBC_2_34); ++versioned_symbol (libc, __new_aio_cancel, aio_cancel64, GLIBC_2_34); ++#if OTHER_SHLIB_COMPAT (librt, GLIBC_2_3, GLIBC_2_34) ++compat_symbol (librt, __new_aio_cancel, aio_cancel, GLIBC_2_3); ++compat_symbol (librt, __new_aio_cancel, aio_cancel64, GLIBC_2_3); ++#endif ++ ++#if OTHER_SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_3) ++ ++# undef ECANCELED ++# define __aio_cancel __old_aio_cancel ++# define ECANCELED 125 ++ ++# include ++ ++# undef __aio_cancel ++compat_symbol (librt, __old_aio_cancel, aio_cancel, GLIBC_2_1); ++compat_symbol (librt, __old_aio_cancel, aio_cancel64, GLIBC_2_1); ++ ++#endif +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/a.out.h b/sysdeps/unix/sysv/linux/sw_64/bits/a.out.h +new file mode 100644 +index 00000000..f15e82c9 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/a.out.h +@@ -0,0 +1,9 @@ ++#ifndef __A_OUT_GNU_H__ ++# error "Never use directly; include instead." ++#endif ++#ifndef __A_OUT_GNU_H__ ++# error "Never use directly; include instead." ++#endif ++#ifndef __A_OUT_GNU_H__ ++# error "Never use directly; include instead." ++#endif +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/dirent.h b/sysdeps/unix/sysv/linux/sw_64/bits/dirent.h +new file mode 100644 +index 00000000..ca27db2f +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/dirent.h +@@ -0,0 +1,57 @@ ++/* Copyright (C) 1996-2023 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_DIRENT_H ++#define _BITS_DIRENT_H 1 ++ ++struct dirent ++{ ++#if (defined __USE_FILE_OFFSET64 || defined __sw_64__) ++ __ino64_t d_ino; ++#else ++ __ino_t d_ino; ++ int __pad; ++#endif ++ __off_t d_off; ++ unsigned short int d_reclen; ++ unsigned char d_type; ++ char d_name[256]; /* We must not include limits.h! */ ++}; ++ ++#ifdef __USE_LARGEFILE64 ++/* Note dirent64 is the same as dirent. */ ++struct dirent64 ++{ ++ __ino64_t d_ino; ++ __off64_t d_off; ++ unsigned short int d_reclen; ++ unsigned char d_type; ++ char d_name[256]; /* We must not include limits.h! */ ++}; ++#endif ++ ++#define d_fileno d_ino /* Backwards compatibility. */ ++ ++#undef _DIRENT_HAVE_D_NAMLEN ++#define _DIRENT_HAVE_D_RECLEN ++#define _DIRENT_HAVE_D_OFF ++#define _DIRENT_HAVE_D_TYPE ++ ++/* Inform libc code that these two types are effectively identical. */ ++#define _DIRENT_MATCHES_DIRENT64 1 ++ ++#endif /* bits/dirent.h */ +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/elfclass.h b/sysdeps/unix/sysv/linux/sw_64/bits/elfclass.h +new file mode 100644 +index 00000000..e74c5f72 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/elfclass.h +@@ -0,0 +1,14 @@ ++/* This file specifies the native word size of the machine, which indicates ++ the ELF file class used for executables and shared objects on this ++ machine. */ ++ ++#ifndef _LINK_H ++# error "Never use directly; include instead." ++#endif ++ ++#include ++ ++#define __ELF_NATIVE_CLASS __WORDSIZE ++ ++/* Linux/Sw_64 is exceptional as it has .hash section with 64 bit entries. */ ++typedef uint64_t Elf_Symndx; +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/epoll.h b/sysdeps/unix/sysv/linux/sw_64/bits/epoll.h +new file mode 100644 +index 00000000..6c78bb04 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/epoll.h +@@ -0,0 +1,27 @@ ++/* Copyright (C) 2002-2023 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_EPOLL_H ++# error "Never use directly; include instead." ++#endif ++ ++/* Flags to be passed to epoll_create1. */ ++enum ++{ ++ EPOLL_CLOEXEC = 010000000 ++#define EPOLL_CLOEXEC EPOLL_CLOEXEC ++}; +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/errno.h b/sysdeps/unix/sysv/linux/sw_64/bits/errno.h +new file mode 100644 +index 00000000..9fdbfe53 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/errno.h +@@ -0,0 +1,53 @@ ++/* Error constants. Linux/Sw_64 specific version. ++ Copyright (C) 1996-2023 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_ERRNO_H ++#define _BITS_ERRNO_H 1 ++ ++#if !defined _ERRNO_H ++# error "Never include directly; use instead." ++#endif ++ ++#include ++ ++/* Older Linux headers do not define these constants. */ ++#ifndef ENOTSUP ++# define ENOTSUP EOPNOTSUPP ++#endif ++ ++#ifndef ECANCELED ++# define ECANCELED 131 ++#endif ++ ++#ifndef EOWNERDEAD ++# define EOWNERDEAD 136 ++#endif ++ ++#ifndef ENOTRECOVERABLE ++# define ENOTRECOVERABLE 137 ++#endif ++ ++#ifndef ERFKILL ++# define ERFKILL 138 ++#endif ++ ++#ifndef EHWPOISON ++# define EHWPOISON 139 ++#endif ++ ++#endif /* bits/errno.h. */ +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/eventfd.h b/sysdeps/unix/sysv/linux/sw_64/bits/eventfd.h +new file mode 100644 +index 00000000..6ddae34b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/eventfd.h +@@ -0,0 +1,32 @@ ++/* Copyright (C) 2007-2023 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_EVENTFD_H ++# error \ ++ "Never use directly; include instead." ++#endif ++ ++/* Flags for eventfd. */ ++enum ++{ ++ EFD_SEMAPHORE = 000000001, ++#define EFD_SEMAPHORE EFD_SEMAPHORE ++ EFD_CLOEXEC = 010000000, ++#define EFD_CLOEXEC EFD_CLOEXEC ++ EFD_NONBLOCK = 000000004 ++#define EFD_NONBLOCK EFD_NONBLOCK ++}; +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/fcntl.h b/sysdeps/unix/sysv/linux/sw_64/bits/fcntl.h +new file mode 100644 +index 00000000..48ae4a7c +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/fcntl.h +@@ -0,0 +1,87 @@ ++/* O_*, F_*, FD_* bit values for Linux. ++ Copyright (C) 1995-2023 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 _FCNTL_H ++# error "Never use directly; include instead." ++#endif ++ ++#define O_CREAT 01000 /* not fcntl */ ++#define O_TRUNC 02000 /* not fcntl */ ++#define O_EXCL 04000 /* not fcntl */ ++#define O_NOCTTY 010000 /* not fcntl */ ++ ++#define O_NONBLOCK 00004 ++#define O_APPEND 00010 ++#define O_SYNC 020040000 ++ ++#define __O_DIRECTORY 0100000 /* Must be a directory. */ ++#define __O_NOFOLLOW 0200000 /* Do not follow links. */ ++#define __O_CLOEXEC 010000000 /* Set close_on_exec. */ ++ ++#define __O_DIRECT 02000000 /* Direct disk access. */ ++#define __O_NOATIME 04000000 /* Do not set atime. */ ++#define __O_PATH 040000000 /* Resolve pathname but do not open file. */ ++#define __O_TMPFILE 0100100000 /* Atomically create nameless file. */ ++ ++/* Not necessary, files are always with 64bit off_t. */ ++#define __O_LARGEFILE 0 ++ ++#define __O_DSYNC 040000 /* Synchronize data. */ ++ ++#define F_GETLK 7 /* Get record locking info. */ ++#define F_SETLK 8 /* Set record locking info (non-blocking). */ ++#define F_SETLKW 9 /* Set record locking info (blocking). */ ++#define F_GETLK64 F_GETLK /* Get record locking info. */ ++#define F_SETLK64 F_SETLK /* Set record locking info (non-blocking). */ ++#define F_SETLKW64 F_SETLKW /* Set record locking info (blocking). */ ++ ++#define __F_SETOWN 5 /* Get owner of socket (receiver of SIGIO). */ ++#define __F_GETOWN 6 /* Set owner of socket (receiver of SIGIO). */ ++ ++/* For posix fcntl() and `l_type' field of a `struct flock' for lockf() */ ++#define F_RDLCK 1 /* Read lock. */ ++#define F_WRLCK 2 /* Write lock. */ ++#define F_UNLCK 8 /* Remove lock. */ ++ ++/* for old implementation of bsd flock () */ ++#define F_EXLCK 16 /* or 3 */ ++#define F_SHLCK 32 /* or 4 */ ++ ++/* We don't need to support __USE_FILE_OFFSET64. */ ++struct flock ++{ ++ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ ++ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ ++ __off_t l_start; /* Offset where the lock begins. */ ++ __off_t l_len; /* Size of the locked area; zero means until EOF. */ ++ __pid_t l_pid; /* Process holding the lock. */ ++}; ++ ++#ifdef __USE_LARGEFILE64 ++struct flock64 ++{ ++ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ ++ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ ++ __off64_t l_start; /* Offset where the lock begins. */ ++ __off64_t l_len; /* Size of the locked area; zero means until EOF. */ ++ __pid_t l_pid; /* Process holding the lock. */ ++}; ++#endif ++ ++/* Include generic Linux declarations. */ ++#include +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/inotify.h b/sysdeps/unix/sysv/linux/sw_64/bits/inotify.h +new file mode 100644 +index 00000000..9d9e2872 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/inotify.h +@@ -0,0 +1,30 @@ ++/* Copyright (C) 2005-2023 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_INOTIFY_H ++# error \ ++ "Never use directly; include instead." ++#endif ++ ++/* Flags for the parameter of inotify_init1. */ ++enum ++{ ++ IN_CLOEXEC = 010000000, ++#define IN_CLOEXEC IN_CLOEXEC ++ IN_NONBLOCK = 000000004 ++#define IN_NONBLOCK IN_NONBLOCK ++}; +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/ioctls.h b/sysdeps/unix/sysv/linux/sw_64/bits/ioctls.h +new file mode 100644 +index 00000000..41c9e754 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/ioctls.h +@@ -0,0 +1,36 @@ ++/* Copyright (C) 1996-2023 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_IOCTL_H ++# error "Never use directly; include instead." ++#endif ++ ++/* Use the definitions from the kernel header files. */ ++#include ++ ++/* Oh well, this is necessary since the kernel data structure is ++ different from the user-level version. */ ++#undef TCGETS ++#undef TCSETS ++#undef TCSETSW ++#undef TCSETSF ++#define TCGETS _IOR ('t', 19, char[44]) ++#define TCSETS _IOW ('t', 20, char[44]) ++#define TCSETSW _IOW ('t', 21, char[44]) ++#define TCSETSF _IOW ('t', 22, char[44]) ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/mman.h b/sysdeps/unix/sysv/linux/sw_64/bits/mman.h +new file mode 100644 +index 00000000..f8e9f148 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/mman.h +@@ -0,0 +1,67 @@ ++/* Definitions for POSIX memory map interface. Linux/Sw_64 version. ++ Copyright (C) 1997-2023 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_MMAN_H ++# error "Never use directly; include instead." ++#endif ++ ++/* The following definitions basically come from the kernel headers. ++ But the kernel header is not namespace clean. */ ++ ++#define __MAP_ANONYMOUS 0x10 /* Don't use a file. */ ++ ++/* These are Linux-specific. */ ++#define MAP_GROWSDOWN 0x01000 /* Stack-like segment. */ ++#define MAP_DENYWRITE 0x02000 /* ETXTBSY */ ++#define MAP_EXECUTABLE 0x04000 /* Mark it as an executable. */ ++#define MAP_LOCKED 0x08000 /* Lock the mapping. */ ++#define MAP_NORESERVE 0x10000 /* Don't check for reservations. */ ++#define MAP_POPULATE 0x20000 /* Populate (prefault) pagetables. */ ++#define MAP_NONBLOCK 0x40000 /* Do not block on IO. */ ++#define MAP_STACK 0x80000 /* Allocation is for a stack. */ ++#define MAP_HUGETLB 0x100000 /* Create huge page mapping. */ ++#define MAP_FIXED_NOREPLACE \ ++ 0x200000 /* MAP_FIXED but do not unmap \ ++ underlying mapping. */ ++ ++/* Flags for `mlockall'. */ ++#define MCL_CURRENT 8192 ++#define MCL_FUTURE 16384 ++#define MCL_ONFAULT 32768 ++ ++#include ++ ++/* Values that differ from standard . For the most part newer ++ values are shared, but older values are skewed. */ ++ ++#undef MAP_FIXED ++#define MAP_FIXED 0x100 ++ ++#undef MS_SYNC ++#define MS_SYNC 2 ++#undef MS_INVALIDATE ++#define MS_INVALIDATE 4 ++ ++#ifdef __USE_MISC ++# undef MADV_DONTNEED ++# define MADV_DONTNEED 6 ++#endif ++#ifdef __USE_XOPEN2K ++# undef POSIX_MADV_DONTNEED ++# define POSIX_MADV_DONTNEED 6 ++#endif +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/netdb.h b/sysdeps/unix/sysv/linux/sw_64/bits/netdb.h +new file mode 100644 +index 00000000..d97e16a4 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/netdb.h +@@ -0,0 +1,33 @@ ++/* Copyright (C) 1996-2023 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 _NETDB_H ++# error "Never include directly; use instead." ++#endif ++ ++/* Description of data base entry for a single network. NOTE: here a ++ poor assumption is made. The network number is expected to fit ++ into an unsigned long int variable. */ ++struct netent ++{ ++ char *n_name; /* Official name of network. */ ++ char **n_aliases; /* Alias list. */ ++ int n_addrtype; /* Net address type. */ ++ /* XXX We should probably use uint32_t for the field and ensure ++ compatibility by adding appropriate padding. */ ++ uint32_t n_net; /* Network number. */ ++}; +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/procfs-prregset.h b/sysdeps/unix/sysv/linux/sw_64/bits/procfs-prregset.h +new file mode 100644 +index 00000000..9b00b279 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/procfs-prregset.h +@@ -0,0 +1,26 @@ ++/* Types of prgregset_t and prfpregset_t. SW_64 version. ++ Copyright (C) 2018-2023 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_PROCFS_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++typedef gregset_t __prgregset_t; ++typedef fpregset_t __prfpregset_t; +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/procfs.h b/sysdeps/unix/sysv/linux/sw_64/bits/procfs.h +new file mode 100644 +index 00000000..0b3453ae +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/procfs.h +@@ -0,0 +1,38 @@ ++/* Types for registers for sys/procfs.h. SW_64 version. ++ Copyright (C) 1996-2023 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_PROCFS_H ++# error "Never include directly; use instead." ++#endif ++ ++#include ++#include ++ ++/* ++ * The OSF/1 version of makes gregset_t 46 entries long. ++ * I have no idea why that is so. For now, we just leave it at 33 ++ * (32 general regs + processor status word). ++ */ ++#define ELF_NGREG 33 ++#define ELF_NFPREG 32 ++ ++typedef unsigned long elf_greg_t; ++typedef elf_greg_t elf_gregset_t[ELF_NGREG]; ++ ++typedef double elf_fpreg_t; ++typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/pthread_stack_min.h b/sysdeps/unix/sysv/linux/sw_64/bits/pthread_stack_min.h +new file mode 100644 +index 00000000..7e785f4a +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/pthread_stack_min.h +@@ -0,0 +1,20 @@ ++/* Definition of PTHREAD_STACK_MIN. Linux/SW_64 version. ++ Copyright (C) 2023 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 Library General Public License as ++ published by the Free Software Foundation; either version 2 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 ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++/* Minimum size for a thread. We are free to choose a reasonable value. */ ++#define PTHREAD_STACK_MIN 24576 +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/resource.h b/sysdeps/unix/sysv/linux/sw_64/bits/resource.h +new file mode 100644 +index 00000000..9c4a2d56 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/resource.h +@@ -0,0 +1,223 @@ ++/* Bit values & structures for resource limits. Sw_64/Linux version. ++ Copyright (C) 1994-2023 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_RESOURCE_H ++# error \ ++ "Never use directly; include instead." ++#endif ++ ++#include ++ ++/* Transmute defines to enumerations. The macro re-definitions are ++ necessary because some programs want to test for operating system ++ features with #ifdef RUSAGE_SELF. In ISO C the reflexive ++ definition is a no-op. */ ++ ++/* Kinds of resource limit. */ ++enum __rlimit_resource ++{ ++ /* Per-process CPU limit, in seconds. */ ++ RLIMIT_CPU = 0, ++#define RLIMIT_CPU RLIMIT_CPU ++ ++ /* Largest file that can be created, in bytes. */ ++ RLIMIT_FSIZE = 1, ++#define RLIMIT_FSIZE RLIMIT_FSIZE ++ ++ /* Maximum size of data segment, in bytes. */ ++ RLIMIT_DATA = 2, ++#define RLIMIT_DATA RLIMIT_DATA ++ ++ /* Maximum size of stack segment, in bytes. */ ++ RLIMIT_STACK = 3, ++#define RLIMIT_STACK RLIMIT_STACK ++ ++ /* Largest core file that can be created, in bytes. */ ++ RLIMIT_CORE = 4, ++#define RLIMIT_CORE RLIMIT_CORE ++ ++ /* Largest resident set size, in bytes. ++ This affects swapping; processes that are exceeding their ++ resident set size will be more likely to have physical memory ++ taken from them. */ ++ __RLIMIT_RSS = 5, ++#define RLIMIT_RSS __RLIMIT_RSS ++ ++ /* Number of open files. */ ++ RLIMIT_NOFILE = 6, ++ __RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same. */ ++#define RLIMIT_NOFILE RLIMIT_NOFILE ++#define RLIMIT_OFILE __RLIMIT_OFILE ++ ++ /* Address space limit (?) */ ++ RLIMIT_AS = 7, ++#define RLIMIT_AS RLIMIT_AS ++ ++ /* Number of processes. */ ++ __RLIMIT_NPROC = 8, ++#define RLIMIT_NPROC __RLIMIT_NPROC ++ ++ /* Locked-in-memory address space. */ ++ __RLIMIT_MEMLOCK = 9, ++#define RLIMIT_MEMLOCK __RLIMIT_MEMLOCK ++ ++ /* Maximum number of file locks. */ ++ __RLIMIT_LOCKS = 10, ++#define RLIMIT_LOCKS __RLIMIT_LOCKS ++ ++ /* Maximum number of pending signals. */ ++ __RLIMIT_SIGPENDING = 11, ++#define RLIMIT_SIGPENDING __RLIMIT_SIGPENDING ++ ++ /* Maximum bytes in POSIX message queues. */ ++ __RLIMIT_MSGQUEUE = 12, ++#define RLIMIT_MSGQUEUE __RLIMIT_MSGQUEUE ++ ++ /* Maximum nice priority allowed to raise to. ++ Nice levels 19 .. -20 correspond to 0 .. 39 ++ values of this resource limit. */ ++ __RLIMIT_NICE = 13, ++#define RLIMIT_NICE __RLIMIT_NICE ++ ++ /* Maximum realtime priority allowed for non-priviledged ++ processes. */ ++ __RLIMIT_RTPRIO = 14, ++#define RLIMIT_RTPRIO __RLIMIT_RTPRIO ++ ++ /* Maximum CPU time in microseconds that a process scheduled under a ++ real-time scheduling policy may consume without making a blocking system ++ call before being forcibly descheduled. */ ++ __RLIMIT_RTTIME = 15, ++#define RLIMIT_RTTIME __RLIMIT_RTTIME ++ ++ __RLIMIT_NLIMITS = 16, ++ __RLIM_NLIMITS = __RLIMIT_NLIMITS ++#define RLIMIT_NLIMITS __RLIMIT_NLIMITS ++#define RLIM_NLIMITS __RLIM_NLIMITS ++}; ++ ++/* Value to indicate that there is no limit. */ ++#ifndef __USE_FILE_OFFSET64 ++# define RLIM_INFINITY ((__rlim_t) -1) ++#else ++# define RLIM_INFINITY 0xffffffffffffffffuLL ++#endif ++ ++#ifdef __USE_LARGEFILE64 ++# define RLIM64_INFINITY 0xffffffffffffffffuLL ++#endif ++ ++/* We can represent all limits. */ ++#define RLIM_SAVED_MAX RLIM_INFINITY ++#define RLIM_SAVED_CUR RLIM_INFINITY ++ ++/* Type for resource quantity measurement. */ ++#ifndef __USE_FILE_OFFSET64 ++typedef __rlim_t rlim_t; ++#else ++typedef __rlim64_t rlim_t; ++#endif ++#ifdef __USE_LARGEFILE64 ++typedef __rlim64_t rlim64_t; ++#endif ++ ++struct rlimit ++{ ++ /* The current (soft) limit. */ ++ rlim_t rlim_cur; ++ /* The hard limit. */ ++ rlim_t rlim_max; ++}; ++ ++#ifdef __USE_LARGEFILE64 ++struct rlimit64 ++{ ++ /* The current (soft) limit. */ ++ rlim64_t rlim_cur; ++ /* The hard limit. */ ++ rlim64_t rlim_max; ++}; ++#endif ++ ++/* Whose usage statistics do you want? */ ++enum __rusage_who ++{ ++ /* The calling process. */ ++ RUSAGE_SELF = 0, ++#define RUSAGE_SELF RUSAGE_SELF ++ ++ /* All of its terminated child processes. */ ++ RUSAGE_CHILDREN = -1 ++#define RUSAGE_CHILDREN RUSAGE_CHILDREN ++ ++#ifdef __USE_GNU ++ , ++ /* The calling thread. */ ++ RUSAGE_THREAD = 1 ++# define RUSAGE_THREAD RUSAGE_THREAD ++/* Name for the same functionality on Solaris. */ ++# define RUSAGE_LWP RUSAGE_THREAD ++#endif ++}; ++ ++#include ++#include ++ ++/* Priority limits. */ ++#define PRIO_MIN -20 /* Minimum priority a process can have. */ ++#define PRIO_MAX 20 /* Maximum priority a process can have. */ ++ ++/* The type of the WHICH argument to `getpriority' and `setpriority', ++ indicating what flavor of entity the WHO argument specifies. */ ++enum __priority_which ++{ ++ PRIO_PROCESS = 0, /* WHO is a process ID. */ ++#define PRIO_PROCESS PRIO_PROCESS ++ PRIO_PGRP = 1, /* WHO is a process group ID. */ ++#define PRIO_PGRP PRIO_PGRP ++ PRIO_USER = 2 /* WHO is a user ID. */ ++#define PRIO_USER PRIO_USER ++}; ++ ++__BEGIN_DECLS ++ ++#ifdef __USE_GNU ++/* Modify and return resource limits of a process atomically. */ ++# ifndef __USE_FILE_OFFSET64 ++extern int prlimit (__pid_t __pid, enum __rlimit_resource __resource, ++ const struct rlimit *__new_limit, ++ struct rlimit *__old_limit) __THROW; ++# else ++# ifdef __REDIRECT_NTH ++extern int __REDIRECT_NTH (prlimit, ++ (__pid_t __pid, enum __rlimit_resource __resource, ++ const struct rlimit *__new_limit, ++ struct rlimit *__old_limit), ++ prlimit64); ++# else ++# define prlimit prlimit64 ++# endif ++# endif ++# ifdef __USE_LARGEFILE64 ++extern int prlimit64 (__pid_t __pid, enum __rlimit_resource __resource, ++ const struct rlimit64 *__new_limit, ++ struct rlimit64 *__old_limit) __THROW; ++# endif ++#endif ++ ++__END_DECLS +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/sigaction.h b/sysdeps/unix/sysv/linux/sw_64/bits/sigaction.h +new file mode 100644 +index 00000000..906d94b7 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/sigaction.h +@@ -0,0 +1,82 @@ ++/* The proper definitions for Linux/Sw_64 sigaction. ++ Copyright (C) 1996-2023 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_SIGACTION_H ++#define _BITS_SIGACTION_H 1 ++ ++#ifndef _SIGNAL_H ++# error "Never include directly; use instead." ++#endif ++ ++/* Structure describing the action to be taken when a signal arrives. */ ++struct sigaction ++{ ++ /* Signal handler. */ ++#if defined __USE_POSIX199309 || defined __USE_XOPEN_EXTENDED ++ union ++ { ++ /* Used if SA_SIGINFO is not set. */ ++ __sighandler_t sa_handler; ++ /* Used if SA_SIGINFO is set. */ ++ void (*sa_sigaction) (int, siginfo_t *, void *); ++ } __sigaction_handler; ++# define sa_handler __sigaction_handler.sa_handler ++# define sa_sigaction __sigaction_handler.sa_sigaction ++#else ++ __sighandler_t sa_handler; ++#endif ++ ++ /* Additional set of signals to be blocked. */ ++ __sigset_t sa_mask; ++ ++ /* Special flags. */ ++ int sa_flags; ++}; ++ ++/* Bits in `sa_flags'. */ ++#define SA_NOCLDSTOP 0x00000004 /* Don't send SIGCHLD when children stop. */ ++#define SA_NOCLDWAIT 0x00000020 /* Don't create zombie on child death. */ ++#define SA_SIGINFO \ ++ 0x00000040 /* Invoke signal-catching function with \ ++ three arguments instead of one. */ ++#if defined __USE_XOPEN_EXTENDED || defined __USE_MISC ++# define SA_ONSTACK 0x00000001 /* Use signal stack by using `sa_restorer'. \ ++ */ ++#endif ++#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 ++# define SA_RESTART 0x00000002 /* Restart syscall on signal return. */ ++# define SA_NODEFER \ ++ 0x00000008 /* Don't automatically block the signal \ ++ when its handler is being executed. */ ++# define SA_RESETHAND 0x00000010 /* Reset to SIG_DFL on entry to handler. */ ++#endif ++#ifdef __USE_MISC ++# define SA_INTERRUPT 0x20000000 /* Historical no-op. */ ++ ++/* Some aliases for the SA_ constants. */ ++# define SA_NOMASK SA_NODEFER ++# define SA_ONESHOT SA_RESETHAND ++# define SA_STACK SA_ONSTACK ++#endif ++ ++/* Values for the HOW argument to `sigprocmask'. */ ++#define SIG_BLOCK 1 /* Block signals. */ ++#define SIG_UNBLOCK 2 /* Unblock signals. */ ++#define SIG_SETMASK 3 /* Set the set of blocked signals. */ ++ ++#endif +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/signalfd.h b/sysdeps/unix/sysv/linux/sw_64/bits/signalfd.h +new file mode 100644 +index 00000000..9474ffe3 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/signalfd.h +@@ -0,0 +1,30 @@ ++/* Copyright (C) 2007-2023 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_SIGNALFD_H ++# error \ ++ "Never use directly; include instead." ++#endif ++ ++/* Flags for signalfd. */ ++enum ++{ ++ SFD_CLOEXEC = 010000000, ++#define SFD_CLOEXEC SFD_CLOEXEC ++ SFD_NONBLOCK = 000000004 ++#define SFD_NONBLOCK SFD_NONBLOCK ++}; +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/signum-arch.h b/sysdeps/unix/sysv/linux/sw_64/bits/signum-arch.h +new file mode 100644 +index 00000000..e36c7e86 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/signum-arch.h +@@ -0,0 +1,67 @@ ++/* Signal number definitions. Linux/Sw_64 version. ++ Copyright (C) 1996-2023 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_SIGNUM_ARCH_H ++#define _BITS_SIGNUM_ARCH_H 1 ++ ++#ifndef _SIGNAL_H ++# error "Never include directly; use instead." ++#endif ++ ++/* Adjustments and additions to the signal number constants for ++ Linux/Sw_64. Signal values on this platform were chosen for OSF/1 ++ binary compatibility, and are therefore almost identical to the ++ BSD-derived defaults. */ ++ ++#define SIGEMT 7 /* Emulator trap (4.2 BSD). */ ++#define SIGINFO 29 /* Information request (BSD). */ ++#define SIGPWR SIGINFO /* Power failure imminent (System V). */ ++ ++/* Historical signals specified by POSIX. */ ++#define SIGBUS 10 /* Bus error. */ ++#define SIGSYS 12 /* Bad system call. */ ++ ++/* New(er) POSIX signals (1003.1-2008, 1003.1-2013). */ ++#define SIGURG 16 /* Urgent data is available at a socket. */ ++#define SIGSTOP 17 /* Stop, unblockable. */ ++#define SIGTSTP 18 /* Keyboard stop. */ ++#define SIGCONT 19 /* Continue. */ ++#define SIGCHLD 20 /* Child terminated or stopped. */ ++#define SIGTTIN 21 /* Background read from control terminal. */ ++#define SIGTTOU 22 /* Background write to control terminal. */ ++#define SIGPOLL 23 /* Pollable event occurred (System V). */ ++#define SIGXCPU 24 /* CPU time limit exceeded. */ ++#define SIGVTALRM 26 /* Virtual timer expired. */ ++#define SIGPROF 27 /* Profiling timer expired. */ ++#define SIGXFSZ 25 /* File size limit exceeded. */ ++#define SIGUSR1 30 /* User-defined signal 1. */ ++#define SIGUSR2 31 /* User-defined signal 2. */ ++ ++/* Nonstandard signals found in all modern POSIX systems ++ (including both BSD and Linux). */ ++#define SIGWINCH 28 ++ ++/* Archaic names for compatibility. */ ++#define SIGIO SIGPOLL /* I/O now possible (4.2 BSD). */ ++#define SIGIOT SIGABRT /* IOT instruction, abort() on a PDP-11. */ ++#define SIGCLD SIGCHLD /* Old System V name */ ++ ++#define __SIGRTMIN 32 ++#define __SIGRTMAX 64 ++ ++#endif /* included. */ +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/sigstack.h b/sysdeps/unix/sysv/linux/sw_64/bits/sigstack.h +new file mode 100644 +index 00000000..7af301ff +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/sigstack.h +@@ -0,0 +1,32 @@ ++/* sigstack, sigaltstack definitions. ++ Copyright (C) 1998-2023 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_SIGSTACK_H ++#define _BITS_SIGSTACK_H 1 ++ ++#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H ++# error "Never include this file directly. Use instead" ++#endif ++ ++/* Minimum stack size for a signal handler. */ ++#define MINSIGSTKSZ 4096 ++ ++/* System default stack size. */ ++#define SIGSTKSZ 16384 ++ ++#endif /* bits/sigstack.h */ +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/socket-constants.h b/sysdeps/unix/sysv/linux/sw_64/bits/socket-constants.h +new file mode 100644 +index 00000000..cb1b5bec +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/socket-constants.h +@@ -0,0 +1,51 @@ ++/* Socket constants which vary among Linux architectures. Version for sw_64. ++ Copyright (C) 2019-2023 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_SOCKET_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++#define SOL_SOCKET 65535 ++#define SO_ACCEPTCONN 4116 ++#define SO_BROADCAST 32 ++#define SO_DONTROUTE 16 ++#define SO_ERROR 4103 ++#define SO_KEEPALIVE 8 ++#define SO_LINGER 128 ++#define SO_OOBINLINE 256 ++#define SO_RCVBUF 4098 ++#define SO_RCVLOWAT 4112 ++#define SO_RCVTIMEO 4114 ++#define SO_REUSEADDR 4 ++#define SO_SNDBUF 4097 ++#define SO_SNDLOWAT 4113 ++#define SO_SNDTIMEO 4115 ++#define SO_TYPE 4104 ++ ++#define SO_RCVTIMEO_OLD 4114 ++#define SO_SNDTIMEO_OLD 4115 ++#define SO_RCVTIMEO_NEW 66 ++#define SO_SNDTIMEO_NEW 67 ++ ++#define SO_TIMESTAMP_OLD 29 ++#define SO_TIMESTAMPNS_OLD 35 ++#define SO_TIMESTAMPING_OLD 37 ++#define SO_TIMESTAMP_NEW 63 ++#define SO_TIMESTAMPNS_NEW 64 ++#define SO_TIMESTAMPING_NEW 65 +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/socket_type.h b/sysdeps/unix/sysv/linux/sw_64/bits/socket_type.h +new file mode 100644 +index 00000000..64452402 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/socket_type.h +@@ -0,0 +1,56 @@ ++/* Define enum __socket_type for Linux/Sw_64. ++ Copyright (C) 1991-2023 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_SOCKET_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++/* Types of sockets. */ ++enum __socket_type ++{ ++ SOCK_STREAM = 1, /* Sequenced, reliable, connection-based ++ byte streams. */ ++#define SOCK_STREAM SOCK_STREAM ++ SOCK_DGRAM = 2, /* Connectionless, unreliable datagrams ++ of fixed maximum length. */ ++#define SOCK_DGRAM SOCK_DGRAM ++ SOCK_RAW = 3, /* Raw protocol interface. */ ++#define SOCK_RAW SOCK_RAW ++ SOCK_RDM = 4, /* Reliably-delivered messages. */ ++#define SOCK_RDM SOCK_RDM ++ SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based, ++ datagrams of fixed maximum length. */ ++#define SOCK_SEQPACKET SOCK_SEQPACKET ++ SOCK_DCCP = 6, /* Datagram Congestion Control Protocol. */ ++#define SOCK_DCCP SOCK_DCCP ++ SOCK_PACKET = 10, /* Linux specific way of getting packets ++ at the dev level. For writing rarp and ++ other similar things on the user level. */ ++#define SOCK_PACKET SOCK_PACKET ++ ++ /* Flags to be ORed into the type parameter of socket and socketpair and ++ used for the flags parameter of paccept. */ ++ ++ SOCK_CLOEXEC = 010000000, /* Atomically set close-on-exec flag for the ++ new descriptor(s). */ ++#define SOCK_CLOEXEC SOCK_CLOEXEC ++ SOCK_NONBLOCK = 0x40000000 /* Atomically mark descriptor(s) as ++ non-blocking. */ ++#define SOCK_NONBLOCK SOCK_NONBLOCK ++}; +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/statfs.h b/sysdeps/unix/sysv/linux/sw_64/bits/statfs.h +new file mode 100644 +index 00000000..72c3f457 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/statfs.h +@@ -0,0 +1,64 @@ ++/* Copyright (C) 1997-2023 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_STATFS_H ++# error "Never include directly; use instead." ++#endif ++ ++#include /* for __fsid_t and __fsblkcnt_t. */ ++ ++#ifndef __statfs_word ++# define __statfs_word long ++#endif ++ ++struct statfs ++{ ++ __statfs_word f_type; ++ __statfs_word f_bsize; ++ __statfs_word f_blocks; ++ __statfs_word f_bfree; ++ __statfs_word f_bavail; ++ __statfs_word f_files; ++ __statfs_word f_ffree; ++ __fsid_t f_fsid; ++ __statfs_word f_namelen; ++ __statfs_word f_frsize; ++ __statfs_word f_flags; ++ __statfs_word f_spare[4]; ++}; ++ ++#ifdef __USE_LARGEFILE64 ++struct statfs64 ++{ ++ __statfs_word f_type; ++ __statfs_word f_bsize; ++ __fsblkcnt64_t f_blocks; ++ __fsblkcnt64_t f_bfree; ++ __fsblkcnt64_t f_bavail; ++ __fsfilcnt64_t f_files; ++ __fsfilcnt64_t f_ffree; ++ __fsid_t f_fsid; ++ __statfs_word f_namelen; ++ __statfs_word f_frsize; ++ __statfs_word f_flags; ++ __statfs_word f_spare[4]; ++}; ++#endif ++ ++/* Tell code we have this member. */ ++#define _STATFS_F_NAMELEN ++#define _STATFS_F_FRSIZE +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sw_64/bits/struct_stat.h +new file mode 100644 +index 00000000..f5de6cb1 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/struct_stat.h +@@ -0,0 +1,119 @@ ++/* Definition for struct stat. ++ Copyright (C) 2020-2023 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 !defined _SYS_STAT_H && !defined _FCNTL_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++#ifndef _BITS_STRUCT_STAT_H ++# define _BITS_STRUCT_STAT_H 1 ++ ++struct stat ++{ ++ __dev_t st_dev; /* Device. */ ++# if (defined __USE_FILE_OFFSET64 || defined __sw_64__) /* mod */ ++ __ino64_t st_ino; /* File serial number. */ ++# else ++ __ino_t st_ino; /* File serial number. */ ++ int __pad0; /* 64-bit st_ino. */ ++# endif ++ __dev_t st_rdev; /* Device number, if device. */ ++ __off_t st_size; /* Size of file, in bytes. */ ++# ifdef __USE_FILE_OFFSET64 ++ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ ++# else ++ __blkcnt_t st_blocks; /* Nr. 512-byte blocks allocated. */ ++ int __pad1; /* 64-bit st_blocks. */ ++# endif ++ __mode_t st_mode; /* File mode. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ __nlink_t st_nlink; /* Link count. */ ++ int __pad2; /* Real padding. */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ long __glibc_reserved[3]; ++}; ++ ++# ifdef __USE_LARGEFILE64 ++/* Note stat64 is the same shape as stat. */ ++struct stat64 ++{ ++ __dev_t st_dev; /* Device. */ ++ __ino64_t st_ino; /* File serial number. */ ++ __dev_t st_rdev; /* Device number, if device. */ ++ __off_t st_size; /* Size of file, in bytes. */ ++ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ ++ __mode_t st_mode; /* File mode. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ __nlink_t st_nlink; /* Link count. */ ++ int __pad0; /* Real padding. */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ long __glibc_reserved[3]; ++}; ++# endif ++ ++/* Tell code we have these members. */ ++# define _STATBUF_ST_BLKSIZE ++# define _STATBUF_ST_RDEV ++# define _STATBUF_ST_NSEC ++ ++#endif /* _BITS_STRUCT_STAT_H */ +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/termios-baud.h b/sysdeps/unix/sysv/linux/sw_64/bits/termios-baud.h +new file mode 100644 +index 00000000..675ee821 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/termios-baud.h +@@ -0,0 +1,47 @@ ++/* termios baud rate selection definitions. Linux/sw_64 version. ++ Copyright (C) 2019-2023 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 _TERMIOS_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++#ifdef __USE_MISC ++# define CBAUD 0000037 ++# define CBAUDEX 0000000 ++# define CMSPAR 010000000000 /* mark or space (stick) parity */ ++# define CRTSCTS 020000000000 /* flow control */ ++#endif ++ ++#define B57600 00020 ++#define B115200 00021 ++#define B230400 00022 ++#define B460800 00023 ++#define B500000 00024 ++#define B576000 00025 ++#define B921600 00026 ++#define B1000000 00027 ++#define B1152000 00030 ++#define B1500000 00031 ++#define B2000000 00032 ++#define B2500000 00033 ++#define B3000000 00034 ++#define B3500000 00035 ++#define B4000000 00036 ++ ++#define __MAX_BAUD B4000000 +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_cc.h b/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_cc.h +new file mode 100644 +index 00000000..19728cf3 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_cc.h +@@ -0,0 +1,41 @@ ++/* termios c_cc symbolic constant definitions. Linux/sw_64 version. ++ Copyright (C) 2019-2023 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 _TERMIOS_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++/* c_cc characters */ ++#define VEOF 0 ++#define VEOL 1 ++#define VEOL2 2 ++#define VERASE 3 ++#define VWERASE 4 ++#define VKILL 5 ++#define VREPRINT 6 ++#define VSWTC 7 ++#define VINTR 8 ++#define VQUIT 9 ++#define VSUSP 10 ++#define VSTART 12 ++#define VSTOP 13 ++#define VLNEXT 14 ++#define VDISCARD 15 ++#define VMIN 16 ++#define VTIME 17 +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_cflag.h b/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_cflag.h +new file mode 100644 +index 00000000..e852f6e2 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_cflag.h +@@ -0,0 +1,39 @@ ++/* termios control mode definitions. Linux/sw_64 version. ++ Copyright (C) 2019-2023 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 _TERMIOS_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++#define CSIZE 00001400 ++#define CS5 00000000 ++#define CS6 00000400 ++#define CS7 00001000 ++#define CS8 00001400 ++ ++#define CSTOPB 00002000 ++#define CREAD 00004000 ++#define PARENB 00010000 ++#define PARODD 00020000 ++#define HUPCL 00040000 ++ ++#define CLOCAL 00100000 ++#ifdef __USE_MISC ++# define ADDRB 04000000000 ++#endif +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_iflag.h b/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_iflag.h +new file mode 100644 +index 00000000..d85fd1e2 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_iflag.h +@@ -0,0 +1,39 @@ ++/* termios input mode definitions. Linux/sw_64 version. ++ Copyright (C) 2019-2023 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 _TERMIOS_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++/* c_iflag bits */ ++#define IGNBRK 0000001 ++#define BRKINT 0000002 ++#define IGNPAR 0000004 ++#define PARMRK 0000010 ++#define INPCK 0000020 ++#define ISTRIP 0000040 ++#define INLCR 0000100 ++#define IGNCR 0000200 ++#define ICRNL 0000400 ++#define IXON 0001000 ++#define IXOFF 0002000 ++#define IXANY 0004000 ++#define IUCLC 0010000 ++#define IMAXBEL 0020000 ++#define IUTF8 0040000 +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_lflag.h b/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_lflag.h +new file mode 100644 +index 00000000..50de240a +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_lflag.h +@@ -0,0 +1,43 @@ ++/* termios local mode definitions. Linux/sw_64 version. ++ Copyright (C) 2019-2023 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 _TERMIOS_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++/* c_lflag bits */ ++#define ISIG 0x00000080 ++#define ICANON 0x00000100 ++#if defined __USE_MISC || (defined __USE_XOPEN && !defined __USE_XOPEN2K) ++# define XCASE 0x00004000 ++#endif ++#define ECHO 0x00000008 ++#define ECHOE 0x00000002 ++#define ECHOK 0x00000004 ++#define ECHONL 0x00000010 ++#define NOFLSH 0x80000000 ++#define TOSTOP 0x00400000 ++#ifdef __USE_MISC ++# define ECHOCTL 0x00000040 ++# define ECHOPRT 0x00000020 ++# define ECHOKE 0x00000001 ++# define FLUSHO 0x00800000 ++# define PENDIN 0x20000000 ++#endif ++#define IEXTEN 0x00000400 +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_oflag.h b/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_oflag.h +new file mode 100644 +index 00000000..bd9eda92 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/termios-c_oflag.h +@@ -0,0 +1,67 @@ ++/* termios output mode definitions. Linux/sw_64 version. ++ Copyright (C) 2019-2023 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 _TERMIOS_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++/* c_oflag bits */ ++#define OPOST 0000001 ++#define ONLCR 0000002 ++#define OLCUC 0000004 ++ ++#define OCRNL 0000010 ++#define ONOCR 0000020 ++#define ONLRET 0000040 ++ ++#define OFILL 00000100 ++#define OFDEL 00000200 ++#if defined __USE_MISC || defined __USE_XOPEN ++# define NLDLY 00001400 ++# define NL0 00000000 ++# define NL1 00000400 ++# if defined __USE_MISC ++# define NL2 00001000 ++# define NL3 00001400 ++# endif ++# define TABDLY 00006000 ++# define TAB0 00000000 ++# define TAB1 00002000 ++# define TAB2 00004000 ++# define TAB3 00006000 ++# define CRDLY 00030000 ++# define CR0 00000000 ++# define CR1 00010000 ++# define CR2 00020000 ++# define CR3 00030000 ++# define FFDLY 00040000 ++# define FF0 00000000 ++# define FF1 00040000 ++# define BSDLY 00100000 ++# define BS0 00000000 ++# define BS1 00100000 ++#endif ++ ++#define VTDLY 00200000 ++#define VT0 00000000 ++#define VT1 00200000 ++ ++#ifdef __USE_MISC ++# define XTABS TAB3 ++#endif +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/termios-struct.h b/sysdeps/unix/sysv/linux/sw_64/bits/termios-struct.h +new file mode 100644 +index 00000000..0c5f0d4c +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/termios-struct.h +@@ -0,0 +1,38 @@ ++/* struct termios definition. Linux/sw_64 version. ++ Copyright (C) 2019-2023 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 _TERMIOS_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++/* SW_64 has C_CC before C_LINE compare to Linux generic definition. */ ++#define NCCS 32 ++struct termios ++{ ++ tcflag_t c_iflag; /* input mode flags */ ++ tcflag_t c_oflag; /* output mode flags */ ++ tcflag_t c_cflag; /* control mode flags */ ++ tcflag_t c_lflag; /* local mode flags */ ++ cc_t c_cc[NCCS]; /* control characters */ ++ cc_t c_line; /* line discipline (== c_cc[33]) */ ++ speed_t c_ispeed; /* input speed */ ++ speed_t c_ospeed; /* output speed */ ++#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1 ++#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1 ++}; +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/timerfd.h b/sysdeps/unix/sysv/linux/sw_64/bits/timerfd.h +new file mode 100644 +index 00000000..a6f1465d +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/timerfd.h +@@ -0,0 +1,30 @@ ++/* Copyright (C) 2008-2023 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_TIMERFD_H ++# error \ ++ "Never use directly; include instead." ++#endif ++ ++/* Bits to be set in the FLAGS parameter of `timerfd_create'. */ ++enum ++{ ++ TFD_CLOEXEC = 010000000, ++#define TFD_CLOEXEC TFD_CLOEXEC ++ TFD_NONBLOCK = 000000004 ++#define TFD_NONBLOCK TFD_NONBLOCK ++}; +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/typesizes.h b/sysdeps/unix/sysv/linux/sw_64/bits/typesizes.h +new file mode 100644 +index 00000000..64eb96f3 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/typesizes.h +@@ -0,0 +1,87 @@ ++/* bits/typesizes.h -- underlying types for *_t. Linux/Sw_64 version. ++ Copyright (C) 2002-2023 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_TYPES_H ++# error \ ++ "Never include directly; use instead." ++#endif ++ ++#ifndef _BITS_TYPESIZES_H ++# define _BITS_TYPESIZES_H 1 ++ ++/* See for the meaning of these macros. This file exists so ++ that need not vary across different GNU platforms. */ ++ ++# define __DEV_T_TYPE __U64_TYPE ++# define __UID_T_TYPE __U32_TYPE ++# define __GID_T_TYPE __U32_TYPE ++# define __INO_T_TYPE __U64_TYPE ++# define __INO64_T_TYPE __U64_TYPE ++# define __MODE_T_TYPE __U32_TYPE ++# define __NLINK_T_TYPE __U32_TYPE ++# define __OFF_T_TYPE __SLONGWORD_TYPE ++# define __OFF64_T_TYPE __S64_TYPE ++# define __PID_T_TYPE __S32_TYPE ++# define __RLIM_T_TYPE __ULONGWORD_TYPE ++# define __RLIM64_T_TYPE __U64_TYPE ++# define __BLKCNT_T_TYPE __U32_TYPE ++# define __BLKCNT64_T_TYPE __U64_TYPE ++# define __FSBLKCNT_T_TYPE __S32_TYPE ++# define __FSBLKCNT64_T_TYPE __S64_TYPE ++# define __FSFILCNT_T_TYPE __U32_TYPE ++# define __FSFILCNT64_T_TYPE __U64_TYPE ++# define __ID_T_TYPE __U32_TYPE ++# define __CLOCK_T_TYPE __SLONGWORD_TYPE ++# define __TIME_T_TYPE __SLONGWORD_TYPE ++# define __USECONDS_T_TYPE __U32_TYPE ++# define __SUSECONDS_T_TYPE __S64_TYPE ++# define __SUSECONDS64_T_TYPE __S64_TYPE ++# define __DADDR_T_TYPE __S32_TYPE ++# define __KEY_T_TYPE __S32_TYPE ++# define __CLOCKID_T_TYPE __S32_TYPE ++# define __TIMER_T_TYPE void * ++# define __BLKSIZE_T_TYPE __U32_TYPE ++# define __FSID_T_TYPE \ ++ struct \ ++ { \ ++ int __val[2]; \ ++ } ++# define __SSIZE_T_TYPE __SWORD_TYPE ++# define __SYSCALL_SLONG_TYPE __SLONGWORD_TYPE ++# define __SYSCALL_ULONG_TYPE __ULONGWORD_TYPE ++# define __CPU_MASK_TYPE __ULONGWORD_TYPE ++# define __FSWORD_T_TYPE __S32_TYPE ++ ++/* Tell the libc code that off_t and off64_t are actually the same type ++ for all ABI purposes, even if possibly expressed as different base types ++ for C type-checking purposes. */ ++# define __OFF_T_MATCHES_OFF64_T 1 ++ ++/* And for __rlim_t and __rlim64_t. */ ++# define __RLIM_T_MATCHES_RLIM64_T 1 ++ ++/* Not for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t. */ ++# define __STATFS_MATCHES_STATFS64 0 ++ ++/* And for getitimer, setitimer and rusage */ ++# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1 ++ ++/* Number of descriptors that can fit in an `fd_set'. */ ++# define __FD_SETSIZE 1024 ++ ++#endif /* bits/typesizes.h */ +diff --git a/sysdeps/unix/sysv/linux/sw_64/bits/wordsize.h b/sysdeps/unix/sysv/linux/sw_64/bits/wordsize.h +new file mode 100644 +index 00000000..36e67434 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/bits/wordsize.h +@@ -0,0 +1,19 @@ ++/* Copyright (C) 1999-2023 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 ++ . */ ++ ++#define __WORDSIZE 64 ++#define __WORDSIZE_TIME64_COMPAT32 0 +diff --git a/sysdeps/unix/sysv/linux/sw_64/brk_call.h b/sysdeps/unix/sysv/linux/sw_64/brk_call.h +new file mode 100644 +index 00000000..67419149 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/brk_call.h +@@ -0,0 +1,27 @@ ++/* Invoke the brk system call. Sw_64 version. ++ Copyright (C) 2023 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 ++ . */ ++ ++static inline void * ++__brk_call (void *addr) ++{ ++ unsigned long int result = INTERNAL_SYSCALL_CALL (brk, addr); ++ if (result == -ENOMEM) ++ /* Mimic the default error reporting behavior. */ ++ result = INTERNAL_SYSCALL_CALL (brk, 0); ++ return (void *) result; ++} +diff --git a/sysdeps/unix/sysv/linux/sw_64/dl-auxv.h b/sysdeps/unix/sysv/linux/sw_64/dl-auxv.h +new file mode 100644 +index 00000000..5f1d7b71 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/dl-auxv.h +@@ -0,0 +1,40 @@ ++/* Auxiliary vector processing for Linux/Sw_64. ++ Copyright (C) 2007-2023 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 ++ . */ ++ ++/* Scan the Aux Vector for the cache shape entries. */ ++ ++extern long __libc_sw_64_cache_shape[4]; ++#define DL_PLATFORM_AUXV \ ++ __libc_sw_64_cache_shape[0] = auxv_values[AT_L1I_CACHESHAPE]; \ ++ __libc_sw_64_cache_shape[1] = auxv_values[AT_L1D_CACHESHAPE]; \ ++ __libc_sw_64_cache_shape[2] = auxv_values[AT_L2_CACHESHAPE]; \ ++ __libc_sw_64_cache_shape[3] = auxv_values[AT_L3_CACHESHAPE]; ++/*#define DL_PLATFORM_AUXV \ ++ case AT_L1I_CACHESHAPE: \ ++ __libc_sw_64_cache_shape[0] = av->a_un.a_val; \ ++ break; \ ++ case AT_L1D_CACHESHAPE: \ ++ __libc_sw_64_cache_shape[1] = av->a_un.a_val; \ ++ break; \ ++ case AT_L2_CACHESHAPE: \ ++ __libc_sw_64_cache_shape[2] = av->a_un.a_val; \ ++ break; \ ++ case AT_L3_CACHESHAPE: \ ++ __libc_sw_64_cache_shape[3] = av->a_un.a_val; \ ++ break; ++*/ +diff --git a/sysdeps/unix/sysv/linux/sw_64/dl-support.c b/sysdeps/unix/sysv/linux/sw_64/dl-support.c +new file mode 100644 +index 00000000..29021767 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/dl-support.c +@@ -0,0 +1,2 @@ ++#include "dl-auxv.h" ++#include +diff --git a/sysdeps/unix/sysv/linux/sw_64/dl-sysdep.c b/sysdeps/unix/sysv/linux/sw_64/dl-sysdep.c +new file mode 100644 +index 00000000..be352fd9 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/dl-sysdep.c +@@ -0,0 +1,5 @@ ++#include "dl-auxv.h" ++ ++long __libc_sw_64_cache_shape[4] = { -2, -2, -2, -2 }; ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/sw_64/errlist-compat.c b/sysdeps/unix/sysv/linux/sw_64/errlist-compat.c +new file mode 100644 +index 00000000..284ce7c5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/errlist-compat.c +@@ -0,0 +1,43 @@ ++/* Linux sys_errlist compat symbol definitions. Sw_64 version. ++ Copyright (C) 2020-2023 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 ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) ++DEFINE_COMPAT_ERRLIST (131, GLIBC_2_0) ++#endif ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3) ++DEFINE_COMPAT_ERRLIST (131, GLIBC_2_1) ++#endif ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_4) ++DEFINE_COMPAT_ERRLIST (132, GLIBC_2_3) ++#endif ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_4, GLIBC_2_12) ++DEFINE_COMPAT_ERRLIST (138, GLIBC_2_4) ++#endif ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_12, GLIBC_2_16) ++DEFINE_COMPAT_ERRLIST (139, GLIBC_2_12) ++#endif ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_16, GLIBC_2_32) ++DEFINE_COMPAT_ERRLIST (140, GLIBC_2_16) ++#endif +diff --git a/sysdeps/unix/sysv/linux/sw_64/fraiseexcpt.S b/sysdeps/unix/sysv/linux/sw_64/fraiseexcpt.S +new file mode 100644 +index 00000000..c3c8b710 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/fraiseexcpt.S +@@ -0,0 +1,58 @@ ++/* Copyright (C) 2004-2023 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 "kernel_sysinfo.h" ++ ++ ++ .text ++ ++ENTRY(__feraiseexcept) ++ cfi_startproc ++ PSEUDO_PROLOGUE ++ ++ ldi sp, -16(sp) ++ cfi_adjust_cfa_offset (16) ++ ++ ldi v0, __NR_setsysinfo ++ stl a0, 0(sp) ++ mov sp, a1 ++ ldi a0, SSI_IEEE_RAISE_EXCEPTION ++ sys_call HMC_callsys ++ ++ ldi sp, 16(sp) ++ cfi_adjust_cfa_offset (-16) ++ ++ /* Here in libm we can't use SYSCALL_ERROR_LABEL. Nor is it clear ++ that we'd want to set errno anyway. All we're required to do is ++ return non-zero on error. Which is exactly A3. */ ++ mov a3, v0 ++ ret ++ ++END(__feraiseexcept) ++ cfi_endproc ++ ++#if IS_IN (libm) ++# include ++# if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) ++strong_alias (__feraiseexcept, __old_feraiseexcept) ++compat_symbol (libm, __old_feraiseexcept, feraiseexcept, GLIBC_2_1); ++# endif ++libm_hidden_def (__feraiseexcept) ++libm_hidden_ver (__feraiseexcept, feraiseexcept) ++versioned_symbol (libm, __feraiseexcept, feraiseexcept, GLIBC_2_2); ++#endif +diff --git a/sysdeps/unix/sysv/linux/sw_64/fstatfs.c b/sysdeps/unix/sysv/linux/sw_64/fstatfs.c +new file mode 100644 +index 00000000..bb184148 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/fstatfs.c +@@ -0,0 +1,29 @@ ++/* Get filesystem statistics. Linux/sw_64. ++ Copyright (C) 2011-2023 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 ++ ++/* Return information about the filesystem on which FD resides. */ ++int ++__fstatfs (int fd, struct statfs *buf) ++{ ++ return INLINE_SYSCALL_CALL (fstatfs, fd, buf); ++} ++libc_hidden_def (__fstatfs) weak_alias (__fstatfs, fstatfs) +diff --git a/sysdeps/unix/sysv/linux/sw_64/fxstat64.c b/sysdeps/unix/sysv/linux/sw_64/fxstat64.c +new file mode 100644 +index 00000000..df56314b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/fxstat64.c +@@ -0,0 +1,45 @@ ++/* fxstat64 using old-style Unix stat system call. ++ Copyright (C) 2004-2023 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 ++ . */ ++ ++#define __fxstat __redirect___fxstat64 ++#include ++#undef __fxstat ++#include ++#include ++#include ++ ++/* Get information about the file NAME in BUF. */ ++int ++__fxstat64 (int vers, int fd, struct stat64 *buf) ++{ ++ switch (vers) ++ { ++ case _STAT_VER_KERNEL64: ++ return INLINE_SYSCALL_CALL (fstat64, fd, buf); ++ ++ default: ++ { ++ struct kernel_stat kbuf; ++ int r = INTERNAL_SYSCALL_CALL (fstat, fd, &kbuf); ++ if (r == 0) ++ return __xstat_conv (vers, &kbuf, buf); ++ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r); ++ } ++ } ++} ++strong_alias (__fxstat64, __fxstat); +diff --git a/sysdeps/unix/sysv/linux/sw_64/fxstatat64.c b/sysdeps/unix/sysv/linux/sw_64/fxstatat64.c +new file mode 100644 +index 00000000..a274b0db +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/fxstatat64.c +@@ -0,0 +1,32 @@ ++/* fxstat using old-style Unix stat system call. ++ Copyright (C) 2004-2023 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 ++ . */ ++ ++#define __fxstatat __redirect___fxstatat64 ++#include ++#undef __fxstatat ++#include ++#include ++#include ++ ++/* Get information about the file NAME in BUF. */ ++int ++__fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag) ++{ ++ return INLINE_SYSCALL_CALL (fstatat64, fd, file, st, flag); ++} ++strong_alias (__fxstatat64, __fxstatat); +diff --git a/sysdeps/unix/sysv/linux/sw_64/getclktck.c b/sysdeps/unix/sysv/linux/sw_64/getclktck.c +new file mode 100644 +index 00000000..111fad85 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/getclktck.c +@@ -0,0 +1,2 @@ ++#define SYSTEM_CLK_TCK 1024 ++#include +diff --git a/sysdeps/unix/sysv/linux/sw_64/getcontext.S b/sysdeps/unix/sysv/linux/sw_64/getcontext.S +new file mode 100644 +index 00000000..f1cc76f2 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/getcontext.S +@@ -0,0 +1,440 @@ ++/* Save current context. ++ Copyright (C) 2004-2023 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 ++ ++/* ??? Should be a better place for this that's asm friendly. */ ++#define SIG_BLOCK 1 ++ ++ ++ENTRY (__getcontext) ++#ifdef PROF ++ ldgp gp, 0(pv) ++ .set noat ++ ldi AT, _mcount ++ call AT, (AT), _mcount ++ .set at ++ .prologue 1 ++#else ++ .prologue 0 ++#endif ++ ++ bsr $0, __getcontext_x ++ mov $31, $0 ++ ret ++ ++END(__getcontext) ++weak_alias (__getcontext, getcontext) ++ ++ ++/* An internal routine used by getcontext and setcontext. ++ The incomming return address register is $0. */ ++ ++ .align 4 ++ .globl __getcontext_x ++ .hidden __getcontext_x ++ .usepv __getcontext_x, no ++ ++ cfi_startproc ++ cfi_return_column (64) ++__getcontext_x: ++ cfi_register (64, 0) ++ ++ .set noat ++ ++ /* Return value of getcontext. $0 is the only register ++ whose value is not preserved. */ ++ stl $31, UC_SIGCTX+SC_REGS($16) ++ ++ /* Store all registers into the context. */ ++ stl $1, UC_SIGCTX+SC_REGS+1*8($16) ++ stl $2, UC_SIGCTX+SC_REGS+2*8($16) ++ stl $3, UC_SIGCTX+SC_REGS+3*8($16) ++ stl $4, UC_SIGCTX+SC_REGS+4*8($16) ++ stl $5, UC_SIGCTX+SC_REGS+5*8($16) ++ stl $6, UC_SIGCTX+SC_REGS+6*8($16) ++ stl $7, UC_SIGCTX+SC_REGS+7*8($16) ++ stl $8, UC_SIGCTX+SC_REGS+8*8($16) ++ stl $9, UC_SIGCTX+SC_REGS+9*8($16) ++ stl $10, UC_SIGCTX+SC_REGS+10*8($16) ++ stl $11, UC_SIGCTX+SC_REGS+11*8($16) ++ stl $12, UC_SIGCTX+SC_REGS+12*8($16) ++ stl $13, UC_SIGCTX+SC_REGS+13*8($16) ++ stl $14, UC_SIGCTX+SC_REGS+14*8($16) ++ stl $15, UC_SIGCTX+SC_REGS+15*8($16) ++ stl $16, UC_SIGCTX+SC_REGS+16*8($16) ++ stl $17, UC_SIGCTX+SC_REGS+17*8($16) ++ stl $18, UC_SIGCTX+SC_REGS+18*8($16) ++ stl $19, UC_SIGCTX+SC_REGS+19*8($16) ++ stl $20, UC_SIGCTX+SC_REGS+20*8($16) ++ stl $21, UC_SIGCTX+SC_REGS+21*8($16) ++ stl $22, UC_SIGCTX+SC_REGS+22*8($16) ++ stl $23, UC_SIGCTX+SC_REGS+23*8($16) ++ stl $24, UC_SIGCTX+SC_REGS+24*8($16) ++ stl $25, UC_SIGCTX+SC_REGS+25*8($16) ++ stl $26, UC_SIGCTX+SC_REGS+26*8($16) ++ stl $27, UC_SIGCTX+SC_REGS+27*8($16) ++ stl $28, UC_SIGCTX+SC_REGS+28*8($16) ++ stl $29, UC_SIGCTX+SC_REGS+29*8($16) ++ stl $30, UC_SIGCTX+SC_REGS+30*8($16) ++ stl $31, UC_SIGCTX+SC_REGS+31*8($16) ++#ifndef SW_64 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+1*8($16) ++ srlow $f0, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+2*8($16) ++ srlow $f0, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+3*8($16) ++ srlow $f0, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+4*8($16) ++ ++ fstd $f1, UC_SIGCTX+SC_FPREGS+5*8($16) ++ srlow $f1, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+6*8($16) ++ srlow $f1, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+7*8($16) ++ srlow $f1, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+8*8($16) ++ ++ fstd $f2, UC_SIGCTX+SC_FPREGS+9*8($16) ++ srlow $f2, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+10*8($16) ++ srlow $f0, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+11*8($16) ++ srlow $f0, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+12*8($16) ++ ++ fstd $f3, UC_SIGCTX+SC_FPREGS+13*8($16) ++ srlow $f3, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+14*8($16) ++ srlow $f1, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+15*8($16) ++ srlow $f1, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+16*8($16) ++ ++ fstd $f4, UC_SIGCTX+SC_FPREGS+17*8($16) ++ srlow $f4, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+18*8($16) ++ srlow $f0, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+19*8($16) ++ srlow $f0, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+20*8($16) ++ ++ fstd $f5, UC_SIGCTX+SC_FPREGS+21*8($16) ++ srlow $f5, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+22*8($16) ++ srlow $f1, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+23*8($16) ++ srlow $f1, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+24*8($16) ++ ++ fstd $f6, UC_SIGCTX+SC_FPREGS+25*8($16) ++ srlow $f6, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+26*8($16) ++ srlow $f0, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+27*8($16) ++ srlow $f0, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+28*8($16) ++ ++ fstd $f7, UC_SIGCTX+SC_FPREGS+29*8($16) ++ srlow $f7, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+30*8($16) ++ srlow $f1, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+31*8($16) ++ srlow $f1, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+32*8($16) ++ ++ fstd $f8, UC_SIGCTX+SC_FPREGS+33*8($16) ++ srlow $f8, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+34*8($16) ++ srlow $f0, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+35*8($16) ++ srlow $f0, 0x40, $f0 ++ fstd $f0, UC_SIGCTX+SC_FPREGS+36*8($16) ++ ++ fstd $f9, UC_SIGCTX+SC_FPREGS+37*8($16) ++ srlow $f9, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+38*8($16) ++ srlow $f1, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+39*8($16) ++ srlow $f1, 0x40, $f1 ++ fstd $f1, UC_SIGCTX+SC_FPREGS+40*8($16) ++ ++ fstd $f10, UC_SIGCTX+SC_FPREGS+41*8($16) ++ srlow $f10, 0x40, $f10 ++ fstd $f10, UC_SIGCTX+SC_FPREGS+42*8($16) ++ srlow $f10, 0x40, $f10 ++ fstd $f10, UC_SIGCTX+SC_FPREGS+43*8($16) ++ srlow $f10, 0x40, $f10 ++ fstd $f10, UC_SIGCTX+SC_FPREGS+44*8($16) ++ ++ fstd $f11, UC_SIGCTX+SC_FPREGS+45*8($16) ++ srlow $f11, 0x40, $f11 ++ fstd $f11, UC_SIGCTX+SC_FPREGS+46*8($16) ++ srlow $f11, 0x40, $f11 ++ fstd $f11, UC_SIGCTX+SC_FPREGS+47*8($16) ++ srlow $f11, 0x40, $f11 ++ fstd $f11, UC_SIGCTX+SC_FPREGS+48*8($16) ++ ++ fstd $f12, UC_SIGCTX+SC_FPREGS+49*8($16) ++ srlow $f12, 0x40, $f12 ++ fstd $f12, UC_SIGCTX+SC_FPREGS+50*8($16) ++ srlow $f12, 0x40, $f12 ++ fstd $f12, UC_SIGCTX+SC_FPREGS+51*8($16) ++ srlow $f12, 0x40, $f12 ++ fstd $f12, UC_SIGCTX+SC_FPREGS+52*8($16) ++ ++ fstd $f13, UC_SIGCTX+SC_FPREGS+53*8($16) ++ srlow $f13, 0x40, $f13 ++ fstd $f13, UC_SIGCTX+SC_FPREGS+54*8($16) ++ srlow $f13, 0x40, $f13 ++ fstd $f13, UC_SIGCTX+SC_FPREGS+55*8($16) ++ srlow $f13, 0x40, $f13 ++ fstd $f13, UC_SIGCTX+SC_FPREGS+56*8($16) ++ ++ fstd $f14, UC_SIGCTX+SC_FPREGS+57*8($16) ++ srlow $f14, 0x40, $f14 ++ fstd $f14, UC_SIGCTX+SC_FPREGS+58*8($16) ++ srlow $f14, 0x40, $f14 ++ fstd $f14, UC_SIGCTX+SC_FPREGS+59*8($16) ++ srlow $f14, 0x40, $f14 ++ fstd $f14, UC_SIGCTX+SC_FPREGS+60*8($16) ++ ++ fstd $f15, UC_SIGCTX+SC_FPREGS+61*8($16) ++ srlow $f15, 0x40, $f15 ++ fstd $f15, UC_SIGCTX+SC_FPREGS+62*8($16) ++ srlow $f15, 0x40, $f15 ++ fstd $f15, UC_SIGCTX+SC_FPREGS+63*8($16) ++ srlow $f15, 0x40, $f15 ++ fstd $f15, UC_SIGCTX+SC_FPREGS+64*8($16) ++ ++ fstd $f16, UC_SIGCTX+SC_FPREGS+65*8($16) ++ srlow $f16, 0x40, $f16 ++ fstd $f16, UC_SIGCTX+SC_FPREGS+66*8($16) ++ srlow $f16, 0x40, $f16 ++ fstd $f16, UC_SIGCTX+SC_FPREGS+67*8($16) ++ srlow $f16, 0x40, $f16 ++ fstd $f16, UC_SIGCTX+SC_FPREGS+68*8($16) ++ ++ fstd $f17, UC_SIGCTX+SC_FPREGS+69*8($16) ++ srlow $f17, 0x40, $f17 ++ fstd $f17, UC_SIGCTX+SC_FPREGS+70*8($16) ++ srlow $f17, 0x40, $f17 ++ fstd $f17, UC_SIGCTX+SC_FPREGS+71*8($16) ++ srlow $f17, 0x40, $f17 ++ fstd $f17, UC_SIGCTX+SC_FPREGS+72*8($16) ++ ++ fstd $f18, UC_SIGCTX+SC_FPREGS+73*8($16) ++ srlow $f18, 0x40, $f18 ++ fstd $f18, UC_SIGCTX+SC_FPREGS+74*8($16) ++ srlow $f18, 0x40, $f18 ++ fstd $f18, UC_SIGCTX+SC_FPREGS+75*8($16) ++ srlow $f18, 0x40, $f18 ++ fstd $f18, UC_SIGCTX+SC_FPREGS+76*8($16) ++ ++ fstd $f19, UC_SIGCTX+SC_FPREGS+77*8($16) ++ srlow $f19, 0x40, $f19 ++ fstd $f19, UC_SIGCTX+SC_FPREGS+78*8($16) ++ srlow $f19, 0x40, $f19 ++ fstd $f19, UC_SIGCTX+SC_FPREGS+79*8($16) ++ srlow $f19, 0x40, $f19 ++ fstd $f19, UC_SIGCTX+SC_FPREGS+80*8($16) ++ ++ fstd $f20, UC_SIGCTX+SC_FPREGS+81*8($16) ++ srlow $f20, 0x40, $f20 ++ fstd $f20, UC_SIGCTX+SC_FPREGS+82*8($16) ++ srlow $f20, 0x40, $f20 ++ fstd $f20, UC_SIGCTX+SC_FPREGS+83*8($16) ++ srlow $f20, 0x40, $f20 ++ fstd $f20, UC_SIGCTX+SC_FPREGS+84*8($16) ++ ++ fstd $f21, UC_SIGCTX+SC_FPREGS+85*8($16) ++ srlow $f21, 0x40, $f21 ++ fstd $f21, UC_SIGCTX+SC_FPREGS+86*8($16) ++ srlow $f21, 0x40, $f21 ++ fstd $f21, UC_SIGCTX+SC_FPREGS+87*8($16) ++ srlow $f21, 0x40, $f21 ++ fstd $f21, UC_SIGCTX+SC_FPREGS+88*8($16) ++ ++ fstd $f22, UC_SIGCTX+SC_FPREGS+89*8($16) ++ srlow $f22, 0x40, $f22 ++ fstd $f22, UC_SIGCTX+SC_FPREGS+90*8($16) ++ srlow $f22, 0x40, $f22 ++ fstd $f22, UC_SIGCTX+SC_FPREGS+91*8($16) ++ srlow $f22, 0x40, $f22 ++ fstd $f22, UC_SIGCTX+SC_FPREGS+92*8($16) ++ ++ fstd $f23, UC_SIGCTX+SC_FPREGS+93*8($16) ++ srlow $f23, 0x40, $f23 ++ fstd $f23, UC_SIGCTX+SC_FPREGS+94*8($16) ++ srlow $f23, 0x40, $f23 ++ fstd $f23, UC_SIGCTX+SC_FPREGS+95*8($16) ++ srlow $f23, 0x40, $f23 ++ fstd $f23, UC_SIGCTX+SC_FPREGS+96*8($16) ++ ++ fstd $f24, UC_SIGCTX+SC_FPREGS+97*8($16) ++ srlow $f24, 0x40, $f24 ++ fstd $f24, UC_SIGCTX+SC_FPREGS+98*8($16) ++ srlow $f24, 0x40, $f24 ++ fstd $f24, UC_SIGCTX+SC_FPREGS+99*8($16) ++ srlow $f24, 0x40, $f24 ++ fstd $f24, UC_SIGCTX+SC_FPREGS+100*8($16) ++ ++ fstd $f25, UC_SIGCTX+SC_FPREGS+101*8($16) ++ srlow $f25, 0x40, $f25 ++ fstd $f25, UC_SIGCTX+SC_FPREGS+102*8($16) ++ srlow $f25, 0x40, $f25 ++ fstd $f25, UC_SIGCTX+SC_FPREGS+103*8($16) ++ srlow $f25, 0x40, $f25 ++ fstd $f25, UC_SIGCTX+SC_FPREGS+104*8($16) ++ ++ fstd $f26, UC_SIGCTX+SC_FPREGS+105*8($16) ++ srlow $f26, 0x40, $f26 ++ fstd $f26, UC_SIGCTX+SC_FPREGS+106*8($16) ++ srlow $f26, 0x40, $f26 ++ fstd $f26, UC_SIGCTX+SC_FPREGS+107*8($16) ++ srlow $f26, 0x40, $f26 ++ fstd $f26, UC_SIGCTX+SC_FPREGS+108*8($16) ++ ++ fstd $f27, UC_SIGCTX+SC_FPREGS+109*8($16) ++ srlow $f27, 0x40, $f27 ++ fstd $f27, UC_SIGCTX+SC_FPREGS+110*8($16) ++ srlow $f27, 0x40, $f27 ++ fstd $f27, UC_SIGCTX+SC_FPREGS+111*8($16) ++ srlow $f27, 0x40, $f27 ++ fstd $f27, UC_SIGCTX+SC_FPREGS+112*8($16) ++ ++ fstd $f28, UC_SIGCTX+SC_FPREGS+113*8($16) ++ srlow $f28, 0x40, $f28 ++ fstd $f28, UC_SIGCTX+SC_FPREGS+114*8($16) ++ srlow $f28, 0x40, $f28 ++ fstd $f28, UC_SIGCTX+SC_FPREGS+115*8($16) ++ srlow $f28, 0x40, $f28 ++ fstd $f28, UC_SIGCTX+SC_FPREGS+116*8($16) ++ ++ fstd $f29, UC_SIGCTX+SC_FPREGS+117*8($16) ++ srlow $f29, 0x40, $f29 ++ fstd $f29, UC_SIGCTX+SC_FPREGS+118*8($16) ++ srlow $f29, 0x40, $f29 ++ fstd $f29, UC_SIGCTX+SC_FPREGS+119*8($16) ++ srlow $f29, 0x40, $f29 ++ fstd $f29, UC_SIGCTX+SC_FPREGS+120*8($16) ++ ++ fstd $f30, UC_SIGCTX+SC_FPREGS+121*8($16) ++ srlow $f30, 0x40, $f30 ++ fstd $f30, UC_SIGCTX+SC_FPREGS+122*8($16) ++ srlow $f30, 0x40, $f30 ++ fstd $f30, UC_SIGCTX+SC_FPREGS+123*8($16) ++ srlow $f30, 0x40, $f30 ++ fstd $f30, UC_SIGCTX+SC_FPREGS+124*8($16) ++#else ++ fstd $f0, UC_SIGCTX+SC_FPREGS+0*8($16) ++ fstd $f1, UC_SIGCTX+SC_FPREGS+1*8($16) ++ fstd $f2, UC_SIGCTX+SC_FPREGS+2*8($16) ++ fstd $f3, UC_SIGCTX+SC_FPREGS+3*8($16) ++ fstd $f4, UC_SIGCTX+SC_FPREGS+4*8($16) ++ fstd $f5, UC_SIGCTX+SC_FPREGS+5*8($16) ++ fstd $f6, UC_SIGCTX+SC_FPREGS+6*8($16) ++ fstd $f7, UC_SIGCTX+SC_FPREGS+7*8($16) ++ fstd $f8, UC_SIGCTX+SC_FPREGS+8*8($16) ++ fstd $f9, UC_SIGCTX+SC_FPREGS+9*8($16) ++ fstd $f10, UC_SIGCTX+SC_FPREGS+10*8($16) ++ fstd $f11, UC_SIGCTX+SC_FPREGS+11*8($16) ++ fstd $f12, UC_SIGCTX+SC_FPREGS+12*8($16) ++ fstd $f13, UC_SIGCTX+SC_FPREGS+13*8($16) ++ fstd $f14, UC_SIGCTX+SC_FPREGS+14*8($16) ++ fstd $f15, UC_SIGCTX+SC_FPREGS+15*8($16) ++ fstd $f16, UC_SIGCTX+SC_FPREGS+16*8($16) ++ fstd $f17, UC_SIGCTX+SC_FPREGS+17*8($16) ++ fstd $f18, UC_SIGCTX+SC_FPREGS+18*8($16) ++ fstd $f19, UC_SIGCTX+SC_FPREGS+19*8($16) ++ fstd $f20, UC_SIGCTX+SC_FPREGS+20*8($16) ++ fstd $f21, UC_SIGCTX+SC_FPREGS+21*8($16) ++ fstd $f22, UC_SIGCTX+SC_FPREGS+22*8($16) ++ fstd $f23, UC_SIGCTX+SC_FPREGS+23*8($16) ++ fstd $f24, UC_SIGCTX+SC_FPREGS+24*8($16) ++ fstd $f25, UC_SIGCTX+SC_FPREGS+25*8($16) ++ fstd $f26, UC_SIGCTX+SC_FPREGS+26*8($16) ++ fstd $f27, UC_SIGCTX+SC_FPREGS+27*8($16) ++ fstd $f28, UC_SIGCTX+SC_FPREGS+28*8($16) ++ fstd $f29, UC_SIGCTX+SC_FPREGS+29*8($16) ++ fstd $f30, UC_SIGCTX+SC_FPREGS+30*8($16) ++ fstd $f31, UC_SIGCTX+SC_FPREGS+31*8($16) ++#endif ++ rfpcr $f0 ++ ldi $1, 8 ++ fstd $f0, UC_SIGCTX+SC_FPCR($16) ++ ++ /* The return address of getcontext is the restart pc. */ ++ stl $26, UC_SIGCTX+SC_PC($16) ++ ++ /* Userlevel always has a processor status word of 8. */ ++ stl $1, UC_SIGCTX+SC_PS($16) ++ ++ /* Save registers around the syscall. We preserve $17 ++ for the benefit of swapcontext. */ ++ subl $30, 4*8, $30 ++ cfi_adjust_cfa_offset (4*8) ++ stl $0, 0($30) ++ cfi_rel_offset (64, 0) ++ stl $16, 8($30) ++ stl $17, 16($30) ++ ++ /* Save the current signal mask. Whee, there are three ++ copies of this in the sw_64 ucontext_t. */ ++/* osf_sigprocmask change to rt_sigprocmask */ ++/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ ++ ldi $19, _NSIG8 ++ ldi $18, UC_SIGMASK($16) ++ ldi $17, 0 ++ ldi $16, SIG_BLOCK ++ ++ ldi $0, __NR_rt_sigprocmask ++ sys_call 0x83 ++ ++ ldl $16, 8($30) ++ ldl $17, 16($30) ++ ++ stl $18, UC_OSF_SIGMASK($16) ++ stl $18, UC_SIGCTX+SC_MASK($16) ++ ++ stl $31, UC_SIGMASK + 1*8($16) ++ stl $31, UC_SIGMASK + 2*8($16) ++ stl $31, UC_SIGMASK + 3*8($16) ++ stl $31, UC_SIGMASK + 4*8($16) ++ stl $31, UC_SIGMASK + 5*8($16) ++ stl $31, UC_SIGMASK + 6*8($16) ++ stl $31, UC_SIGMASK + 7*8($16) ++ stl $31, UC_SIGMASK + 8*8($16) ++ stl $31, UC_SIGMASK + 9*8($16) ++ stl $31, UC_SIGMASK +10*8($16) ++ stl $31, UC_SIGMASK +11*8($16) ++ stl $31, UC_SIGMASK +12*8($16) ++ stl $31, UC_SIGMASK +13*8($16) ++ stl $31, UC_SIGMASK +14*8($16) ++ stl $31, UC_SIGMASK +15*8($16) ++ ++ ldl $0, 0($30) ++ addl $30, 4*8, $30 ++ cfi_register (64, 0) ++ cfi_adjust_cfa_offset (-4*8) ++ ret $31, ($0), 1 ++ ++ cfi_endproc ++ .size __getcontext_x, .-__getcontext_x ++ .type __getcontext_x, @function +diff --git a/sysdeps/unix/sysv/linux/sw_64/getdents.c b/sysdeps/unix/sysv/linux/sw_64/getdents.c +new file mode 100644 +index 00000000..16ca198a +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/getdents.c +@@ -0,0 +1,18 @@ ++/* Although Sw_64 defines _DIRENT_MATCHES_DIRENT64, 'struct dirent' and ++ 'struct dirent64' have slight different internal layout with d_ino ++ being a __ino_t on non-LFS version with an extra __pad field which should ++ be zeroed. */ ++ ++#include ++#undef _DIRENT_MATCHES_DIRENT64 ++#define _DIRENT_MATCHES_DIRENT64 0 ++#ifdef SW_64 ++# define DIRENT_SET_DP_INO(dp, value) \ ++ do \ ++ { \ ++ (dp)->d_ino = (value); \ ++ (dp)->__pad = 0; \ ++ } \ ++ while (0) ++#endif ++#include +diff --git a/sysdeps/unix/sysv/linux/sw_64/getdents64.c b/sysdeps/unix/sysv/linux/sw_64/getdents64.c +new file mode 100644 +index 00000000..f24cc638 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/getdents64.c +@@ -0,0 +1,10 @@ ++/* Although Sw_64 defines _DIRENT_MATCHES_DIRENT64, 'struct dirent' and ++ 'struct dirent64' have slight different internal layout with d_ino ++ being a __ino_t on non-LFS version with an extra __pad field which should ++ be zeroed. */ ++ ++#include ++/* It suppresses the __getdents64 to __getdents alias. */ ++#undef _DIRENT_MATCHES_DIRENT64 ++#define _DIRENT_MATCHES_DIRENT64 0 ++#include +diff --git a/sysdeps/unix/sysv/linux/sw_64/getegid.S b/sysdeps/unix/sysv/linux/sw_64/getegid.S +new file mode 100644 +index 00000000..fe5bd51a +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/getegid.S +@@ -0,0 +1,26 @@ ++/* Copyright (C) 1991-2023 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 ++ ++ ++PSEUDO (__getegid, getxgid, 0) ++ MOVE (r1, r0) ++ ret ++PSEUDO_END (__getegid) ++ ++weak_alias (__getegid, getegid) +diff --git a/sysdeps/unix/sysv/linux/sw_64/geteuid.S b/sysdeps/unix/sysv/linux/sw_64/geteuid.S +new file mode 100644 +index 00000000..fb8fd714 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/geteuid.S +@@ -0,0 +1,26 @@ ++/* Copyright (C) 1991-2023 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 ++ ++ ++PSEUDO (__geteuid, getxuid, 0) ++ MOVE (r1, r0) ++ ret ++PSEUDO_END (__geteuid) ++ ++weak_alias (__geteuid, geteuid) +diff --git a/sysdeps/unix/sysv/linux/sw_64/gethostname.c b/sysdeps/unix/sysv/linux/sw_64/gethostname.c +new file mode 100644 +index 00000000..aeb3a957 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/gethostname.c +@@ -0,0 +1,45 @@ ++/* Copyright (C) 2001-2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Ulrich Drepper , 2001 ++ ++ 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 ++ ++int ++__gethostname (char *name, size_t len) ++{ ++ int result; ++ ++ result = INLINE_SYSCALL (gethostname, 2, name, len); ++ ++ if (result == 0 ++ /* See whether the string is terminated. If not we will return ++ an error. */ ++ && memchr (name, '\0', len) == NULL) ++ { ++ __set_errno (EOVERFLOW); ++ result = -1; ++ } ++ ++ return result; ++} ++ ++weak_alias (__gethostname, gethostname) +diff --git a/sysdeps/unix/sysv/linux/sw_64/getppid.S b/sysdeps/unix/sysv/linux/sw_64/getppid.S +new file mode 100644 +index 00000000..2107686d +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/getppid.S +@@ -0,0 +1,26 @@ ++/* Copyright (C) 1991-2023 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 ++ ++ ++PSEUDO (__getppid, getxpid, 0) ++ MOVE (r1, r0) ++ ret ++PSEUDO_END (__getppid) ++ ++weak_alias (__getppid, getppid) +diff --git a/sysdeps/unix/sysv/linux/sw_64/getrlimit64.c b/sysdeps/unix/sysv/linux/sw_64/getrlimit64.c +new file mode 100644 +index 00000000..7d455c74 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/getrlimit64.c +@@ -0,0 +1,54 @@ ++/* Copyright (C) 2018-2023 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 ++ . */ ++ ++#define USE_VERSIONED_RLIMIT ++#include ++versioned_symbol (libc, __getrlimit, getrlimit, GLIBC_2_27); ++versioned_symbol (libc, __getrlimit64, getrlimit64, GLIBC_2_27); ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) ++/* RLIM64_INFINITY was supposed to be a glibc convention rather than ++ anything seen by the kernel, but it ended being passed to the kernel ++ through the prlimit64 syscall. Given that a lot of binaries with ++ the wrong constant value are in the wild, provide a wrapper function ++ fixing the value after the syscall. */ ++# define OLD_RLIM64_INFINITY 0x7fffffffffffffffULL ++ ++int attribute_compat_text_section ++__old_getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) ++{ ++ struct rlimit64 krlimits; ++ ++ if (__getrlimit64 (resource, &krlimits) < 0) ++ return -1; ++ ++ if (krlimits.rlim_cur == RLIM64_INFINITY) ++ rlimits->rlim_cur = OLD_RLIM64_INFINITY; ++ else ++ rlimits->rlim_cur = krlimits.rlim_cur; ++ if (krlimits.rlim_max == RLIM64_INFINITY) ++ rlimits->rlim_max = OLD_RLIM64_INFINITY; ++ else ++ rlimits->rlim_max = krlimits.rlim_max; ++ ++ return 0; ++} ++ ++strong_alias (__old_getrlimit64, __old_getrlimit) ++ compat_symbol (libc, __old_getrlimit, getrlimit, GLIBC_2_0); ++compat_symbol (libc, __old_getrlimit64, getrlimit64, GLIBC_2_1); ++#endif +diff --git a/sysdeps/unix/sysv/linux/sw_64/gettimeofday.c b/sysdeps/unix/sysv/linux/sw_64/gettimeofday.c +new file mode 100644 +index 00000000..d6fcc00a +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sw_64/gettimeofday.c +@@ -0,0 +1,26 @@ ++/* gettimeofday -- Get the current time of day. Linux/Sw_64/tv64 version. ++ Copyright (C) 2019-2023 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 ++ . */ ++ ++/* We can use the generic implementation, but we have to override its ++ default symbol version. */ ++#define SET_VERSION ++#include