diff mbox series

[v6,01/13] ARC: ABI Implementation

Message ID 20200423014126.10417-2-vgupta@synopsys.com
State New
Headers show
Series glibc port to ARC processors | expand

Commit Message

Vineet Gupta April 23, 2020, 1:41 a.m. UTC
This code deals with the ARC ABI.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 sysdeps/arc/__longjmp.S       | 50 ++++++++++++++++++++++
 sysdeps/arc/abort-instr.h     |  2 +
 sysdeps/arc/bits/endianness.h | 15 +++++++
 sysdeps/arc/bits/setjmp.h     | 26 ++++++++++++
 sysdeps/arc/bsd-_setjmp.S     |  1 +
 sysdeps/arc/bsd-setjmp.S      |  1 +
 sysdeps/arc/dl-runtime.c      | 33 +++++++++++++++
 sysdeps/arc/dl-sysdep.h       | 25 +++++++++++
 sysdeps/arc/dl-trampoline.S   | 80 +++++++++++++++++++++++++++++++++++
 sysdeps/arc/gccframe.h        | 21 +++++++++
 sysdeps/arc/jmpbuf-offsets.h  | 47 ++++++++++++++++++++
 sysdeps/arc/jmpbuf-unwind.h   | 47 ++++++++++++++++++++
 sysdeps/arc/machine-gmon.h    | 35 +++++++++++++++
 sysdeps/arc/memusage.h        | 23 ++++++++++
 sysdeps/arc/setjmp.S          | 66 +++++++++++++++++++++++++++++
 sysdeps/arc/sysdep.h          | 48 +++++++++++++++++++++
 sysdeps/arc/tls-macros.h      | 47 ++++++++++++++++++++
 17 files changed, 567 insertions(+)
 create mode 100644 sysdeps/arc/__longjmp.S
 create mode 100644 sysdeps/arc/abort-instr.h
 create mode 100644 sysdeps/arc/bits/endianness.h
 create mode 100644 sysdeps/arc/bits/setjmp.h
 create mode 100644 sysdeps/arc/bsd-_setjmp.S
 create mode 100644 sysdeps/arc/bsd-setjmp.S
 create mode 100644 sysdeps/arc/dl-runtime.c
 create mode 100644 sysdeps/arc/dl-sysdep.h
 create mode 100644 sysdeps/arc/dl-trampoline.S
 create mode 100644 sysdeps/arc/gccframe.h
 create mode 100644 sysdeps/arc/jmpbuf-offsets.h
 create mode 100644 sysdeps/arc/jmpbuf-unwind.h
 create mode 100644 sysdeps/arc/machine-gmon.h
 create mode 100644 sysdeps/arc/memusage.h
 create mode 100644 sysdeps/arc/setjmp.S
 create mode 100644 sysdeps/arc/sysdep.h
 create mode 100644 sysdeps/arc/tls-macros.h

Comments

Adhemerval Zanella May 27, 2020, 6:26 p.m. UTC | #1
On 22/04/2020 22:41, Vineet Gupta via Libc-alpha wrote:
> This code deals with the ARC ABI.
> 
> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>

We do not use DCO, but rather copyright assignment.

Looks ok in general, with some comments below.

> ---
>  sysdeps/arc/__longjmp.S       | 50 ++++++++++++++++++++++
>  sysdeps/arc/abort-instr.h     |  2 +
>  sysdeps/arc/bits/endianness.h | 15 +++++++
>  sysdeps/arc/bits/setjmp.h     | 26 ++++++++++++
>  sysdeps/arc/bsd-_setjmp.S     |  1 +
>  sysdeps/arc/bsd-setjmp.S      |  1 +
>  sysdeps/arc/dl-runtime.c      | 33 +++++++++++++++
>  sysdeps/arc/dl-sysdep.h       | 25 +++++++++++
>  sysdeps/arc/dl-trampoline.S   | 80 +++++++++++++++++++++++++++++++++++
>  sysdeps/arc/gccframe.h        | 21 +++++++++
>  sysdeps/arc/jmpbuf-offsets.h  | 47 ++++++++++++++++++++
>  sysdeps/arc/jmpbuf-unwind.h   | 47 ++++++++++++++++++++
>  sysdeps/arc/machine-gmon.h    | 35 +++++++++++++++
>  sysdeps/arc/memusage.h        | 23 ++++++++++
>  sysdeps/arc/setjmp.S          | 66 +++++++++++++++++++++++++++++
>  sysdeps/arc/sysdep.h          | 48 +++++++++++++++++++++
>  sysdeps/arc/tls-macros.h      | 47 ++++++++++++++++++++
>  17 files changed, 567 insertions(+)
>  create mode 100644 sysdeps/arc/__longjmp.S
>  create mode 100644 sysdeps/arc/abort-instr.h
>  create mode 100644 sysdeps/arc/bits/endianness.h
>  create mode 100644 sysdeps/arc/bits/setjmp.h
>  create mode 100644 sysdeps/arc/bsd-_setjmp.S
>  create mode 100644 sysdeps/arc/bsd-setjmp.S
>  create mode 100644 sysdeps/arc/dl-runtime.c
>  create mode 100644 sysdeps/arc/dl-sysdep.h
>  create mode 100644 sysdeps/arc/dl-trampoline.S
>  create mode 100644 sysdeps/arc/gccframe.h
>  create mode 100644 sysdeps/arc/jmpbuf-offsets.h
>  create mode 100644 sysdeps/arc/jmpbuf-unwind.h
>  create mode 100644 sysdeps/arc/machine-gmon.h
>  create mode 100644 sysdeps/arc/memusage.h
>  create mode 100644 sysdeps/arc/setjmp.S
>  create mode 100644 sysdeps/arc/sysdep.h
>  create mode 100644 sysdeps/arc/tls-macros.h
> 
> diff --git a/sysdeps/arc/__longjmp.S b/sysdeps/arc/__longjmp.S
> new file mode 100644
> index 000000000000..ffc3daa7de72
> --- /dev/null
> +++ b/sysdeps/arc/__longjmp.S
> @@ -0,0 +1,50 @@
> +/* longjmp for ARC.
> +   Copyright (C) 2017-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sysdep.h>
> +#include <jmpbuf-offsets.h>
> +
> +;@ r0 = jump buffer from which regs will be restored
> +;@ r1 = value that setjmp( ) will return due to this longjmp

Since all .S files are processed by gcc assembly implementation usually
use C style comment (/* ... */). Same applies to other assembly
implementations.

> +
> +ENTRY (__longjmp)
> +
> +	ld_s r13,   [r0]
> +	ld_s r14,   [r0,4]
> +	ld   r15,   [r0,8]
> +	ld   r16,   [r0,12]
> +	ld   r17,   [r0,16]
> +	ld   r18,   [r0,20]
> +	ld   r19,   [r0,24]
> +	ld   r20,   [r0,28]
> +	ld   r21,   [r0,32]
> +	ld   r22,   [r0,36]
> +	ld   r23,   [r0,40]
> +	ld   r24,   [r0,44]
> +	ld   r25,   [r0,48]
> +
> +	ld   blink, [r0,60]
> +	ld   fp,    [r0,52]
> +	ld   sp,    [r0,56]
> +
> +	mov.f  r0, r1	; get the setjmp return value(due to longjmp) in place
> +
> +	j.d    [blink]	; to caller of setjmp location, right after the call
> +	mov.z  r0, 1	; can't let setjmp return 0 when it is due to longjmp
> +
> +END (__longjmp)

Ok.

> diff --git a/sysdeps/arc/abort-instr.h b/sysdeps/arc/abort-instr.h
> new file mode 100644
> index 000000000000..49f33613c404
> --- /dev/null
> +++ b/sysdeps/arc/abort-instr.h
> @@ -0,0 +1,2 @@
> +/* FLAG 1 is privilege mode only instruction, hence will crash any program.  */
> +#define ABORT_INSTRUCTION asm ("flag 1")

Ok.

> diff --git a/sysdeps/arc/bits/endianness.h b/sysdeps/arc/bits/endianness.h
> new file mode 100644
> index 000000000000..8f17ca84b485
> --- /dev/null
> +++ b/sysdeps/arc/bits/endianness.h
> @@ -0,0 +1,15 @@
> +#ifndef _BITS_ENDIANNESS_H
> +#define _BITS_ENDIANNESS_H 1
> +
> +#ifndef _BITS_ENDIAN_H
> +# error "Never use <bits/endian.h> directly; include <endian.h> instead."
> +#endif
> +
> +/* ARC has selectable endianness.  */
> +#ifdef __BIG_ENDIAN__
> +# define __BYTE_ORDER __BIG_ENDIAN
> +#else
> +# define __BYTE_ORDER __LITTLE_ENDIAN
> +#endif
> +
> +#endif /* bits/endianness.h */

Ok (assuming __BIG_ENDIAN__ is what gcc for arc defines for big endian).

