ARC: ABI Implementation

This code deals with the ARC ABI.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
This commit is contained in:
Vineet Gupta 2018-10-23 11:38:32 -07:00
parent 04deeaa9ea
commit 0e7d930c4c
17 changed files with 547 additions and 0 deletions

49
sysdeps/arc/__longjmp.S Normal file
View File

@ -0,0 +1,49 @@
/* longjmp for ARC.
Copyright (C) 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)
LDR (blink, r0, 0)
LDR (sp, r0, 1)
LDR (fp, r0, 2)
LDR (gp, r0, 3)
LDR (r13, r0, 4)
LDR (r14, r0, 5)
LDR (r15, r0, 6)
LDR (r16, r0, 7)
LDR (r17, r0, 8)
LDR (r18, r0, 9)
LDR (r19, r0, 10)
LDR (r20, r0, 11)
LDR (r21, r0, 12)
LDR (r22, r0, 13)
LDR (r23, r0, 14)
LDR (r24, r0, 15)
mov.f r0, r1
j.d [blink]
mov.z r0, 1 /* don't return 0 to setjmp callsite from longjmp. */
END (__longjmp)

View File

@ -0,0 +1,2 @@
/* FLAG 1 is privilege mode only instruction, hence will crash any program. */
#define ABORT_INSTRUCTION asm ("flag 1")

View File

@ -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 */

26
sysdeps/arc/bits/setjmp.h Normal file
View File

@ -0,0 +1,26 @@
/* Define the machine-dependent type 'jmp_buf'. ARC version.
Copyright (C) 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

View File

@ -0,0 +1 @@
/* _setjmp is in setjmp.S. */

1
sysdeps/arc/bsd-setjmp.S Normal file
View File

@ -0,0 +1 @@
/* setjmp is in setjmp.S. */

42
sysdeps/arc/dl-runtime.h Normal file
View File

@ -0,0 +1,42 @@
/* Helpers for On-demand PLT fixup for shared objects. ARC version.
Copyright (C) 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.
- @plt0: runtime pc of first plt entry (DT_PLTGOT)
- @pltn: runtime pc of plt entry being resolved
- @size: size of .plt.rela entry (unused). */
static inline uintptr_t
reloc_index (uintptr_t plt0, uintptr_t pltn, size_t size)
{
unsigned long int idx = pltn - plt0;
/* PLT trampoline is 16 bytes. */
idx /= 16;
/* Exclude PLT0 and PLT1. */
return idx - 2;
}
static inline uintptr_t
reloc_offset (uintptr_t plt0, uintptr_t pltn)
{
size_t sz = sizeof (ElfW(Rela));
return reloc_index (plt0, pltn, sz) * sz;
}

25
sysdeps/arc/dl-sysdep.h Normal file
View File

@ -0,0 +1,25 @@
/* System-specific settings for dynamic linker code. ARC version.
Copyright (C) 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

View File

@ -0,0 +1,72 @@
/* PLT trampolines. ARC version.
Copyright (C) 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>
/* resolver has atypical calling ABI (r11 and r12)
PLTn which lands us here, sets up
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)
/* save args to func being resolved before entering resolver. */
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)
mov_s r1, r12
bl.d _dl_fixup
mov r0, r11
/* restore regs back. */
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)
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)

21
sysdeps/arc/gccframe.h Normal file
View File

@ -0,0 +1,21 @@
/* Definition of object in frame unwind info. ARC version.
Copyright (C) 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>

View File

@ -0,0 +1,22 @@
/* Private macros for accessing __jmp_buf contents. ARC version.
Copyright (C) 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 JB_SP 1
/* Helper for generic ____longjmp_chk. */
#define JB_FRAME_ADDRESS(buf) ((void *) (unsigned long int) (buf[JB_SP]))

View File

@ -0,0 +1,47 @@
/* Examine __jmp_buf for unwinding frames. ARC version.
Copyright (C) 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)

View File

@ -0,0 +1,35 @@
/* Machine-dependent definitions for profiling support. ARC version.
Copyright (C) 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)); \
}

23
sysdeps/arc/memusage.h Normal file
View File

@ -0,0 +1,23 @@
/* Machine-specific definitions for memory usage profiling, ARC version.
Copyright (C) 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>

66
sysdeps/arc/setjmp.S Normal file
View File

@ -0,0 +1,66 @@
/* setjmp for ARC.
Copyright (C) 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)
/* Make a note of where longjmp will return to.
that will be right next to this setjmp call-site in BLINK
since "C" caller of this routine will do a branch-n-link. */
STR (blink, r0, 0)
STR (sp, r0, 1)
STR (fp, r0, 2)
STR (gp, r0, 3)
STR (r13, r0, 4)
STR (r14, r0, 5)
STR (r15, r0, 6)
STR (r16, r0, 7)
STR (r17, r0, 8)
STR (r18, r0, 9)
STR (r19, r0, 10)
STR (r20, r0, 11)
STR (r21, r0, 12)
STR (r22, r0, 13)
STR (r23, r0, 14)
STR (r24, r0, 15)
b __sigjmp_save
END (__sigsetjmp)
libc_hidden_def (__sigsetjmp)

53
sysdeps/arc/sysdep.h Normal file
View File

@ -0,0 +1,53 @@
/* Assembler macros for ARC.
Copyright (C) 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 L(label) .L##label
# define CALL_MCOUNT /* Do nothing for now. */
# define STR(reg, rbase, off) st reg, [rbase, off * 4]
# define LDR(reg, rbase, off) ld reg, [rbase, off * 4]
#endif /* __ASSEMBLER__ */

47
sysdeps/arc/tls-macros.h Normal file
View File

@ -0,0 +1,47 @@
/* Macros to support TLS testing in times of missing compiler support. ARC version.
Copyright (C) 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) \
({ void *__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) \
({ void *__result; \
void *tp = __builtin_thread_pointer (); \
__asm__ ("add %0, %1, @" #x "@tpoff \n" \
: "=r" (__result) : "r"(tp)); \
__result; })
#define TLS_IE(x) \
({ void *__result; \
void *tp = __builtin_thread_pointer (); \
__asm__ ("ld %0, [pcl, @" #x "@tlsie] \n" \
"add %0, %1, %0 \n" \
: "=&r" (__result) : "r" (tp)); \
__result; })