summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/misc/Makefile.in2
-rw-r--r--libc/misc/auxvt/Makefile.in23
-rwxr-xr-xlibc/misc/auxvt/getauxval.c40
-rw-r--r--libc/misc/internals/Makefile.in2
-rw-r--r--libc/misc/internals/reloc_static_pie.c93
-rw-r--r--libc/string/arc/memcmp.S94
-rw-r--r--libc/string/arc/memcpy.S65
-rw-r--r--libc/string/arc/memset.S61
-rw-r--r--libc/string/arc/strchr.S25
-rw-r--r--libc/string/arc/strcmp.S21
-rw-r--r--libc/string/arc/strlen.S7
-rw-r--r--libc/string/generic/strchr.c23
-rw-r--r--libc/string/generic/strchrnul.c23
-rw-r--r--libc/sysdeps/linux/arc/asm.h91
-rw-r--r--libc/sysdeps/linux/arc/bits/syscalls.h4
-rw-r--r--libc/sysdeps/linux/arc/crt1.S4
-rw-r--r--libc/sysdeps/linux/common/bits/mman-linux.h1
-rwxr-xr-x[-rw-r--r--]libc/sysdeps/linux/common/bits/syscalls-common.h5
-rw-r--r--libc/sysdeps/linux/common/futimesat.c26
-rwxr-xr-x[-rw-r--r--]libc/sysdeps/linux/common/gettimeofday.c25
-rw-r--r--libc/sysdeps/linux/mips/crt1.S23
-rw-r--r--libc/sysdeps/linux/powerpc/crt1.S19
l---------libc/sysdeps/linux/riscv321
-rw-r--r--libc/sysdeps/linux/riscv64/bits/wordsize.h3
-rw-r--r--libc/sysdeps/linux/riscv64/setjmp.S2
-rw-r--r--libc/sysdeps/linux/riscv64/sys/asm.h6
-rw-r--r--libc/sysdeps/linux/xtensa/crt1.S27
27 files changed, 620 insertions, 96 deletions
diff --git a/libc/misc/Makefile.in b/libc/misc/Makefile.in
index 53bb6d6c8..caf7f1391 100644
--- a/libc/misc/Makefile.in
+++ b/libc/misc/Makefile.in
@@ -5,7 +5,9 @@
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
+
include $(top_srcdir)libc/misc/assert/Makefile.in
+include $(top_srcdir)libc/misc/auxvt/Makefile.in
include $(top_srcdir)libc/misc/ctype/Makefile.in
include $(top_srcdir)libc/misc/dirent/Makefile.in
include $(top_srcdir)libc/misc/error/Makefile.in
diff --git a/libc/misc/auxvt/Makefile.in b/libc/misc/auxvt/Makefile.in
new file mode 100644
index 000000000..142ade10c
--- /dev/null
+++ b/libc/misc/auxvt/Makefile.in
@@ -0,0 +1,23 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+subdirs += libc/misc/auxvt
+
+CSRC-y := getauxval.c
+
+MISC_AUXVT_DIR := $(top_srcdir)libc/misc/auxvt
+MISC_AUXVT_OUT := $(top_builddir)libc/misc/auxvt
+
+MISC_AUXVT_SRC := $(patsubst %.c,$(MISC_AUXVT_DIR)/%.c,$(CSRC-y))
+MISC_AUXVT_OBJ := $(patsubst %.c,$(MISC_AUXVT_OUT)/%.o,$(CSRC-y))
+
+libc-y += $(MISC_AUXVT_OBJ)
+
+objclean-y += CLEAN_libc/misc/auxvt
+
+CLEAN_libc/misc/auxvt:
+ $(do_rm) $(addprefix $(MISC_AUXVT_OUT)/*., o os)
diff --git a/libc/misc/auxvt/getauxval.c b/libc/misc/auxvt/getauxval.c
new file mode 100755
index 000000000..b4e621301
--- /dev/null
+++ b/libc/misc/auxvt/getauxval.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 2022 Ramin Seyed Moussavi
+ * An getauxval() function compatible with the glibc auxv.h
+ * that is used by uClibc-ng.
+ *
+ * This 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.
+ *
+ * This 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 this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "errno.h"
+#include "ldso.h"
+#include "sys/auxv.h"
+
+
+unsigned long int getauxval (unsigned long int __type)
+{
+ if ( __type >= AUX_MAX_AT_ID ){
+ __set_errno (ENOENT);
+ return 0;
+ }
+
+ if ( _dl_auxvt[__type].a_type == __type){
+ return _dl_auxvt[__type].a_un.a_val;
+ }
+
+ __set_errno (ENOENT);
+ return 0;
+}
+
+
diff --git a/libc/misc/internals/Makefile.in b/libc/misc/internals/Makefile.in
index 69af8b76e..908b18321 100644
--- a/libc/misc/internals/Makefile.in
+++ b/libc/misc/internals/Makefile.in
@@ -17,7 +17,7 @@ MISC_INTERNALS_SRC := $(patsubst %.c,$(MISC_INTERNALS_DIR)/%.c,$(CSRC-y))
MISC_INTERNALS_OBJ := $(patsubst %.c,$(MISC_INTERNALS_OUT)/%.o,$(CSRC-y))
CFLAGS-__uClibc_main.c := $(SSP_DISABLE_FLAGS)
-CFLAGS-reloc_static_pie.c := $(SSP_DISABLE_FLAGS)
+CFLAGS-reloc_static_pie.c := $(SSP_DISABLE_FLAGS) -DL_rcrt1
libc-y += $(MISC_INTERNALS_OBJ)
ifneq ($(UCLIBC_FORMAT_SHARED_FLAT),y)
diff --git a/libc/misc/internals/reloc_static_pie.c b/libc/misc/internals/reloc_static_pie.c
index 578202d23..ab1923024 100644
--- a/libc/misc/internals/reloc_static_pie.c
+++ b/libc/misc/internals/reloc_static_pie.c
@@ -15,33 +15,96 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-
+#define IS_IN_rtld // force inline function calls
#include <link.h>
#include <elf.h>
#include <dl-elf.h>
-ElfW(Addr) _dl_load_base = NULL;
+#include <ldso.h>
+#if defined(__mips__) || defined(__xtensa__)
+#include <dl-startup.h>
+#endif
+
+extern ElfW(Addr) _dl_load_base;
void
reloc_static_pie (ElfW(Addr) load_addr);
void
-reloc_static_pie (ElfW(Addr) load_addr)
+reloc_static_pie(ElfW(Addr) load_addr)
{
- ElfW(Word) relative_count = 0;
- ElfW(Addr) rel_addr = 0;
- ElfW(Dyn) * dyn_addr = NULL;
- unsigned long dynamic_info[DYNAMIC_SIZE] = {0};
+ int indx;
+ ElfW(Addr) got;
+ ElfW(Dyn) *dpnt;
+ struct elf_resolve tpnt_tmp;
+ struct elf_resolve *tpnt = &tpnt_tmp;
+
+ DL_BOOT_COMPUTE_GOT(got);
+ DL_BOOT_COMPUTE_DYN(dpnt, got, (DL_LOADADDR_TYPE)load_addr);
+
+ _dl_memset(tpnt, 0, sizeof(struct elf_resolve));
+ tpnt->loadaddr = load_addr;
+ tpnt->dynamic_addr = dpnt;
+
+ __dl_parse_dynamic_info(dpnt, tpnt->dynamic_info, NULL, load_addr);
+
+#if defined(PERFORM_BOOTSTRAP_GOT)
+ /* some arches (like MIPS) we have to tweak the GOT before relocations */
+ PERFORM_BOOTSTRAP_GOT(tpnt);
+#endif
+
+
+#if defined(ELF_MACHINE_PLTREL_OVERLAP)
+# define INDX_MAX 1
+#else
+# define INDX_MAX 2
+#endif
+
+ for (indx = 0; indx < INDX_MAX; indx++) {
+ unsigned long rel_addr, rel_size;
+ ElfW(Word) relative_count = tpnt->dynamic_info[DT_RELCONT_IDX];
+
+ rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] :
+ tpnt->dynamic_info[DT_RELOC_TABLE_ADDR]);
+ rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] :
+ tpnt->dynamic_info[DT_RELOC_TABLE_SIZE]);
+
+ if (!rel_addr)
+ continue;
- /* Read our own dynamic section and fill in the info array. */
- dyn_addr = ((void *) load_addr + elf_machine_dynamic ());
+ if((0 == indx) && relative_count) {
+ rel_size -= relative_count * sizeof(ELF_RELOC);
+ elf_machine_relative(load_addr, rel_addr, relative_count);
+ rel_addr += relative_count * sizeof(ELF_RELOC);
+ }
- /* Use the underlying function to avoid TLS access before initialization */
- __dl_parse_dynamic_info(dyn_addr, dynamic_info, NULL, load_addr);
+#ifdef ARCH_NEEDS_BOOTSTRAP_RELOCS
+ {
+ ELF_RELOC *rpnt;
+ unsigned int i;
+ ElfW(Sym) *sym;
+ unsigned long symbol_addr;
+ int symtab_index;
+ unsigned long *reloc_addr;
- /* Perform relocations */
- relative_count = dynamic_info[DT_RELCONT_IDX];
- rel_addr = dynamic_info[DT_RELOC_TABLE_ADDR];
- elf_machine_relative(load_addr, rel_addr, relative_count);
+ /* Now parse the relocation information */
+ rpnt = (ELF_RELOC *) rel_addr;
+ for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
+ reloc_addr = (unsigned long *) DL_RELOC_ADDR(load_addr, (unsigned long)rpnt->r_offset);
+ symtab_index = ELF_R_SYM(rpnt->r_info);
+ symbol_addr = 0;
+ sym = NULL;
+ if (symtab_index) {
+ ElfW(Sym) *symtab;
+ symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB];
+ sym = &symtab[symtab_index];
+ symbol_addr = (unsigned long) DL_RELOC_ADDR(load_addr, sym->st_value);
+ }
+ /* Use this machine-specific macro to perform the actual relocation. */
+ PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, sym);
+ }
+ }
+#endif
+ }
_dl_load_base = load_addr;
}
diff --git a/libc/string/arc/memcmp.S b/libc/string/arc/memcmp.S
index a60757e7a..20122a296 100644
--- a/libc/string/arc/memcmp.S
+++ b/libc/string/arc/memcmp.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
+ * Copyright (C) 2013, 2022 Synopsys, Inc. (www.synopsys.com)
* Copyright (C) 2007 ARC International (UK) LTD
*
* Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
@@ -17,6 +17,8 @@
#endif
ENTRY(memcmp)
+
+#if defined(__ARC700__) || defined(__ARCHS__)
or r12,r0,r1
asl_s r12,r12,30
sub r3,r2,1
@@ -149,6 +151,96 @@ ENTRY(memcmp)
.Lnil:
j_s.d [blink]
mov r0,0
+
+#elif (__ARC64_ARCH32__)
+ ;; Based on Synopsys code from newlib's arc64/memcmp.S
+ cmp r2, 32
+ bls.d @.L_compare_1_bytes
+ mov r3, r0 ; "r0" will be used as return value
+
+ lsr r12, r2, 4 ; counter for 16-byte chunks
+ xor r13, r13, r13 ; the mask showing inequal registers
+
+.L_compare_16_bytes:
+ ld.ab r4, [r3, +4]
+ ld.ab r5, [r1, +4]
+ ld.ab r6, [r3, +4]
+ ld.ab r7, [r1, +4]
+ ld.ab r8, [r3, +4]
+ ld.ab r9, [r1, +4]
+ ld.ab r10, [r3, +4]
+ ld.ab r11, [r1, +4]
+ xor.f 0, r4, r5
+ xor.ne r13, r13, 0b0001
+ xor.f 0, r6, r7
+ xor.ne r13, r13, 0b0010
+ xor.f 0, r8, r9
+ xor.ne r13, r13, 0b0100
+ xor.f 0, r10, r11
+ xor.ne r13, r13, 0b1000
+ brne r13, 0, @.L_unequal_find
+ dbnz r12, @.L_compare_16_bytes
+
+ ;; Adjusting the pointers because of the extra loads in the end
+ sub r1, r1, 4
+ sub r3, r3, 4
+ bmsk_s r2, r2, 3 ; any remaining bytes to compare
+
+.L_compare_1_bytes:
+ cmp r2, 0
+ jeq.d [blink]
+ xor_s r0, r0, r0
+
+2:
+ ldb.ab r4, [r3, +1]
+ ldb.ab r5, [r1, +1]
+ sub.f r0, r4, r5
+ jne [blink]
+ dbnz r2, @2b
+ j_s [blink]
+
+ ;; At this point, we want to find the _first_ comparison that marked the
+ ;; inequality of "lhs" and "rhs"
+.L_unequal_find:
+ ffs r13, r13
+ asl r13, r13, 2
+ bi [r13]
+.L_unequal_r4r5:
+ mov r1, r4
+ b.d @.L_diff_byte_in_regs
+ mov r2, r5
+ nop
+.L_unequal_r6r7:
+ mov r1, r6
+ b.d @.L_diff_byte_in_regs
+ mov r2, r7
+ nop
+.L_unequal_r8r9:
+ mov r1, r8
+ b.d @.L_diff_byte_in_regs
+ mov r2, r9
+ nop
+.L_unequal_r10r11:
+ mov r1, r10
+ mov r2, r11
+
+ ;; fall-through
+ ;; If we're here, that means the two operands are not equal.
+.L_diff_byte_in_regs:
+ xor r0, r1, r2
+ ffs r0, r0
+ and r0, r0, 0x18
+ lsr r1, r1, r0
+ lsr r2, r2, r0
+ bmsk_s r1, r1, 7
+ bmsk_s r2, r2, 7
+ j_s.d [blink]
+ sub r0, r1, r2
+
+#else
+#error "Unsupported ARC CPU type"
+#endif
+
END(memcmp)
libc_hidden_def(memcmp)
diff --git a/libc/string/arc/memcpy.S b/libc/string/arc/memcpy.S
index 69d7220b8..153083765 100644
--- a/libc/string/arc/memcpy.S
+++ b/libc/string/arc/memcpy.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2014-2015, 2017 Synopsys, Inc. (www.synopsys.com)
+ * Copyright (C) 2013, 2014-2015, 2017, 2022 Synopsys, Inc. (www.synopsys.com)
* Copyright (C) 2007 ARC International (UK) LTD
*
* Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
@@ -7,13 +7,9 @@
#include <sysdep.h>
-#if !defined(__ARC700__) && !defined(__ARCHS__)
-#error "Neither ARC700 nor ARCHS is defined!"
-#endif
-
ENTRY(memcpy)
-#ifdef __ARC700__
+#if defined(__ARC700__)
/* This memcpy implementation does not support objects of 1GB or larger -
the check for alignment does not work then. */
/* We assume that most sources and destinations are aligned, and
@@ -73,9 +69,9 @@ ENTRY(memcpy)
.Lendbloop:
j_s.d [blink]
stb r12,[r5,0]
-#endif /* __ARC700__ */
-#ifdef __ARCHS__
+#elif defined(__ARCHS__)
+
#ifdef __LITTLE_ENDIAN__
# define SHIFT_1(RX,RY,IMM) asl RX, RY, IMM ; <<
# define SHIFT_2(RX,RY,IMM) lsr RX, RY, IMM ; >>
@@ -299,7 +295,58 @@ ENTRY(memcpy)
stb.ab r6, [r3,1]
.Lcopybytewise_3:
j [blink]
-#endif /* __ARCHS__ */
+
+#elif defined(__ARC64_ARCH32__)
+ ;; Based on Synopsys code from newlib's arc64/memcpy.S
+ lsr.f r11, r2, 4 ; counter for 16-byte chunks
+ beq.d @.L_write_15_bytes
+ mov r3, r0 ; work on a copy of "r0"
+
+.L_write_16_bytes:
+#if defined(__ARC64_LL64__)
+ ldd.ab r4, [r1, 8]
+ ldd.ab r6, [r1, 8]
+ std.ab r4, [r3, 8]
+ std.ab r6, [r3, 8]
+ dbnz r11, @.L_write_16_bytes
+#else
+ ld.ab r4, [r1, 4]
+ ld.ab r5, [r1, 4]
+ ld.ab r6, [r1, 4]
+ ld.ab r7, [r1, 4]
+ st.ab r4, [r3, 4]
+ st.ab r5, [r3, 4]
+ st.ab r6, [r3, 4]
+ dbnz.d r11, @.L_write_16_bytes
+ st.ab r7, [r3, 4]
+#endif
+ bmsk_s r2, r2, 3
+
+.L_write_15_bytes:
+ bbit0.d r2, 1, @1f
+ lsr r11, r2, 2
+ ldh.ab r4, [r1, 2]
+ sth.ab r4, [r3, 2]
+1:
+ bbit0.d r2, 0, @1f
+ xor r11, r11, 3
+ ldb.ab r4, [r1, 1]
+ stb.ab r4, [r3, 1]
+1:
+ asl r11, r11, 1
+ bi [r11]
+ ld.ab r4,[r1, 4]
+ st.ab r4,[r3, 4]
+ ld.ab r4,[r1, 4]
+ st.ab r4,[r3, 4]
+ ld r4,[r1]
+ st r4,[r3]
+
+ j_s [blink]
+
+#else
+#error "Unsupported ARC CPU type"
+#endif
END(memcpy)
libc_hidden_def(memcpy)
diff --git a/libc/string/arc/memset.S b/libc/string/arc/memset.S
index 0b74ddc7f..5aa5d6c65 100644
--- a/libc/string/arc/memset.S
+++ b/libc/string/arc/memset.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2014-2015, 2017 Synopsys, Inc. (www.synopsys.com)
+ * Copyright (C) 2013, 2014-2015, 2017, 2022 Synopsys, Inc. (www.synopsys.com)
* Copyright (C) 2007 ARC International (UK) LTD
*
* Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
@@ -7,13 +7,9 @@
#include <sysdep.h>
-#if !defined(__ARC700__) && !defined(__ARCHS__)
-#error "Neither ARC700 nor ARCHS is defined!"
-#endif
-
ENTRY(memset)
-#ifdef __ARC700__
+#if defined(__ARC700__)
#define SMALL 7 /* Must be at least 6 to deal with alignment/loop issues. */
mov_s r4,r0
@@ -52,9 +48,8 @@ ENTRY(memset)
stb.ab r1,[r4,1]
.Ltiny_end:
j_s [blink]
-#endif /* __ARC700__ */
-#ifdef __ARCHS__
+#elif defined(__ARCHS__)
#ifdef DONT_USE_PREALLOC
#define PREWRITE(A,B) prefetchw [(A),(B)]
#else
@@ -156,7 +151,55 @@ ENTRY(memset)
.Lcopy3bytes:
j [blink]
-#endif /* __ARCHS__ */
+
+#elif defined(__ARC64_ARCH32__)
+ ;; Based on Synopsys code from newlib's arc64/memset.S
+
+ ;; Assemble the bytes to 32bit words
+ bmsk_s r1, r1, 7 ; treat it like unsigned char
+ lsl8 r3, r1
+ or_s r1, r1, r3
+ lsl16 r3, r1
+ or r6, r1, r3
+ mov r7,r6
+
+ lsr.f r5, r2, 4 ; counter for 16-byte chunks
+ beq.d @.L_write_15_bytes
+ mov r4, r0 ; work on a copy of "r0"
+
+.L_write_16_bytes:
+#if defined(__ARC64_LL64__)
+ std.ab r6, [r4, 8]
+ std.ab r6, [r4, 8]
+ dbnz r5, @.L_write_16_bytes
+#else
+ st.ab r6, [r4, 4]
+ st.ab r6, [r4, 4]
+ st.ab r6, [r4, 4]
+ dbnz.d r5, @.L_write_16_bytes
+ st.ab r6, [r4, 4]
+#endif
+ bmsk_s r2, r2, 3
+
+.L_write_15_bytes:
+ bbit0.d r2, 1, @1f
+ lsr r3, r2, 2
+ sth.ab r6, [r4, 2]
+1:
+ bbit0.d r2, 0, @1f
+ xor r3, r3, 3
+ stb.ab r6, [r4, 1]
+1:
+ bi [r3]
+ st.ab r6,[r4, 4]
+ st.ab r6,[r4, 4]
+ st.ab r6,[r4, 4]
+
+ j_s [blink]
+
+#else
+#error "Unsupported ARC CPU type"
+#endif
END(memset)
libc_hidden_def(memset)
diff --git a/libc/string/arc/strchr.S b/libc/string/arc/strchr.S
index 443993589..df25eb3be 100644
--- a/libc/string/arc/strchr.S
+++ b/libc/string/arc/strchr.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
+ * Copyright (C) 2013, 2022 Synopsys, Inc. (www.synopsys.com)
* Copyright (C) 2007 ARC International (UK) LTD
*
* Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
@@ -7,6 +7,7 @@
#include <sysdep.h>
#include <features.h>
+#include <asm.h>
/* ARC700 has a relatively long pipeline and branch prediction, so we want
to avoid branches that are hard to predict. On the other hand, the
@@ -21,7 +22,7 @@ ENTRY(strchr)
mov_s r3,0x01010101
breq.d r2,r0,.Laligned
asl r4,r5,16
- sub_s r0,r0,r2
+ SUBR_S r0,r0,r2
asl r7,r2,3
ld_s r2,[r0]
#ifdef __LITTLE_ENDIAN__
@@ -77,10 +78,10 @@ ENTRY(strchr)
sub r3,r7,1
bic r3,r3,r7
norm r2,r3
- sub_s r0,r0,1
- asr_s r2,r2,3
+ SUBR_S r0,r0,1
+ ASRR_S r2,r2,3
j.d [blink]
- sub_s r0,r0,r2
+ SUBR_S r0,r0,r2
.balign 4
.Lfound0_ua:
@@ -90,13 +91,13 @@ ENTRY(strchr)
bic r3,r3,r6
and r2,r3,r4
or_s r12,r12,r2
- sub_s r3,r12,1
+ SUBR_S r3,r12,1
bic_s r3,r3,r12
norm r3,r3
- add_s r0,r0,3
- asr_s r12,r3,3
+ ADDR_S r0,r0,3
+ ASRR_S r12,r3,3
asl.f 0,r2,r3
- sub_s r0,r0,r12
+ SUBR_S r0,r0,r12
j_s.d [blink]
mov.pl r0,0
#else /* BIG ENDIAN */
@@ -106,10 +107,10 @@ ENTRY(strchr)
bic r2,r7,r6
.Lfound_char_b:
norm r2,r2
- sub_s r0,r0,4
+ SUBR_S r0,r0,4
asr_s r2,r2,3
j.d [blink]
- add_s r0,r0,r2
+ ADDR_S r0,r0,r2
.Lfound0_ua:
mov_s r3,r7
@@ -126,7 +127,7 @@ ENTRY(strchr)
add.pl r3,r3,1
asr_s r12,r3,3
asl.f 0,r2,r3
- add_s r0,r0,r12
+ ADDR_S r0,r0,r12
j_s.d [blink]
mov.mi r0,0
#endif /* ENDIAN */
diff --git a/libc/string/arc/strcmp.S b/libc/string/arc/strcmp.S
index ad38d9e00..3f64ac421 100644
--- a/libc/string/arc/strcmp.S
+++ b/libc/string/arc/strcmp.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2014-2015, 2017 Synopsys, Inc. (www.synopsys.com)
+ * Copyright (C) 2013, 2014-2015, 2017, 2022 Synopsys, Inc. (www.synopsys.com)
* Copyright (C) 2007 ARC International (UK) LTD
*
* Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
@@ -7,14 +7,11 @@
#include <features.h>
#include <sysdep.h>
-
-#if !defined(__ARC700__) && !defined(__ARCHS__)
-#error "Neither ARC700 nor ARCHS is defined!"
-#endif
+#include <asm.h>
ENTRY(strcmp)
-#ifdef __ARC700__
+#if defined(__ARC700__) || defined(__ARC64_ARCH32__)
/* This is optimized primarily for the ARC700.
It would be possible to speed up the loops by one cycle / word
respective one cycle / byte by forcing double source 1 alignment, unrolling
@@ -38,7 +35,7 @@ ENTRY(strcmp)
breq r2,r3,.Lwordloop
#ifdef __LITTLE_ENDIAN__
xor r0,r2,r3 ; mask for difference
- sub_s r1,r0,1
+ SUBR_S r1,r0,1
bic_s r0,r0,r1 ; mask for least significant difference bit
sub r1,r5,r0
xor r0,r5,r1 ; mask for least significant difference byte
@@ -55,7 +52,7 @@ ENTRY(strcmp)
.Lfound0:
xor r0,r2,r3 ; mask for difference
or r0,r0,r4 ; or in zero indicator
- sub_s r1,r0,1
+ SUBR_S r1,r0,1
bic_s r0,r0,r1 ; mask for least significant difference bit
sub r1,r5,r0
xor r0,r5,r1 ; mask for least significant difference byte
@@ -99,9 +96,8 @@ ENTRY(strcmp)
.Lcmpend:
j_s.d [blink]
sub r0,r2,r3
-#endif /* __ARC700__ */
-#ifdef __ARCHS__
+#elif defined(__ARCHS__)
or r2, r0, r1
bmsk_s r2, r2, 1
brne r2, 0, @.Lcharloop
@@ -168,7 +164,10 @@ ENTRY(strcmp)
.Lcmpend:
j_s.d [blink]
sub r0, r2, r3
-#endif /* __ARCHS__ */
+
+#else
+#error "Unsupported ARC CPU type"
+#endif
END(strcmp)
libc_hidden_def(strcmp)
diff --git a/libc/string/arc/strlen.S b/libc/string/arc/strlen.S
index 0b9b93815..0d1d3aa4e 100644
--- a/libc/string/arc/strlen.S
+++ b/libc/string/arc/strlen.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
+ * Copyright (C) 2013, 2022 Synopsys, Inc. (www.synopsys.com)
* Copyright (C) 2007 ARC International (UK) LTD
*
* Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
@@ -7,6 +7,7 @@
#include <sysdep.h>
+#include <asm.h>
ENTRY(strlen)
or r3,r0,7
@@ -15,7 +16,7 @@ ENTRY(strlen)
mov r4,0x01010101
; uses long immediate
#ifdef __LITTLE_ENDIAN__
- asl_s r1,r0,3
+ ASLR_S r1,r0,3
btst_s r0,2
asl r7,r4,r1
ror r5,r4
@@ -59,7 +60,7 @@ ENTRY(strlen)
sub.ne r3,r3,4
mov.eq r1,r12
#ifdef __LITTLE_ENDIAN__
- sub_s r2,r1,1
+ SUBR_S r2,r1,1
bic_s r2,r2,r1
norm r1,r2
sub_s r0,r0,3
diff --git a/libc/string/generic/strchr.c b/libc/string/generic/strchr.c
index 321d2b8c3..b34884d67 100644
--- a/libc/string/generic/strchr.c
+++ b/libc/string/generic/strchr.c
@@ -60,22 +60,19 @@ char *strchr (const char *s, int c_in)
The 1-bits make sure that carries propagate to the next 0-bit.
The 0-bits provide holes for carries to fall into. */
- switch (sizeof (longword))
- {
- case 4: magic_bits = 0x7efefeffL; break;
- case 8: magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; break;
- default:
- abort ();
- }
-
/* Set up a longword, each of whose bytes is C. */
+#if __WORDSIZE == 32
+ magic_bits = 0x7efefeffL;
charmask = c | (c << 8);
charmask |= charmask << 16;
- if (sizeof (longword) > 4)
- /* Do the shift in two steps to avoid a warning if long has 32 bits. */
- charmask |= (charmask << 16) << 16;
- if (sizeof (longword) > 8)
- abort ();
+#elif __WORDSIZE == 64
+ magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL;
+ charmask = c | (c << 8);
+ charmask |= charmask << 16;
+ charmask |= (charmask << 16) << 16;
+#else
+ #error unexpected integer size strchr()
+#endif
/* Instead of the traditional loop which tests each character,
we will test a longword at a time. The tricky part is testing
diff --git a/libc/string/generic/strchrnul.c b/libc/string/generic/strchrnul.c
index d11d9e00d..d9fadc776 100644
--- a/libc/string/generic/strchrnul.c
+++ b/libc/string/generic/strchrnul.c
@@ -59,22 +59,19 @@ char *strchrnul (const char *s, int c_in)
The 1-bits make sure that carries propagate to the next 0-bit.
The 0-bits provide holes for carries to fall into. */
- switch (sizeof (longword))
- {
- case 4: magic_bits = 0x7efefeffL; break;
- case 8: magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; break;
- default:
- abort ();
- }
- /* Set up a longword, each of whose bytes is C. */
+#if __WORDSIZE == 32
+ magic_bits = 0x7efefeffL;
charmask = c | (c << 8);
charmask |= charmask << 16;
- if (sizeof (longword) > 4)
- /* Do the shift in two steps to avoid a warning if long has 32 bits. */
- charmask |= (charmask << 16) << 16;
- if (sizeof (longword) > 8)
- abort ();
+#elif __WORDSIZE == 64
+ magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL;
+ charmask = c | (c << 8);
+ charmask |= charmask << 16;
+ charmask |= (charmask << 16) << 16;
+#else
+ #error unexpected integer size strchr()
+#endif
/* Instead of the traditional loop which tests each character,
we will test a longword at a time. The tricky part is testing
diff --git a/libc/sysdeps/linux/arc/asm.h b/libc/sysdeps/linux/arc/asm.h
new file mode 100644
index 000000000..f83075ea1
--- /dev/null
+++ b/libc/sysdeps/linux/arc/asm.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2022, Synopsys, Inc. (www.synopsys.com)
+ *
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ */
+
+#ifndef _ARC_ASM_H
+#define _ARC_ASM_H
+
+/*
+ * Some 16-bit instructions were excluded from the ARCv3 ISA
+ * the following macros are introduced to handle these changes in one place.
+ * This will allow not to change existing ARCv2 code and use 16-bit versions
+ * of instructions for ARCv2 and replace them with 32-bit vesrions for ARCv3
+ */
+
+#if defined (__ARC64_ARCH32__)
+
+.macro PUSHR reg
+ push \reg
+.endm
+
+.macro PUSHR_S reg
+ push \reg
+.endm
+
+.macro POPR reg
+ pop \reg
+.endm
+
+.macro POPR_S reg
+ pop \reg
+.endm
+
+.macro SUBR_S dst,src1,src2
+ sub \dst, \src1, \src2
+.endm
+
+.macro ADDR_S dst,src1,src2
+ add \dst, \src1, \src2
+.endm
+
+.macro ASRR_S dst,src1,src2
+ asr \dst, \src1, \src2
+.endm
+
+.macro ASLR_S dst,src1,src2
+ asl \dst, \src1, \src2
+.endm
+
+#elif defined (__ARC64_ARCH64__)
+
+# error ARCv3 64-bit is not supported by uClibc-ng
+
+#else /* ARCHS || ARC700 */
+
+.macro PUSHR reg
+ push \reg
+.endm
+
+.macro PUSHR_S reg
+ push_s \reg
+.endm
+
+.macro POPR reg
+ pop \reg
+.endm
+
+.macro POPR_S reg
+ pop_s \reg
+.endm
+
+.macro SUBR_S dst,src1,src2
+ sub_s \dst, \src1, \src2
+.endm
+
+.macro ADDR_S dst,src1,src2
+ add_s \dst, \src1, \src2
+.endm
+
+.macro ASRR_S dst,src1,src2
+ asr_s \dst, \src1, \src2
+.endm
+
+.macro ASLR_S dst,src1,src2
+ asl_s \dst, \src1, \src2
+.endm
+
+#endif
+
+#endif /* _ARC_ASM_H */
diff --git a/libc/sysdeps/linux/arc/bits/syscalls.h b/libc/sysdeps/linux/arc/bits/syscalls.h
index c858d788b..000b6b631 100644
--- a/libc/sysdeps/linux/arc/bits/syscalls.h
+++ b/libc/sysdeps/linux/arc/bits/syscalls.h
@@ -100,7 +100,7 @@ extern long __syscall_error (int);
#ifdef __A7__
#define ARC_TRAP_INSN "trap0 \n\t"
-#elif defined(__HS__)
+#else
#define ARC_TRAP_INSN "trap_s 0 \n\t"
#endif
@@ -182,7 +182,7 @@ extern long __syscall_error (int);
#ifdef __A7__
#define ARC_TRAP_INSN trap0
-#elif defined(__HS__)
+#else
#define ARC_TRAP_INSN trap_s 0
#endif
diff --git a/libc/sysdeps/linux/arc/crt1.S b/libc/sysdeps/linux/arc/crt1.S
index 70a06e058..ff36d252e 100644
--- a/libc/sysdeps/linux/arc/crt1.S
+++ b/libc/sysdeps/linux/arc/crt1.S
@@ -40,7 +40,9 @@ __start:
ld_s r1, [sp] ; argc
mov_s r5, r0 ; rltd_fini
- add_s r2, sp, 4 ; argv
+ /* Use the universal 32-bit add instruction as 16-bit add_s was excluded from
+ ARCv3 ISA */
+ add r2, sp, 4 ; argv
#ifdef L_Scrt1
ld r0, [pcl, @main@gotpc]
ld r3, [pcl, @_init@gotpc]
diff --git a/libc/sysdeps/linux/common/bits/mman-linux.h b/libc/sysdeps/linux/common/bits/mman-linux.h
index 6ca08415a..4947ddd89 100644
--- a/libc/sysdeps/linux/common/bits/mman-linux.h
+++ b/libc/sysdeps/linux/common/bits/mman-linux.h
@@ -46,6 +46,7 @@
/* Other flags. */
#define MAP_FIXED 0x10 /* Interpret addr exactly. */
+# define MAP_FIXED_NOREPLACE 0x100000 /* Used to solve problem with MAP_FIXED */
#ifdef __USE_MISC
# define MAP_FILE 0
# ifdef __MAP_ANONYMOUS
diff --git a/libc/sysdeps/linux/common/bits/syscalls-common.h b/libc/sysdeps/linux/common/bits/syscalls-common.h
index 3665345a6..adae45aac 100644..100755
--- a/libc/sysdeps/linux/common/bits/syscalls-common.h
+++ b/libc/sysdeps/linux/common/bits/syscalls-common.h
@@ -104,11 +104,16 @@ type name(C_DECL_ARGS_##nargs(args)) { \
return (type)INLINE_SYSCALL_NOERR(name, nargs, C_ARGS_##nargs(args)); \
}
+#define SYSCALL_FUNC_BODY(nargs, type, name, args...) \
+ return (type)INLINE_SYSCALL(name, nargs, C_ARGS_##nargs(args));
+
+
#define _syscall0(args...) SYSCALL_FUNC(0, args)
#define _syscall_noerr0(args...) SYSCALL_NOERR_FUNC(0, args)
#define _syscall1(args...) SYSCALL_FUNC(1, args)
#define _syscall_noerr1(args...) SYSCALL_NOERR_FUNC(1, args)
#define _syscall2(args...) SYSCALL_FUNC(2, args)
+#define _syscall2_body(args...) SYSCALL_FUNC_BODY(2, args)
#define _syscall3(args...) SYSCALL_FUNC(3, args)
#define _syscall4(args...) SYSCALL_FUNC(4, args)
#define _syscall5(args...) SYSCALL_FUNC(5, args)
diff --git a/libc/sysdeps/linux/common/futimesat.c b/libc/sysdeps/linux/common/futimesat.c
index bd73eae7e..fd19fea7c 100644
--- a/libc/sysdeps/linux/common/futimesat.c
+++ b/libc/sysdeps/linux/common/futimesat.c
@@ -11,6 +11,28 @@
#ifdef __NR_futimesat
_syscall3(int, futimesat, int, fd, const char *, file, const struct timeval *, tvp)
-#else
-/* should add emulation with futimes() and /proc/self/fd/ ... */
+#elif defined __NR_utimensat
+#include <errno.h>
+#define __need_NULL
+#include <stddef.h>
+
+int futimesat(int dirfd, const char *file, const struct timeval tvp[2])
+{
+ struct timespec ts[2];
+
+ if (tvp != NULL)
+ {
+ if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000
+ || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
+ {
+ __set_errno(EINVAL);
+ return -1;
+ }
+
+ TIMEVAL_TO_TIMESPEC(&tvp[0], &ts[0]);
+ TIMEVAL_TO_TIMESPEC(&tvp[1], &ts[1]);
+ }
+
+ return utimensat(dirfd, file, tvp ? ts : NULL, 0);
+}
#endif
diff --git a/libc/sysdeps/linux/common/gettimeofday.c b/libc/sysdeps/linux/common/gettimeofday.c
index 1c62b3937..e5141088e 100644..100755
--- a/libc/sysdeps/linux/common/gettimeofday.c
+++ b/libc/sysdeps/linux/common/gettimeofday.c
@@ -9,5 +9,28 @@
#include <sys/syscall.h>
#include <sys/time.h>
-_syscall2(int, gettimeofday, struct timeval *, tv, __timezone_ptr_t, tz)
+#include "ldso.h"
+
+
+
+#ifdef __VDSO_SUPPORT__
+typedef int (*gettimeofday_func)(struct timeval * tv, __timezone_ptr_t tz);
+#endif
+
+int gettimeofday(struct timeval * tv, __timezone_ptr_t tz) {
+
+ #ifdef __VDSO_SUPPORT__
+ if ( _dl__vdso_gettimeofday != 0 ){
+ gettimeofday_func func= _dl__vdso_gettimeofday;
+ return func( tv, tz );
+
+ }else{
+ _syscall2_body(int, gettimeofday, struct timeval *, tv, __timezone_ptr_t, tz)
+ }
+ #else
+ _syscall2_body(int, gettimeofday, struct timeval *, tv, __timezone_ptr_t, tz)
+ #endif
+}
+
+
libc_hidden_def(gettimeofday)
diff --git a/libc/sysdeps/linux/mips/crt1.S b/libc/sysdeps/linux/mips/crt1.S
index 083615515..7c4db447c 100644
--- a/libc/sysdeps/linux/mips/crt1.S
+++ b/libc/sysdeps/linux/mips/crt1.S
@@ -78,6 +78,10 @@
.weak _init
.weak _fini
#endif
+#ifdef L_rcrt1
+ .type reloc_static_pie,@function
+ .hidden .L0
+#endif
.type main,@function
.type __uClibc_main,@function
.ent __start
@@ -90,6 +94,25 @@ __start:
PTR_LA $28, _gp /* Setup GP correctly if we're non-PIC. */
move $31, $0
#endif
+#ifdef L_rcrt1
+ PTR_LA $4, _DYNAMIC /* Place _DYNAMIC into the GOT */
+ REG_S $4, -0x7ff0($28) /* offset to GOT stolen from dl-startup */
+ jal .L0 /* Get the current $pc address */
+.L0:
+ PTR_SUBU $4, $31, $25 /* Calculate load addr */
+ move $31, $0 /* Clear ra */
+ and $29, -2 * SZREG /* Ensure stack is aligned */
+ PTR_ADDIU $29, (-2 * SZREG) /* Allocate 2 register spaces on stack */
+ REG_S $2, SZREG($29) /* Store atexit in case it exists */
+ PTR_LA $5, reloc_static_pie /* function calls before relocation
+ don't work unless we set $t9 manually */
+ PTR_ADDU $25, $4, $5 /* store reloc_static_pie in $t9 */
+ jalr $25 /* call reloc_static_pie */
+ nop /* delay slot, just in case */
+ REG_L $2, SZREG($29) /* cleanup stack */
+ PTR_ADDIU $29, $29, (2 * SZREG)
+
+#endif
PTR_LA $4, main /* main */
PTR_L $5, 0($29) /* argc */
diff --git a/libc/sysdeps/linux/powerpc/crt1.S b/libc/sysdeps/linux/powerpc/crt1.S
index 3f5d056c0..3ac32636c 100644
--- a/libc/sysdeps/linux/powerpc/crt1.S
+++ b/libc/sysdeps/linux/powerpc/crt1.S
@@ -41,6 +41,9 @@
.weak _init
.weak _fini
#endif
+#ifdef L_rcrt1
+ .type reloc_static_pie,%function
+#endif
.type main,%function
.type __uClibc_main,%function
@@ -61,6 +64,22 @@ _start:
# ifdef PPC_HAS_SECUREPLT
mr 30,31
# endif
+#ifdef L_rcrt1
+ stwu r3, -4(r1) /* Save r3 */
+ stwu r9, -16(r1) /* Save r9 */
+ bcl 20,31,2f /* Jump to label 2 */
+2: mflr r3 /* Load lr into r3 */
+ addis r3, r3, _DYNAMIC-2b@ha /* Add high half of _DYNAMIC to r3 */
+ addi r3,r3,_DYNAMIC-2b@l /* Add low half of _DYNAMIC */
+ lwz r4, 0(r31) /* load _DYNAMIC from the GOT */
+ subf r3, r4, r3 /* sub _DYNAMIC@got and it's actual address */
+ bl reloc_static_pie /* Call reloc_static_pie */
+ lwzu r9, 0(r1) /* restore r9 */
+ addi r1, r1, 16 /* update stack pointer */
+ lwzu r3, 0(r1) /* restore r3 */
+ addi r1, r1, 4 /* update stack pointer */
+ li r5, 0 /* zero r5 */
+#endif
#endif
/* Set up the small data pointer in r13. */
#ifdef __PIC__
diff --git a/libc/sysdeps/linux/riscv32 b/libc/sysdeps/linux/riscv32
new file mode 120000
index 000000000..11677ef05
--- /dev/null
+++ b/libc/sysdeps/linux/riscv32
@@ -0,0 +1 @@
+riscv64 \ No newline at end of file
diff --git a/libc/sysdeps/linux/riscv64/bits/wordsize.h b/libc/sysdeps/linux/riscv64/bits/wordsize.h
index 67a16ba62..1fc649aad 100644
--- a/libc/sysdeps/linux/riscv64/bits/wordsize.h
+++ b/libc/sysdeps/linux/riscv64/bits/wordsize.h
@@ -25,5 +25,6 @@
#if __riscv_xlen == 64
# define __WORDSIZE_TIME64_COMPAT32 1
#else
-# error "rv32i-based targets are not supported"
+# define __WORDSIZE_TIME64_COMPAT32 1
+// # warning "rv32i-based targets are experimental"
#endif
diff --git a/libc/sysdeps/linux/riscv64/setjmp.S b/libc/sysdeps/linux/riscv64/setjmp.S
index 4cdb8e9c3..100a0bd78 100644
--- a/libc/sysdeps/linux/riscv64/setjmp.S
+++ b/libc/sysdeps/linux/riscv64/setjmp.S
@@ -20,7 +20,7 @@
ENTRY (_setjmp)
li a1, 0
- j __sigsetjmp
+ j HIDDEN_JUMPTARGET (__sigsetjmp)
END (_setjmp)
ENTRY (setjmp)
li a1, 1
diff --git a/libc/sysdeps/linux/riscv64/sys/asm.h b/libc/sysdeps/linux/riscv64/sys/asm.h
index ddb84b683..3c94c9a70 100644
--- a/libc/sysdeps/linux/riscv64/sys/asm.h
+++ b/libc/sysdeps/linux/riscv64/sys/asm.h
@@ -26,7 +26,11 @@
# define REG_S sd
# define REG_L ld
#elif __riscv_xlen == 32
-# error "rv32i-based targets are not supported"
+# define PTRLOG 2
+# define SZREG 4
+# define REG_S sw
+# define REG_L lw
+// # warning "rv32i-based targets are experimental"
#else
# error __riscv_xlen must equal 32 or 64
#endif
diff --git a/libc/sysdeps/linux/xtensa/crt1.S b/libc/sysdeps/linux/xtensa/crt1.S
index efbe264c0..3fa14ae58 100644
--- a/libc/sysdeps/linux/xtensa/crt1.S
+++ b/libc/sysdeps/linux/xtensa/crt1.S
@@ -76,9 +76,26 @@
.global _start
.type _start, @function
_start:
+#ifdef L_rcrt1
+ .begin no-transform
+ call0 1f
+.Lret_addr:
+ .end no-transform
+ .align 4
+1:
+#endif
#if defined(__XTENSA_WINDOWED_ABI__)
+#ifdef L_rcrt1
+ movi a6, .Lret_addr
+ sub a6, a0, a6
+ movi a0, 0
+ movi a4, reloc_static_pie
+ add a4, a4, a6
+ callx4 a4
+#else
/* Clear a0 to obviously mark the outermost frame. */
movi a0, 0
+#endif
/* Load up the user's main function. */
movi a6, main
@@ -106,8 +123,18 @@ _start:
movi a4, __uClibc_main
callx4 a4
#elif defined(__XTENSA_CALL0_ABI__)
+#ifdef L_rcrt1
+ mov a12, a2
+ movi a2, .Lret_addr
+ sub a2, a0, a2
+ movi a0, reloc_static_pie
+ add a0, a0, a2
+ callx0 a0
+ mov a7, a12
+#else
/* Setup the shared library termination function. */
mov a7, a2
+#endif
/* Load up the user's main function. */
movi a2, main