> diff --git a/sysdeps/arc/bits/setjmp.h b/sysdeps/arc/bits/setjmp.h
> new file mode 100644
> index 000000000000..333e5cce3bea
> --- /dev/null
> +++ b/sysdeps/arc/bits/setjmp.h
> @@ -0,0 +1,26 @@
> +/* Define the machine-dependent type `jmp_buf'.  ARC version.
> +   Copyright (C) 1992-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _ARC_BITS_SETJMP_H
> +#define _ARC_BITS_SETJMP_H 1
> +
> +/* Saves r13-r25 (callee-saved), fp (frame pointer), sp (stack pointer),
> +   blink (branch-n-link).  */
> +typedef long int __jmp_buf[32];
> +
> +#endif

Ok.

> diff --git a/sysdeps/arc/bsd-_setjmp.S b/sysdeps/arc/bsd-_setjmp.S
> new file mode 100644
> index 000000000000..90b99cd8c3e0
> --- /dev/null
> +++ b/sysdeps/arc/bsd-_setjmp.S
> @@ -0,0 +1 @@
> +/* _setjmp is in setjmp.S.  */

Ok.

> diff --git a/sysdeps/arc/bsd-setjmp.S b/sysdeps/arc/bsd-setjmp.S
> new file mode 100644
> index 000000000000..d3b823c118bc
> --- /dev/null
> +++ b/sysdeps/arc/bsd-setjmp.S
> @@ -0,0 +1 @@
> +/* setjmp is in setjmp.S.  */

Ok.

> diff --git a/sysdeps/arc/dl-runtime.c b/sysdeps/arc/dl-runtime.c
> new file mode 100644
> index 000000000000..b28da38329f1
> --- /dev/null
> +++ b/sysdeps/arc/dl-runtime.c
> @@ -0,0 +1,33 @@
> +/* dl-runtime helpers for ARC.
> +   Copyright (C) 2017-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +/* PLT jump into resolver passes PC of PLTn, while _dl_fixup expects the
> +   address of corresponding .rela.plt entry.  */
> +
> +#define reloc_index						\
> +({								\
> +  unsigned long int plt0 = D_PTR (l, l_info[DT_PLTGOT]);	\
> +  unsigned long int pltn = reloc_arg;				\
> +  /* Exclude PLT0 and PLT1.  */					\
> +  unsigned long int idx = ((pltn - plt0) / 16) - 2;		\
> +  idx;								\
> +})
> +
> +#define reloc_offset reloc_index * sizeof (PLTREL)
> +
> +#include <elf/dl-runtime.c>

Ok, although this kid of macro are really error-prone: it relies on
not specified arguments (l, reloc_arg) and its variable definition might
clash.

I wonder if it would be better to refactor both reloc_index and
reloc_offset to inline function that might be overriden by the
architecture where required. Something like:

diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index cf5f1d3e82..62f9057937 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -27,6 +27,7 @@
 #include "dynamic-link.h"
 #include <tls.h>
 #include <dl-irel.h>
+#include <dl-runtime.h>
 
 
 #if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
@@ -42,13 +43,6 @@
 # define ARCH_FIXUP_ATTRIBUTE
 #endif
 
-#ifndef reloc_offset
-# define reloc_offset reloc_arg
-# define reloc_index  reloc_arg / sizeof (PLTREL)
-#endif
-
-
-
 /* This function is called through a special trampoline from the PLT the
    first time each PLT entry is called.  We must perform the relocation
    specified in the PLT of the given shared object, and return the resolved
@@ -68,8 +62,11 @@ _dl_fixup (
     = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
   const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
 
+  const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
+
   const PLTREL *const reloc
-    = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
+    = (const void *) (D_PTR (l, l_info[DT_JMPREL])
+		      + reloc_offset (pltgot, reloc_arg));
   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
   const ElfW(Sym) *refsym = sym;
   void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
@@ -182,7 +179,8 @@ _dl_profile_fixup (
 
   /* This is the address in the array where we store the result of previous
      relocations.  */
-  struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
+  struct reloc_result *reloc_result
+    = &l->l_reloc_result[reloc_index (reloc_arg, sizeof (PLTREL))];
 
  /* CONCURRENCY NOTES:
 
@@ -219,8 +217,11 @@ _dl_profile_fixup (
 	= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
       const char *strtab = (const char *) D_PTR (l, l_info[DT_STRTAB]);
 
+      const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
+
       const PLTREL *const reloc
-	= (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
+	= (const void *) (D_PTR (l, l_info[DT_JMPREL])
+			  + reloc_offset (pltgot, reloc_arg));
       const ElfW(Sym) *refsym = &symtab[ELFW(R_SYM) (reloc->r_info)];
       const ElfW(Sym) *defsym = refsym;
       lookup_t result;
@@ -489,7 +490,8 @@ _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
      relocations.  */
   // XXX Maybe the bound information must be stored on the stack since
   // XXX with bind_not a new value could have been stored in the meantime.
-  struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
+  struct reloc_result *reloc_result =
+    &l->l_reloc_result[reloc_index (reloc_arg, sizeof (PLTREL))];
   ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
 					    l_info[DT_SYMTAB])
 		       + reloc_result->boundndx);
diff --git a/elf/dl-runtime.h b/elf/dl-runtime.h
new file mode 100644
index 0000000000..901249f912
--- /dev/null
+++ b/elf/dl-runtime.h
@@ -0,0 +1,11 @@
+static inline uintptr_t
+reloc_offset (uintptr_t plt0, uintptr_t pltn)
+{
+  return pltn;
+}
+
+static inline uintptr_t
+reloc_index (uintptr_t pltn, size_t size)
+{
+  return pltn / size;
+}
diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
index 885a3f1837..2d061b150f 100644
--- a/sysdeps/hppa/dl-runtime.c
+++ b/sysdeps/hppa/dl-runtime.c
@@ -17,10 +17,6 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* Clear PA_GP_RELOC bit in relocation offset.  */
-#define reloc_offset (reloc_arg & ~PA_GP_RELOC)
-#define reloc_index  (reloc_arg & ~PA_GP_RELOC) / sizeof (PLTREL)
-
 #include <elf/dl-runtime.c>
 
 /* The caller has encountered a partially relocated function descriptor.
diff --git a/sysdeps/hppa/dl-runtime.h b/sysdeps/hppa/dl-runtime.h
new file mode 100644
index 0000000000..dc12fd1071
--- /dev/null
+++ b/sysdeps/hppa/dl-runtime.h
@@ -0,0 +1,12 @@
+/* Clear PA_GP_RELOC bit in relocation offset.  */
+static inline uintptr_t
+reloc_offset (uintptr_t plt0, uintptr_t pltn)
+{
+  return pltn & ~PA_GP_RELOC;
+}
+
+static inline uintptr_t
+reloc_index (uintptr_t pltn, size_t size)
+{
+  return (pltn & ~PA_GP_RELOC )/ size;
+}
diff --git a/sysdeps/x86_64/dl-runtime.c b/sysdeps/x86_64/dl-runtime.h
similarity index 60%
rename from sysdeps/x86_64/dl-runtime.c
rename to sysdeps/x86_64/dl-runtime.h
index b625d1e882..494ff47b70 100644
--- a/sysdeps/x86_64/dl-runtime.c
+++ b/sysdeps/x86_64/dl-runtime.h
@@ -3,7 +3,14 @@
    also use the index.  Therefore it is wasteful to compute the offset
    in the trampoline just to reverse the operation immediately
    afterwards.  */
-#define reloc_offset reloc_arg * sizeof (PLTREL)
-#define reloc_index  reloc_arg
+static inline uintptr_t
+reloc_offset (uintptr_t plt0, uintptr_t pltn)
+{
+  return pltn * sizeof (ElfW(Rela));
+}
 
-#include <elf/dl-runtime.c>
+static inline uintptr_t
+reloc_index (uintptr_t pltn, size_t size)
+{
+  return pltn;
+}

> diff --git a/sysdeps/arc/dl-sysdep.h b/sysdeps/arc/dl-sysdep.h
> new file mode 100644
> index 000000000000..6382c05bf485
> --- /dev/null
> +++ b/sysdeps/arc/dl-sysdep.h
> @@ -0,0 +1,25 @@
> +/* System-specific settings for dynamic linker code.  ARC version.
> +   Copyright (C) 2009-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include_next <dl-sysdep.h>
> +
> +/* _dl_argv cannot be attribute_relro, because _dl_start_user
> +   might write into it after _dl_start returns.  */
> +#define DL_ARGV_NOT_RELRO 1
> +
> +#define DL_EXTERN_PROTECTED_DATA

Ok.

