Message ID | 20200423014126.10417-2-vgupta@synopsys.com |
---|---|
State | New |
Headers | show |
Series | glibc port to ARC processors | expand |
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.
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.
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.
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
* 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
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.
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 --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; })
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