> diff --git a/sysdeps/arc/dl-trampoline.S b/sysdeps/arc/dl-trampoline.S
> new file mode 100644
> index 000000000000..3dad904caaf9
> --- /dev/null
> +++ b/sysdeps/arc/dl-trampoline.S
> @@ -0,0 +1,80 @@
> +/* PLT trampolines.  ARC version.
> +   Copyright (C) 2005-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sysdep.h>
> +#include <libc-symbols.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +
> +/* Save the registers which resolver could possibly clobber
> +	r0-r9: args to the function - symbol being resolved
> +	r10-r12 are already clobbered by PLTn, PLT0 thus neednot be saved.  */
> +
> +.macro	SAVE_CALLER_SAVED
> +	push_s	r0
> +	push_s	r1
> +	push_s	r2
> +	push_s	r3
> +	st.a	r4, [sp, -4]
> +	st.a	r5, [sp, -4]
> +	st.a	r6, [sp, -4]
> +	st.a	r7, [sp, -4]
> +	st.a	r8, [sp, -4]
> +	st.a	r9, [sp, -4]
> +	cfi_adjust_cfa_offset (40)
> +	push_s	blink
> +	cfi_adjust_cfa_offset (4)
> +	cfi_rel_offset (blink, 0)
> +.endm
> +
> +.macro RESTORE_CALLER_SAVED_BUT_R0
> +	ld.ab	blink,[sp, 4]
> +	cfi_adjust_cfa_offset (-4)
> +	cfi_restore (blink)
> +	ld.ab	r9, [sp, 4]
> +	ld.ab	r8, [sp, 4]
> +	ld.ab	r7, [sp, 4]
> +	ld.ab	r6, [sp, 4]
> +	ld.ab	r5, [sp, 4]
> +	ld.ab	r4, [sp, 4]
> +	pop_s   r3
> +	pop_s   r2
> +	pop_s   r1
> +	cfi_adjust_cfa_offset (-36)
> +.endm
> +
> +/* Upon entry, PLTn, which led us here, sets up the following regs
> +	r11 = Module info (tpnt pointer as expected by resolver)
> +	r12 = PC of the PLTn itself - needed by resolver to find
> +	      corresponding .rela.plt entry.  */
> +
> +ENTRY (_dl_runtime_resolve)
> +	; args to func being resolved, which resolver might clobber
> +	SAVE_CALLER_SAVED
> +
> +	mov_s 	r1, r12
> +	bl.d  	_dl_fixup
> +	mov   	r0, r11
> +
> +	RESTORE_CALLER_SAVED_BUT_R0
> +	j_s.d   [r0]    /* r0 has resolved function addr.  */
> +	pop_s   r0      /* restore first arg to resolved call.  */
> +	cfi_adjust_cfa_offset (-4)
> +	cfi_restore (r0)
> +END (_dl_runtime_resolve)

Ok, although I am not seeing why exactly you need asm macros here.

> diff --git a/sysdeps/arc/gccframe.h b/sysdeps/arc/gccframe.h
> new file mode 100644
> index 000000000000..5d547fd40a6c
> --- /dev/null
> +++ b/sysdeps/arc/gccframe.h
> @@ -0,0 +1,21 @@
> +/* Definition of object in frame unwind info.  ARC version.
> +   Copyright (C) 2017-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#define FIRST_PSEUDO_REGISTER 40
> +
> +#include <sysdeps/generic/gccframe.h>

Ok.

> diff --git a/sysdeps/arc/jmpbuf-offsets.h b/sysdeps/arc/jmpbuf-offsets.h
> new file mode 100644
> index 000000000000..a76af7d0f7ce
> --- /dev/null
> +++ b/sysdeps/arc/jmpbuf-offsets.h
> @@ -0,0 +1,47 @@
> +/* Private macros for accessing __jmp_buf contents.  ARC version.
> +   Copyright (C) 2006-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +/* Save offsets within __jmp_buf
> +   We don't use most of these symbols; they are here for documentation. */
> +
> +/* Callee Regs.  */
> +#define JB_R13 0
> +#define JB_R14 1
> +#define JB_R15 2
> +#define JB_R16 3
> +#define JB_R17 4
> +#define JB_R18 5
> +#define JB_R19 6
> +#define JB_R20 7
> +#define JB_R21 8
> +#define JB_R22 9
> +#define JB_R23 10
> +#define JB_R24 11
> +#define JB_R25 12
> +
> +/* Frame Pointer, Stack Pointer, Branch-n-link.  */
> +#define JB_FP  13
> +#define JB_SP  14
> +#define JB_BLINK  15
> +
> +/* We save space for some extra state to accommodate future changes
> +   This is number of words.  */
> +#define JB_NUM	32
> +
> +/* Helper for generic ____longjmp_chk.  */
> +#define JB_FRAME_ADDRESS(buf) ((void *) (unsigned long int) (buf[JB_SP]))

Ok.

> diff --git a/sysdeps/arc/jmpbuf-unwind.h b/sysdeps/arc/jmpbuf-unwind.h
> new file mode 100644
> index 000000000000..b333cd51c80e
> --- /dev/null
> +++ b/sysdeps/arc/jmpbuf-unwind.h
> @@ -0,0 +1,47 @@
> +/* Examine __jmp_buf for unwinding frames.  ARC version.
> +   Copyright (C) 2005-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <setjmp.h>
> +#include <jmpbuf-offsets.h>
> +#include <stdint.h>
> +#include <unwind.h>
> +
> +/* 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 jmpbuf)
> +{
> +  uintptr_t sp = jmpbuf[JB_SP];
> +#ifdef PTR_DEMANGLE
> +  PTR_DEMANGLE (sp);
> +#endif
> +  return sp;
> +}
> +
> +#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
> +  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf_sp (_jmpbuf) - (_adj)))
> +
> +/* We use the normal longjmp for unwinding.  */

Ok.

> +#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
> diff --git a/sysdeps/arc/machine-gmon.h b/sysdeps/arc/machine-gmon.h
> new file mode 100644
> index 000000000000..5fcde54722f2
> --- /dev/null
> +++ b/sysdeps/arc/machine-gmon.h
> @@ -0,0 +1,35 @@
> +/* Machine-dependent definitions for profiling support.  ARC version.
> +   Copyright (C) 1996-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sysdep.h>
> +
> +#define _MCOUNT_DECL(frompc, selfpc)					\
> +static void								\
> +__mcount_internal (unsigned long int frompc, unsigned long int selfpc)
> +
> +/* This is very simple as gcc does all the heavy lifting at _mcount call site
> +    - sets up caller's blink in r0, so frompc is setup correctly
> +    - preserve argument registers for original call.  */
> +
> +#define MCOUNT								\
> +void									\
> +_mcount (void *frompc)							\
> +{									\
> +  __mcount_internal ((unsigned long int) frompc,			\
> +		     (unsigned long int) __builtin_return_address (0));	\
> +}

Ok.

> diff --git a/sysdeps/arc/memusage.h b/sysdeps/arc/memusage.h
> new file mode 100644
> index 000000000000..c72beb1ce9a4
> --- /dev/null
> +++ b/sysdeps/arc/memusage.h
> @@ -0,0 +1,23 @@
> +/* Machine-specific definitions for memory usage profiling, ARC version.
> +   Copyright (C) 2000-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#define GETSP() ({ register uintptr_t stack_ptr asm ("sp"); stack_ptr; })
> +
> +#define uatomic32_t unsigned int

Not sure if this is really required now that we are moving to C11 atomic
model withing glibc itself. Maybe we could just use uint32_t on
malloc/memusage.c and rely on atomic macros instead.

> +
> +#include <sysdeps/generic/memusage.h>

Ok.

> diff --git a/sysdeps/arc/setjmp.S b/sysdeps/arc/setjmp.S
> new file mode 100644
> index 000000000000..e745f81643e3
> --- /dev/null
> +++ b/sysdeps/arc/setjmp.S
> @@ -0,0 +1,66 @@
> +/* setjmp for ARC.
> +   Copyright (C) 1991-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +
> +#include <sysdep.h>
> +
> +/* Upon entry r0 = jump buffer into which regs will be saved.  */
> +ENTRY (setjmp)
> +	b.d	__sigsetjmp
> +	mov	r1, 1		; save signals
> +END (setjmp)
> +
> +/* Upon entry r0 = jump buffer into which regs will be saved.  */
> +ENTRY (_setjmp)
> +	b.d	__sigsetjmp
> +	mov	r1, 0		/* don't save signals.  */
> +END (_setjmp)
> +libc_hidden_def (_setjmp)
> +
> +/* Upon entry
> +   r0 = jump buffer into which regs will be saved
> +   r1 = do we need to save signals.  */
> +ENTRY (__sigsetjmp)
> +
> +	st_s r13, [r0]
> +	st_s r14, [r0,4]
> +	st   r15, [r0,8]
> +	st   r16, [r0,12]
> +	st   r17, [r0,16]
> +	st   r18, [r0,20]
> +	st   r19, [r0,24]
> +	st   r20, [r0,28]
> +	st   r21, [r0,32]
> +	st   r22, [r0,36]
> +	st   r23, [r0,40]
> +	st   r24, [r0,44]
> +	st   r25, [r0,48]
> +	st   fp,  [r0,52]
> +	st   sp,  [r0,56]
> +
> +	/* Make a note of where longjmp will return to.
> +	   that will be right next to this setjmp call-site which will be
> +	   contained in blink, since "C" caller of this routine will do
> +	   a branch-n-link */
> +
> +	st   blink, [r0,60]
> +	b    __sigjmp_save
> +
> +END (__sigsetjmp)
> +
> +libc_hidden_def (__sigsetjmp)

Ok.

> diff --git a/sysdeps/arc/sysdep.h b/sysdeps/arc/sysdep.h
> new file mode 100644
> index 000000000000..e94955ed9d5f
> --- /dev/null
> +++ b/sysdeps/arc/sysdep.h
> @@ -0,0 +1,48 @@
> +/* Assembler macros for ARC.
> +   Copyright (C) 2017-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sysdeps/generic/sysdep.h>
> +
> +#ifdef	__ASSEMBLER__
> +
> +/* Syntactic details of assembler.
> +   ; is not newline but comment, # is also for comment.  */
> +# define ASM_SIZE_DIRECTIVE(name) .size name,.-name
> +
> +# define ENTRY(name)						\
> +	.align 4				ASM_LINE_SEP	\
> +	.globl C_SYMBOL_NAME(name)		ASM_LINE_SEP	\
> +	.type C_SYMBOL_NAME(name),%function	ASM_LINE_SEP	\
> +	C_LABEL(name)				ASM_LINE_SEP	\
> +	cfi_startproc				ASM_LINE_SEP	\
> +	CALL_MCOUNT
> +
> +# undef  END
> +# define END(name)						\
> +	cfi_endproc				ASM_LINE_SEP	\
> +	ASM_SIZE_DIRECTIVE(name)
> +
> +# ifdef SHARED
> +#  define PLTJMP(_x)	_x##@plt
> +# else
> +#  define PLTJMP(_x)	_x
> +# endif
> +
> +# define CALL_MCOUNT		/* Do nothing for now.  */
> +
> +#endif	/* __ASSEMBLER__ */

Ok.

> diff --git a/sysdeps/arc/tls-macros.h b/sysdeps/arc/tls-macros.h
> new file mode 100644
> index 000000000000..b96425569143
> --- /dev/null
> +++ b/sysdeps/arc/tls-macros.h
> @@ -0,0 +1,47 @@
> +/* Macros to support TLS testing in times of missing compiler support.  ARC version.
> +   Copyright (C) 2017-2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +
> +/* For now.  */
> +#define TLS_LD(x)	TLS_IE(x)
> +
> +#define TLS_GD(x)					\
> +  ({ int *__result;					\
> +     __asm__ ("add r0, pcl, @" #x "@tlsgd      \n"     	\
> +	  ".tls_gd_ld " #x "`bl __tls_get_addr@plt \n"	\
> +	  "mov %0, r0                    \n"		\
> +	  : "=&r" (__result)				\
> +	  ::"r0","r1","r2","r3","r4","r5","r6","r7",	\
> +	    "r8","r9","r10","r11","r12");		\
> +     __result; })
> +
> +#define TLS_LE(x)					\
> +  ({ int *__result;					\
> +     void *tp = __builtin_thread_pointer ();		\
> +     __asm__ ("add %0, %1, @" #x "@tpoff   \n"		\
> +	  : "=r" (__result) : "r"(tp));	        	\
> +     __result; })
> +
> +#define TLS_IE(x)					\
> +  ({ int *__result;					\
> +     void *tp = __builtin_thread_pointer ();		\
> +     __asm__ ("ld %0, [pcl, @" #x "@tlsie]      \n"     \
> +	  "add %0, %1, %0                       \n"	\
> +	  : "=&r" (__result) : "r" (tp));		\
> +     __result; })
> 

Ok.
Vineet Gupta May 27, 2020, 10:15 p.m. UTC | #2
On 5/27/20 11:26 AM, Adhemerval Zanella via Libc-alpha wrote:
> 
> 
> On 22/04/2020 22:41, Vineet Gupta via Libc-alpha wrote:
>> This code deals with the ARC ABI.
>>
>> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
> 
> We do not use DCO, but rather copyright assignment.

Right, removed that now.

> Looks ok in general, with some comments below.

Thx for taking a look.

>> +;@ r1 = value that setjmp( ) will return due to this longjmp
> 
> Since all .S files are processed by gcc assembly implementation usually
> use C style comment (/* ... */). Same applies to other assembly
> implementations.

OK, I can update throughout, although I like the small assembler comments which
are on the same line.


>> diff --git a/sysdeps/arc/dl-runtime.c b/sysdeps/arc/dl-runtime.c
>> new file mode 100644
>> index 000000000000..b28da38329f1
>> --- /dev/null
>> +++ b/sysdeps/arc/dl-runtime.c
>> @@ -0,0 +1,33 @@
>> +/* dl-runtime helpers for ARC.
>> +   Copyright (C) 2017-2020 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
>> +   <https://www.gnu.org/licenses/>.  */
>> +
>> +/* PLT jump into resolver passes PC of PLTn, while _dl_fixup expects the
>> +   address of corresponding .rela.plt entry.  */
>> +
>> +#define reloc_index						\
>> +({								\
>> +  unsigned long int plt0 = D_PTR (l, l_info[DT_PLTGOT]);	\
>> +  unsigned long int pltn = reloc_arg;				\
>> +  /* Exclude PLT0 and PLT1.  */					\
>> +  unsigned long int idx = ((pltn - plt0) / 16) - 2;		\
>> +  idx;								\
>> +})
>> +
>> +#define reloc_offset reloc_index * sizeof (PLTREL)
>> +
>> +#include <elf/dl-runtime.c>
> 
> Ok, although this kid of macro are really error-prone: it relies on
> not specified arguments (l, reloc_arg) and its variable definition might
> clash.
> 
> I wonder if it would be better to refactor both reloc_index and
> reloc_offset to inline function that might be overriden by the
> architecture where required. Something like:
> 
> diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
> index cf5f1d3e82..62f9057937 100644
> --- a/elf/dl-runtime.c
> +++ b/elf/dl-runtime.c
> @@ -27,6 +27,7 @@
>  #include "dynamic-link.h"
>  #include <tls.h>
>  #include <dl-irel.h>
> +#include <dl-runtime.h>
>  
>  
>  #if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
> @@ -42,13 +43,6 @@
>  # define ARCH_FIXUP_ATTRIBUTE
>  #endif
>  
> -#ifndef reloc_offset
> -# define reloc_offset reloc_arg
> -# define reloc_index  reloc_arg / sizeof (PLTREL)
> -#endif
> -
> -
> -
>  /* This function is called through a special trampoline from the PLT the
>     first time each PLT entry is called.  We must perform the relocation
>     specified in the PLT of the given shared object, and return the resolved
> @@ -68,8 +62,11 @@ _dl_fixup (
>      = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
>    const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
>  
> +  const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
> +
>    const PLTREL *const reloc
> -    = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
> +    = (const void *) (D_PTR (l, l_info[DT_JMPREL])
> +		      + reloc_offset (pltgot, reloc_arg));
>    const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
>    const ElfW(Sym) *refsym = sym;
>    void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
> @@ -182,7 +179,8 @@ _dl_profile_fixup (
>  
>    /* This is the address in the array where we store the result of previous
>       relocations.  */
> -  struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
> +  struct reloc_result *reloc_result
> +    = &l->l_reloc_result[reloc_index (reloc_arg, sizeof (PLTREL))];
>  
>   /* CONCURRENCY NOTES:
>  
> @@ -219,8 +217,11 @@ _dl_profile_fixup (
>  	= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
>        const char *strtab = (const char *) D_PTR (l, l_info[DT_STRTAB]);
>  
> +      const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
> +
>        const PLTREL *const reloc
> -	= (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
> +	= (const void *) (D_PTR (l, l_info[DT_JMPREL])
> +			  + reloc_offset (pltgot, reloc_arg));
>        const ElfW(Sym) *refsym = &symtab[ELFW(R_SYM) (reloc->r_info)];
>        const ElfW(Sym) *defsym = refsym;
>        lookup_t result;
> @@ -489,7 +490,8 @@ _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
>       relocations.  */
>    // XXX Maybe the bound information must be stored on the stack since
>    // XXX with bind_not a new value could have been stored in the meantime.
> -  struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
> +  struct reloc_result *reloc_result =
> +    &l->l_reloc_result[reloc_index (reloc_arg, sizeof (PLTREL))];
>    ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
>  					    l_info[DT_SYMTAB])
>  		       + reloc_result->boundndx);
> diff --git a/elf/dl-runtime.h b/elf/dl-runtime.h
> new file mode 100644
> index 0000000000..901249f912
> --- /dev/null
> +++ b/elf/dl-runtime.h
> @@ -0,0 +1,11 @@
> +static inline uintptr_t
> +reloc_offset (uintptr_t plt0, uintptr_t pltn)
> +{
> +  return pltn;
> +}
> +
> +static inline uintptr_t
> +reloc_index (uintptr_t pltn, size_t size)
> +{
> +  return pltn / size;
> +}
> diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
> index 885a3f1837..2d061b150f 100644
> --- a/sysdeps/hppa/dl-runtime.c
> +++ b/sysdeps/hppa/dl-runtime.c
> @@ -17,10 +17,6 @@
>     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
>     02111-1307 USA.  */
>  
> -/* Clear PA_GP_RELOC bit in relocation offset.  */
> -#define reloc_offset (reloc_arg & ~PA_GP_RELOC)
> -#define reloc_index  (reloc_arg & ~PA_GP_RELOC) / sizeof (PLTREL)
> -
>  #include <elf/dl-runtime.c>
>  
>  /* The caller has encountered a partially relocated function descriptor.
> diff --git a/sysdeps/hppa/dl-runtime.h b/sysdeps/hppa/dl-runtime.h
> new file mode 100644
> index 0000000000..dc12fd1071
> --- /dev/null
> +++ b/sysdeps/hppa/dl-runtime.h
> @@ -0,0 +1,12 @@
> +/* Clear PA_GP_RELOC bit in relocation offset.  */
> +static inline uintptr_t
> +reloc_offset (uintptr_t plt0, uintptr_t pltn)
> +{
> +  return pltn & ~PA_GP_RELOC;
> +}
> +
> +static inline uintptr_t
> +reloc_index (uintptr_t pltn, size_t size)
> +{
> +  return (pltn & ~PA_GP_RELOC )/ size;
> +}
> diff --git a/sysdeps/x86_64/dl-runtime.c b/sysdeps/x86_64/dl-runtime.h
> similarity index 60%
> rename from sysdeps/x86_64/dl-runtime.c
> rename to sysdeps/x86_64/dl-runtime.h
> index b625d1e882..494ff47b70 100644
> --- a/sysdeps/x86_64/dl-runtime.c
> +++ b/sysdeps/x86_64/dl-runtime.h
> @@ -3,7 +3,14 @@
>     also use the index.  Therefore it is wasteful to compute the offset
>     in the trampoline just to reverse the operation immediately
>     afterwards.  */
> -#define reloc_offset reloc_arg * sizeof (PLTREL)
> -#define reloc_index  reloc_arg
> +static inline uintptr_t
> +reloc_offset (uintptr_t plt0, uintptr_t pltn)
> +{
> +  return pltn * sizeof (ElfW(Rela));
> +}
>  
> -#include <elf/dl-runtime.c>
> +static inline uintptr_t
> +reloc_index (uintptr_t pltn, size_t size)
> +{
> +  return pltn;
> +}

Indeed looks much sane now. Do you want me to break out this code as a separate
patch, ahead of the series ?

>> +
>> +.macro RESTORE_CALLER_SAVED_BUT_R0
>> +	ld.ab	blink,[sp, 4]
>> +	cfi_adjust_cfa_offset (-4)
>> +	cfi_restore (blink)
>> +	ld.ab	r9, [sp, 4]
>> +	ld.ab	r8, [sp, 4]
>> +	ld.ab	r7, [sp, 4]
>> +	ld.ab	r6, [sp, 4]
>> +	ld.ab	r5, [sp, 4]
>> +	ld.ab	r4, [sp, 4]
>> +	pop_s   r3
>> +	pop_s   r2
>> +	pop_s   r1
>> +	cfi_adjust_cfa_offset (-36)
>> +.endm
>> +
>> +/* Upon entry, PLTn, which led us here, sets up the following regs
>> +	r11 = Module info (tpnt pointer as expected by resolver)
>> +	r12 = PC of the PLTn itself - needed by resolver to find
>> +	      corresponding .rela.plt entry.  */
>> +
>> +ENTRY (_dl_runtime_resolve)
>> +	; args to func being resolved, which resolver might clobber
>> +	SAVE_CALLER_SAVED
>> +
>> +	mov_s 	r1, r12
>> +	bl.d  	_dl_fixup
>> +	mov   	r0, r11
>> +
>> +	RESTORE_CALLER_SAVED_BUT_R0
>> +	j_s.d   [r0]    /* r0 has resolved function addr.  */
>> +	pop_s   r0      /* restore first arg to resolved call.  */
>> +	cfi_adjust_cfa_offset (-4)
>> +	cfi_restore (r0)
>> +END (_dl_runtime_resolve)
> 
> Ok, although I am not seeing why exactly you need asm macros here.

Yes this is just a relic of code from the past, I can opencode it.

>> diff --git a/sysdeps/arc/gccframe.h b/sysdeps/arc/gccframe.h
>> new file mode 100644
>> index 000000000000..5d547fd40a6c
>> --- /dev/null
>> +++ b/sysdeps/arc/gccframe.h
>> @@ -0,0 +1,21 @@
>> +/* Definition of object in frame unwind info.  ARC version.
>> +   Copyright (C) 2017-2020 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
>> +   <https://www.gnu.org/licenses/>.  */
>> +
>> +#define FIRST_PSEUDO_REGISTER 40
>> +
>> +#include <sysdeps/generic/gccframe.h>
> 
> Ok.
> 
>> diff --git a/sysdeps/arc/jmpbuf-offsets.h b/sysdeps/arc/jmpbuf-offsets.h
>> new file mode 100644

>> +
>> +/* Callee Regs.  */
>> +#define JB_R13 0
>> +#define JB_R14 1
>> +#define JB_R15 2
>> +#define JB_R16 3
>> +#define JB_R17 4
>> +#define JB_R18 5
>> +#define JB_R19 6
>> +#define JB_R20 7
>> +#define JB_R21 8
>> +#define JB_R22 9
>> +#define JB_R23 10
>> +#define JB_R24 11
>> +#define JB_R25 12

I'll probably drop these as these are not used anyways. Also will help declutter
on the next architecture where the ABI for callee regs is changed from r13-25 to
r14-r26.

>> +
>> +/* Frame Pointer, Stack Pointer, Branch-n-link.  */
>> +#define JB_FP  13
>> +#define JB_SP  14
>> +#define JB_BLINK  15
>> +
>> +/* We save space for some extra state to accommodate future changes
>> +   This is number of words.  */
>> +#define JB_NUM	32
>> +
>> +/* Helper for generic ____longjmp_chk.  */
>> +#define JB_FRAME_ADDRESS(buf) ((void *) (unsigned long int) (buf[JB_SP]))
> 
> Ok.
> 

>> diff --git a/sysdeps/arc/memusage.h b/sysdeps/arc/memusage.h

>> +
>> +#define GETSP() ({ register uintptr_t stack_ptr asm ("sp"); stack_ptr; })
>> +
>> +#define uatomic32_t unsigned int
> 
> Not sure if this is really required now that we are moving to C11 atomic
> model withing glibc itself. Maybe we could just use uint32_t on
> malloc/memusage.c and rely on atomic macros instead.

But that would be much bigger change, and orthogonal to the port. So perhaps we
add it for now and then do the bigger/sweeping change.
Adhemerval Zanella May 29, 2020, 1:56 p.m. UTC | #3
On 27/05/2020 19:15, Vineet Gupta wrote:
> On 5/27/20 11:26 AM, Adhemerval Zanella via Libc-alpha wrote:
>>
>>
>> On 22/04/2020 22:41, Vineet Gupta via Libc-alpha wrote:
>>> This code deals with the ARC ABI.
>>>
>>> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
>>
>> We do not use DCO, but rather copyright assignment.
> 
> Right, removed that now.
> 
>> Looks ok in general, with some comments below.
> 
> Thx for taking a look.
> 
>>> +;@ r1 = value that setjmp( ) will return due to this longjmp
>>
>> Since all .S files are processed by gcc assembly implementation usually
>> use C style comment (/* ... */). Same applies to other assembly
>> implementations.
> 
> OK, I can update throughout, although I like the small assembler comments which
> are on the same line.

I don't have a strong preference and I am not sure if there is a strict
code guideline for comment in assembly implementations. It was more a
suggestion, since other assembly implementations tend to use C style
comment as well.


>>> diff --git a/sysdeps/arc/memusage.h b/sysdeps/arc/memusage.h
> 
>>> +
>>> +#define GETSP() ({ register uintptr_t stack_ptr asm ("sp"); stack_ptr; })
>>> +
>>> +#define uatomic32_t unsigned int
>>
>> Not sure if this is really required now that we are moving to C11 atomic
>> model withing glibc itself. Maybe we could just use uint32_t on
>> malloc/memusage.c and rely on atomic macros instead.
> 
> But that would be much bigger change, and orthogonal to the port. So perhaps we
> add it for now and then do the bigger/sweeping change.
> 

Indeed, it was more a open note for a future cleanup. The current
definition is fine as is.
Vineet Gupta June 3, 2020, 8:05 p.m. UTC | #4
On 5/27/20 11:26 AM, Adhemerval Zanella via Libc-alpha wrote:
> +ENTRY (__longjmp)
> +
> +	ld_s r13,   [r0]
> +	ld_s r14,   [r0,4]
> +	ld   r15,   [r0,8]
> +	ld   r16,   [r0,12]
> +	ld   r17,   [r0,16]
> +	ld   r18,   [r0,20]
> +	ld   r19,   [r0,24]
> +	ld   r20,   [r0,28]
> +	ld   r21,   [r0,32]
> +	ld   r22,   [r0,36]
> +	ld   r23,   [r0,40]
> +	ld   r24,   [r0,44]
> +	ld   r25,   [r0,48]
> +
> +	ld   blink, [r0,60]
> +	ld   fp,    [r0,52]
> +	ld   sp,    [r0,56]
> +
> +	mov.f  r0, r1	; get the setjmp return value(due to longjmp) in place
> +
> +	j.d    [blink]	; to caller of setjmp location, right after the call
> +	mov.z  r0, 1	; can't let setjmp return 0 when it is due to longjmp
> +
> +END (__longjmp)

So wanted to pick your brains on this thing. While longjmp is not necessarily an
application hotspot, it seems bulk load/store can in general benefit from with
ARCv2 double load/store instructions LDD/STD which work with register pairs.

So we could have 2 variants which compile differently to one runtime
implementation or better still have 2 runtime implementations which could be
switched to using hwcaps (which I can add to kernel). Does that require IFUNC
which ARC toolchain doesn't support ATM.

-Vineet
Florian Weimer June 4, 2020, 9:04 a.m. UTC | #5
* Vineet Gupta via Libc-alpha:

> On 5/27/20 11:26 AM, Adhemerval Zanella via Libc-alpha wrote:
>> +ENTRY (__longjmp)
>> +
>> +	ld_s r13,   [r0]
>> +	ld_s r14,   [r0,4]
>> +	ld   r15,   [r0,8]
>> +	ld   r16,   [r0,12]
>> +	ld   r17,   [r0,16]
>> +	ld   r18,   [r0,20]
>> +	ld   r19,   [r0,24]
>> +	ld   r20,   [r0,28]
>> +	ld   r21,   [r0,32]
>> +	ld   r22,   [r0,36]
>> +	ld   r23,   [r0,40]
>> +	ld   r24,   [r0,44]
>> +	ld   r25,   [r0,48]
>> +
>> +	ld   blink, [r0,60]
>> +	ld   fp,    [r0,52]
>> +	ld   sp,    [r0,56]
>> +
>> +	mov.f  r0, r1	; get the setjmp return value(due to longjmp) in place
>> +
>> +	j.d    [blink]	; to caller of setjmp location, right after the call
>> +	mov.z  r0, 1	; can't let setjmp return 0 when it is due to longjmp
>> +
>> +END (__longjmp)
>
> So wanted to pick your brains on this thing. While longjmp is not necessarily an
> application hotspot, it seems bulk load/store can in general benefit from with
> ARCv2 double load/store instructions LDD/STD which work with register pairs.
>
> So we could have 2 variants which compile differently to one runtime
> implementation or better still have 2 runtime implementations which could be
> switched to using hwcaps (which I can add to kernel). Does that require IFUNC
> which ARC toolchain doesn't support ATM.

Without IFUNCs, you would have to use a conditional branch in the
(single) __longjmp implementation.

With IFUNCs, all internal callers will have to go through a function
pointer—or those internal callers would have to turn into IFUNCs as
well.

So it's doubtful whether this is beneficial in this case.

Also, please double-check the register list.  The ABI manual says this:

| The scratch registers are not preserved across function calls. When
| calling an external function, the compiler assumes that registers %r0
| through %r12 and %r30 are trashed; and that %r13 through %r29 are
| preserved.  The EV6x processor reserves %r25.

r27 and r28 are handled as fp and sp.  That leaves r26 and r29 as
unhandled.

r25 seems to be the thread pointer.  It cannot change its value between
setjmp and longjmp because you cannot longjmp onto another thread, so
saving and restoring it should not be necessary.

Thanks,
Florian
Vineet Gupta June 4, 2020, 7:01 p.m. UTC | #6
On 6/4/20 2:04 AM, Florian Weimer via Libc-alpha wrote:
> * Vineet Gupta via Libc-alpha:
> 
>> On 5/27/20 11:26 AM, Adhemerval Zanella via Libc-alpha wrote:
>>> +ENTRY (__longjmp)
>>> +
>>> +	ld_s r13,   [r0]
>>> +	ld_s r14,   [r0,4]
>>> +	ld   r15,   [r0,8]
>>> +	ld   r16,   [r0,12]
>>> +	ld   r17,   [r0,16]
>>> +	ld   r18,   [r0,20]
>>> +	ld   r19,   [r0,24]
>>> +	ld   r20,   [r0,28]
>>> +	ld   r21,   [r0,32]
>>> +	ld   r22,   [r0,36]
>>> +	ld   r23,   [r0,40]
>>> +	ld   r24,   [r0,44]
>>> +	ld   r25,   [r0,48]
>>> +
>>> +	ld   blink, [r0,60]
>>> +	ld   fp,    [r0,52]
>>> +	ld   sp,    [r0,56]
>>> +
>>> +	mov.f  r0, r1	; get the setjmp return value(due to longjmp) in place
>>> +
>>> +	j.d    [blink]	; to caller of setjmp location, right after the call
>>> +	mov.z  r0, 1	; can't let setjmp return 0 when it is due to longjmp
>>> +
>>> +END (__longjmp)
>>
>> So wanted to pick your brains on this thing. While longjmp is not necessarily an
>> application hotspot, it seems bulk load/store can in general benefit from with
>> ARCv2 double load/store instructions LDD/STD which work with register pairs.
>>
>> So we could have 2 variants which compile differently to one runtime
>> implementation or better still have 2 runtime implementations which could be
>> switched to using hwcaps (which I can add to kernel). Does that require IFUNC
>> which ARC toolchain doesn't support ATM.
> 
> Without IFUNCs, you would have to use a conditional branch in the
> (single) __longjmp implementation.
> 
> With IFUNCs, all internal callers will have to go through a function
> pointer—or those internal callers would have to turn into IFUNCs as
> well.
> 
> So it's doubtful whether this is beneficial in this case.
> 
> Also, please double-check the register list.  The ABI manual says this:
> 
> | The scratch registers are not preserved across function calls. When
> | calling an external function, the compiler assumes that registers %r0
> | through %r12 and %r30 are trashed; and that %r13 through %r29 are
> | preserved.  The EV6x processor reserves %r25.
> 
> r27 and r28 are handled as fp and sp.  That leaves r26 and r29 as
> unhandled.

r29 is ILINK1 (Interrupt Link Register) and accessible only in kernel mode so can
be ignored here.

r26 is GP and indeed could be potential problem and thus needs saving. The reason
it is missing in first place is the historic use of GP as "PIC assist" register
which has since been reworked in compiler). As of today the register allocator is
simply ignoring GP.

> r25 seems to be the thread pointer.  It cannot change its value between
> setjmp and longjmp because you cannot longjmp onto another thread, so
> saving and restoring it should not be necessary.

Good point. This can be removed.

It seems that *jmp and *context routines deal with same set of regs (in different
structures) and perhaps I should make them reuse asm code.
Vineet Gupta June 4, 2020, 11:56 p.m. UTC | #7
On 6/4/20 12:01 PM, Vineet Gupta wrote:
> On 6/4/20 2:04 AM, Florian Weimer via Libc-alpha wrote:
>> * Vineet Gupta via Libc-alpha:
>>
>>> On 5/27/20 11:26 AM, Adhemerval Zanella via Libc-alpha wrote:
>>>> +ENTRY (__longjmp)
>>>> +
>>>> +	ld_s r13,   [r0]
>>>> +	ld_s r14,   [r0,4]
>>>> +	ld   r15,   [r0,8]
>>>> +	ld   r16,   [r0,12]
>>>> +	ld   r17,   [r0,16]
>>>> +	ld   r18,   [r0,20]
>>>> +	ld   r19,   [r0,24]
>>>> +	ld   r20,   [r0,28]
>>>> +	ld   r21,   [r0,32]
>>>> +	ld   r22,   [r0,36]
>>>> +	ld   r23,   [r0,40]
>>>> +	ld   r24,   [r0,44]
>>>> +	ld   r25,   [r0,48]
>>>> +
>>>> +	ld   blink, [r0,60]
>>>> +	ld   fp,    [r0,52]
>>>> +	ld   sp,    [r0,56]
>>>> +
>>>> +	mov.f  r0, r1	; get the setjmp return value(due to longjmp) in place
>>>> +
>>>> +	j.d    [blink]	; to caller of setjmp location, right after the call
>>>> +	mov.z  r0, 1	; can't let setjmp return 0 when it is due to longjmp
>>>> +
>>>> +END (__longjmp)
>>>
>>> So wanted to pick your brains on this thing. While longjmp is not necessarily an
>>> application hotspot, it seems bulk load/store can in general benefit from with
>>> ARCv2 double load/store instructions LDD/STD which work with register pairs.
>>>
>>> So we could have 2 variants which compile differently to one runtime
>>> implementation or better still have 2 runtime implementations which could be
>>> switched to using hwcaps (which I can add to kernel). Does that require IFUNC
>>> which ARC toolchain doesn't support ATM.
>>
>> Without IFUNCs, you would have to use a conditional branch in the
>> (single) __longjmp implementation.
>>
>> With IFUNCs, all internal callers will have to go through a function
>> pointer—or those internal callers would have to turn into IFUNCs as
>> well.
>>
>> So it's doubtful whether this is beneficial in this case.
>>
>> Also, please double-check the register list.  The ABI manual says this:
>>
>> | The scratch registers are not preserved across function calls. When
>> | calling an external function, the compiler assumes that registers %r0
>> | through %r12 and %r30 are trashed; and that %r13 through %r29 are
>> | preserved.  The EV6x processor reserves %r25.
>>
>> r27 and r28 are handled as fp and sp.  That leaves r26 and r29 as
>> unhandled.
> 
> r29 is ILINK1 (Interrupt Link Register) and accessible only in kernel mode so can
> be ignored here.
> 
> r26 is GP and indeed could be potential problem and thus needs saving. The reason
> it is missing in first place is the historic use of GP as "PIC assist" register
> which has since been reworked in compiler). As of today the register allocator is
> simply ignoring GP.
> 
>> r25 seems to be the thread pointer.  It cannot change its value between
>> setjmp and longjmp because you cannot longjmp onto another thread, so
>> saving and restoring it should not be necessary.
> 
> Good point. This can be removed.
> 
> It seems that *jmp and *context routines deal with same set of regs (in different
> structures) and perhaps I should make them reuse asm code.

It seems better to keep them seperate afterall.

On the topic of ABI, and considering the future port to ARCv3 with slightly
different ABI I'm thinking I should simplify the existing
sysdeps/unix/sysv/linux/arc/sys/ucontext.h (patch 8/13) by not naming specific
registers (while still being compliant with the kernel exported interface).

-Vineet
diff mbox series

Patch

diff --git a/sysdeps/arc/__longjmp.S b/sysdeps/arc/__longjmp.S
new file mode 100644
index 000000000000..ffc3daa7de72
--- /dev/null
+++ b/sysdeps/arc/__longjmp.S
@@ -0,0 +1,50 @@ 
+/* longjmp for ARC.
+   Copyright (C) 2017-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+
+;@ r0 = jump buffer from which regs will be restored
+;@ r1 = value that setjmp( ) will return due to this longjmp
+
+ENTRY (__longjmp)
+
+	ld_s r13,   [r0]
+	ld_s r14,   [r0,4]
+	ld   r15,   [r0,8]
+	ld   r16,   [r0,12]
+	ld   r17,   [r0,16]
+	ld   r18,   [r0,20]
+	ld   r19,   [r0,24]
+	ld   r20,   [r0,28]
+	ld   r21,   [r0,32]
+	ld   r22,   [r0,36]
+	ld   r23,   [r0,40]
+	ld   r24,   [r0,44]
+	ld   r25,   [r0,48]
+
+	ld   blink, [r0,60]
+	ld   fp,    [r0,52]
+	ld   sp,    [r0,56]
+
+	mov.f  r0, r1	; get the setjmp return value(due to longjmp) in place
+
+	j.d    [blink]	; to caller of setjmp location, right after the call
+	mov.z  r0, 1	; can't let setjmp return 0 when it is due to longjmp
+
+END (__longjmp)
diff --git a/sysdeps/arc/abort-instr.h b/sysdeps/arc/abort-instr.h
new file mode 100644
index 000000000000..49f33613c404
--- /dev/null
+++ b/sysdeps/arc/abort-instr.h
@@ -0,0 +1,2 @@ 
+/* FLAG 1 is privilege mode only instruction, hence will crash any program.  */
+#define ABORT_INSTRUCTION asm ("flag 1")
diff --git a/sysdeps/arc/bits/endianness.h b/sysdeps/arc/bits/endianness.h
new file mode 100644
index 000000000000..8f17ca84b485
--- /dev/null
+++ b/sysdeps/arc/bits/endianness.h
@@ -0,0 +1,15 @@ 
+#ifndef _BITS_ENDIANNESS_H
+#define _BITS_ENDIANNESS_H 1
+
+#ifndef _BITS_ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+/* ARC has selectable endianness.  */
+#ifdef __BIG_ENDIAN__
+# define __BYTE_ORDER __BIG_ENDIAN
+#else
+# define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
+
+#endif /* bits/endianness.h */
diff --git a/sysdeps/arc/bits/setjmp.h b/sysdeps/arc/bits/setjmp.h
new file mode 100644
index 000000000000..333e5cce3bea
--- /dev/null
+++ b/sysdeps/arc/bits/setjmp.h
@@ -0,0 +1,26 @@ 
+/* Define the machine-dependent type `jmp_buf'.  ARC version.
+   Copyright (C) 1992-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _ARC_BITS_SETJMP_H
+#define _ARC_BITS_SETJMP_H 1
+
+/* Saves r13-r25 (callee-saved), fp (frame pointer), sp (stack pointer),
+   blink (branch-n-link).  */
+typedef long int __jmp_buf[32];
+
+#endif
diff --git a/sysdeps/arc/bsd-_setjmp.S b/sysdeps/arc/bsd-_setjmp.S
new file mode 100644
index 000000000000..90b99cd8c3e0
--- /dev/null
+++ b/sysdeps/arc/bsd-_setjmp.S
@@ -0,0 +1 @@ 
+/* _setjmp is in setjmp.S.  */
diff --git a/sysdeps/arc/bsd-setjmp.S b/sysdeps/arc/bsd-setjmp.S
new file mode 100644
index 000000000000..d3b823c118bc
--- /dev/null
+++ b/sysdeps/arc/bsd-setjmp.S
@@ -0,0 +1 @@ 
+/* setjmp is in setjmp.S.  */
diff --git a/sysdeps/arc/dl-runtime.c b/sysdeps/arc/dl-runtime.c
new file mode 100644
index 000000000000..b28da38329f1
--- /dev/null
+++ b/sysdeps/arc/dl-runtime.c
@@ -0,0 +1,33 @@ 
+/* dl-runtime helpers for ARC.
+   Copyright (C) 2017-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+/* PLT jump into resolver passes PC of PLTn, while _dl_fixup expects the
+   address of corresponding .rela.plt entry.  */
+
+#define reloc_index						\
+({								\
+  unsigned long int plt0 = D_PTR (l, l_info[DT_PLTGOT]);	\
+  unsigned long int pltn = reloc_arg;				\
+  /* Exclude PLT0 and PLT1.  */					\
+  unsigned long int idx = ((pltn - plt0) / 16) - 2;		\
+  idx;								\
+})
+
+#define reloc_offset reloc_index * sizeof (PLTREL)
+
+#include <elf/dl-runtime.c>
diff --git a/sysdeps/arc/dl-sysdep.h b/sysdeps/arc/dl-sysdep.h
new file mode 100644
index 000000000000..6382c05bf485
--- /dev/null
+++ b/sysdeps/arc/dl-sysdep.h
@@ -0,0 +1,25 @@ 
+/* System-specific settings for dynamic linker code.  ARC version.
+   Copyright (C) 2009-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include_next <dl-sysdep.h>
+
+/* _dl_argv cannot be attribute_relro, because _dl_start_user
+   might write into it after _dl_start returns.  */
+#define DL_ARGV_NOT_RELRO 1
+
+#define DL_EXTERN_PROTECTED_DATA
diff --git a/sysdeps/arc/dl-trampoline.S b/sysdeps/arc/dl-trampoline.S
new file mode 100644
index 000000000000..3dad904caaf9
--- /dev/null
+++ b/sysdeps/arc/dl-trampoline.S
@@ -0,0 +1,80 @@ 
+/* PLT trampolines.  ARC version.
+   Copyright (C) 2005-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <libc-symbols.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Save the registers which resolver could possibly clobber
+	r0-r9: args to the function - symbol being resolved
+	r10-r12 are already clobbered by PLTn, PLT0 thus neednot be saved.  */
+
+.macro	SAVE_CALLER_SAVED
+	push_s	r0
+	push_s	r1
+	push_s	r2
+	push_s	r3
+	st.a	r4, [sp, -4]
+	st.a	r5, [sp, -4]
+	st.a	r6, [sp, -4]
+	st.a	r7, [sp, -4]
+	st.a	r8, [sp, -4]
+	st.a	r9, [sp, -4]
+	cfi_adjust_cfa_offset (40)
+	push_s	blink
+	cfi_adjust_cfa_offset (4)
+	cfi_rel_offset (blink, 0)
+.endm
+
+.macro RESTORE_CALLER_SAVED_BUT_R0
+	ld.ab	blink,[sp, 4]
+	cfi_adjust_cfa_offset (-4)
+	cfi_restore (blink)
+	ld.ab	r9, [sp, 4]
+	ld.ab	r8, [sp, 4]
+	ld.ab	r7, [sp, 4]
+	ld.ab	r6, [sp, 4]
+	ld.ab	r5, [sp, 4]
+	ld.ab	r4, [sp, 4]
+	pop_s   r3
+	pop_s   r2
+	pop_s   r1
+	cfi_adjust_cfa_offset (-36)
+.endm
+
+/* Upon entry, PLTn, which led us here, sets up the following regs
+	r11 = Module info (tpnt pointer as expected by resolver)
+	r12 = PC of the PLTn itself - needed by resolver to find
+	      corresponding .rela.plt entry.  */
+
+ENTRY (_dl_runtime_resolve)
+	; args to func being resolved, which resolver might clobber
+	SAVE_CALLER_SAVED
+
+	mov_s 	r1, r12
+	bl.d  	_dl_fixup
+	mov   	r0, r11
+
+	RESTORE_CALLER_SAVED_BUT_R0
+	j_s.d   [r0]    /* r0 has resolved function addr.  */
+	pop_s   r0      /* restore first arg to resolved call.  */
+	cfi_adjust_cfa_offset (-4)
+	cfi_restore (r0)
+END (_dl_runtime_resolve)
diff --git a/sysdeps/arc/gccframe.h b/sysdeps/arc/gccframe.h
new file mode 100644
index 000000000000..5d547fd40a6c
--- /dev/null
+++ b/sysdeps/arc/gccframe.h
@@ -0,0 +1,21 @@ 
+/* Definition of object in frame unwind info.  ARC version.
+   Copyright (C) 2017-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define FIRST_PSEUDO_REGISTER 40
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/sysdeps/arc/jmpbuf-offsets.h b/sysdeps/arc/jmpbuf-offsets.h
new file mode 100644
index 000000000000..a76af7d0f7ce
--- /dev/null
+++ b/sysdeps/arc/jmpbuf-offsets.h
@@ -0,0 +1,47 @@ 
+/* Private macros for accessing __jmp_buf contents.  ARC version.
+   Copyright (C) 2006-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+/* Save offsets within __jmp_buf
+   We don't use most of these symbols; they are here for documentation. */
+
+/* Callee Regs.  */
+#define JB_R13 0
+#define JB_R14 1
+#define JB_R15 2
+#define JB_R16 3
+#define JB_R17 4
+#define JB_R18 5
+#define JB_R19 6
+#define JB_R20 7
+#define JB_R21 8
+#define JB_R22 9
+#define JB_R23 10
+#define JB_R24 11
+#define JB_R25 12
+
+/* Frame Pointer, Stack Pointer, Branch-n-link.  */
+#define JB_FP  13
+#define JB_SP  14
+#define JB_BLINK  15
+
+/* We save space for some extra state to accommodate future changes
+   This is number of words.  */
+#define JB_NUM	32
+
+/* Helper for generic ____longjmp_chk.  */
+#define JB_FRAME_ADDRESS(buf) ((void *) (unsigned long int) (buf[JB_SP]))
diff --git a/sysdeps/arc/jmpbuf-unwind.h b/sysdeps/arc/jmpbuf-unwind.h
new file mode 100644
index 000000000000..b333cd51c80e
--- /dev/null
+++ b/sysdeps/arc/jmpbuf-unwind.h
@@ -0,0 +1,47 @@ 
+/* Examine __jmp_buf for unwinding frames.  ARC version.
+   Copyright (C) 2005-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+
+/* 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 jmpbuf)
+{
+  uintptr_t sp = jmpbuf[JB_SP];
+#ifdef PTR_DEMANGLE
+  PTR_DEMANGLE (sp);
+#endif
+  return sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_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/arc/machine-gmon.h b/sysdeps/arc/machine-gmon.h
new file mode 100644
index 000000000000..5fcde54722f2
--- /dev/null
+++ b/sysdeps/arc/machine-gmon.h
@@ -0,0 +1,35 @@ 
+/* Machine-dependent definitions for profiling support.  ARC version.
+   Copyright (C) 1996-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+#define _MCOUNT_DECL(frompc, selfpc)					\
+static void								\
+__mcount_internal (unsigned long int frompc, unsigned long int selfpc)
+
+/* This is very simple as gcc does all the heavy lifting at _mcount call site
+    - sets up caller's blink in r0, so frompc is setup correctly
+    - preserve argument registers for original call.  */
+
+#define MCOUNT								\
+void									\
+_mcount (void *frompc)							\
+{									\
+  __mcount_internal ((unsigned long int) frompc,			\
+		     (unsigned long int) __builtin_return_address (0));	\
+}
diff --git a/sysdeps/arc/memusage.h b/sysdeps/arc/memusage.h
new file mode 100644
index 000000000000..c72beb1ce9a4
--- /dev/null
+++ b/sysdeps/arc/memusage.h
@@ -0,0 +1,23 @@ 
+/* Machine-specific definitions for memory usage profiling, ARC version.
+   Copyright (C) 2000-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("sp"); stack_ptr; })
+
+#define uatomic32_t unsigned int
+
+#include <sysdeps/generic/memusage.h>
diff --git a/sysdeps/arc/setjmp.S b/sysdeps/arc/setjmp.S
new file mode 100644
index 000000000000..e745f81643e3
--- /dev/null
+++ b/sysdeps/arc/setjmp.S
@@ -0,0 +1,66 @@ 
+/* setjmp for ARC.
+   Copyright (C) 1991-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+
+#include <sysdep.h>
+
+/* Upon entry r0 = jump buffer into which regs will be saved.  */
+ENTRY (setjmp)
+	b.d	__sigsetjmp
+	mov	r1, 1		; save signals
+END (setjmp)
+
+/* Upon entry r0 = jump buffer into which regs will be saved.  */
+ENTRY (_setjmp)
+	b.d	__sigsetjmp
+	mov	r1, 0		/* don't save signals.  */
+END (_setjmp)
+libc_hidden_def (_setjmp)
+
+/* Upon entry
+   r0 = jump buffer into which regs will be saved
+   r1 = do we need to save signals.  */
+ENTRY (__sigsetjmp)
+
+	st_s r13, [r0]
+	st_s r14, [r0,4]
+	st   r15, [r0,8]
+	st   r16, [r0,12]
+	st   r17, [r0,16]
+	st   r18, [r0,20]
+	st   r19, [r0,24]
+	st   r20, [r0,28]
+	st   r21, [r0,32]
+	st   r22, [r0,36]
+	st   r23, [r0,40]
+	st   r24, [r0,44]
+	st   r25, [r0,48]
+	st   fp,  [r0,52]
+	st   sp,  [r0,56]
+
+	/* Make a note of where longjmp will return to.
+	   that will be right next to this setjmp call-site which will be
+	   contained in blink, since "C" caller of this routine will do
+	   a branch-n-link */
+
+	st   blink, [r0,60]
+	b    __sigjmp_save
+
+END (__sigsetjmp)
+
+libc_hidden_def (__sigsetjmp)
diff --git a/sysdeps/arc/sysdep.h b/sysdeps/arc/sysdep.h
new file mode 100644
index 000000000000..e94955ed9d5f
--- /dev/null
+++ b/sysdeps/arc/sysdep.h
@@ -0,0 +1,48 @@ 
+/* Assembler macros for ARC.
+   Copyright (C) 2017-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sysdeps/generic/sysdep.h>
+
+#ifdef	__ASSEMBLER__
+
+/* Syntactic details of assembler.
+   ; is not newline but comment, # is also for comment.  */
+# define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+# define ENTRY(name)						\
+	.align 4				ASM_LINE_SEP	\
+	.globl C_SYMBOL_NAME(name)		ASM_LINE_SEP	\
+	.type C_SYMBOL_NAME(name),%function	ASM_LINE_SEP	\
+	C_LABEL(name)				ASM_LINE_SEP	\
+	cfi_startproc				ASM_LINE_SEP	\
+	CALL_MCOUNT
+
+# undef  END
+# define END(name)						\
+	cfi_endproc				ASM_LINE_SEP	\
+	ASM_SIZE_DIRECTIVE(name)
+
+# ifdef SHARED
+#  define PLTJMP(_x)	_x##@plt
+# else
+#  define PLTJMP(_x)	_x
+# endif
+
+# define CALL_MCOUNT		/* Do nothing for now.  */
+
+#endif	/* __ASSEMBLER__ */
diff --git a/sysdeps/arc/tls-macros.h b/sysdeps/arc/tls-macros.h
new file mode 100644
index 000000000000..b96425569143
--- /dev/null
+++ b/sysdeps/arc/tls-macros.h
@@ -0,0 +1,47 @@ 
+/* Macros to support TLS testing in times of missing compiler support.  ARC version.
+   Copyright (C) 2017-2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+
+/* For now.  */
+#define TLS_LD(x)	TLS_IE(x)
+
+#define TLS_GD(x)					\
+  ({ int *__result;					\
+     __asm__ ("add r0, pcl, @" #x "@tlsgd      \n"     	\
+	  ".tls_gd_ld " #x "`bl __tls_get_addr@plt \n"	\
+	  "mov %0, r0                    \n"		\
+	  : "=&r" (__result)				\
+	  ::"r0","r1","r2","r3","r4","r5","r6","r7",	\
+	    "r8","r9","r10","r11","r12");		\
+     __result; })
+
+#define TLS_LE(x)					\
+  ({ int *__result;					\
+     void *tp = __builtin_thread_pointer ();		\
+     __asm__ ("add %0, %1, @" #x "@tpoff   \n"		\
+	  : "=r" (__result) : "r"(tp));	        	\
+     __result; })
+
+#define TLS_IE(x)					\
+  ({ int *__result;					\
+     void *tp = __builtin_thread_pointer ();		\
+     __asm__ ("ld %0, [pcl, @" #x "@tlsie]      \n"     \
+	  "add %0, %1, %0                       \n"	\
+	  : "=&r" (__result) : "r" (tp));		\
+     __result; })