diff options
| author | David Holsgrove <david.holsgrove@xilinx.com> | 2014-02-17 11:08:21 +1000 |
|---|---|---|
| committer | David Holsgrove <david.holsgrove@xilinx.com> | 2014-02-17 11:08:21 +1000 |
| commit | ef114eafbff80525d079d7d6fadd69a58eb8dcc3 (patch) | |
| tree | e643e00a609e9a6cda5ae90e2eb499cb992dd91b /sysdeps/microblaze | |
| parent | ab7ac0f2cf8731fe4c3f3aea6088a7c0127b5725 (diff) | |
| download | glibc-ef114eafbff80525d079d7d6fadd69a58eb8dcc3.tar.xz glibc-ef114eafbff80525d079d7d6fadd69a58eb8dcc3.zip | |
[MicroBlaze]: Move MicroBlaze from ports to sysdeps.
2014-02-17 David Holsgrove <david.holsgrove@xilinx.com>
* sysdeps/microblaze: Move directory from ports/sysdeps/microblaze.
* sysdeps/unix/sysv/linux/microblaze: Move directory from
ports/sysdeps/unix/sysv/linux/microblaze.
* README: Add missing listing for microblaze*-*-linux-gnu.
Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
Diffstat (limited to 'sysdeps/microblaze')
42 files changed, 7783 insertions, 0 deletions
diff --git a/sysdeps/microblaze/Implies b/sysdeps/microblaze/Implies new file mode 100644 index 0000000000..73c766c52e --- /dev/null +++ b/sysdeps/microblaze/Implies @@ -0,0 +1,4 @@ +wordsize-32 +# MicroBlaze uses IEEE 754 floating point. +ieee754/flt-32 +ieee754/dbl-64 diff --git a/sysdeps/microblaze/Makefile b/sysdeps/microblaze/Makefile new file mode 100644 index 0000000000..f7c95ae115 --- /dev/null +++ b/sysdeps/microblaze/Makefile @@ -0,0 +1,11 @@ +ifeq ($(subdir),elf) +CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused +endif + +ifeq ($(subdir),gmon) +sysdep_routines += _mcount +endif + +ifeq ($(subdir),resource) +sysdep_routines += backtrace_linux +endif diff --git a/sysdeps/microblaze/__longjmp.S b/sysdeps/microblaze/__longjmp.S new file mode 100644 index 0000000000..dc588ebfe2 --- /dev/null +++ b/sysdeps/microblaze/__longjmp.S @@ -0,0 +1,55 @@ +/* Copyright (C) 1997-2014 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 + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. */ + +/* void __longjmp (__jmp_buf env, int val) */ + +ENTRY(__longjmp) + lwi r1,r5,0 + lwi r2,r5,4 + lwi r13,r5,8 + lwi r14,r5,12 + lwi r15,r5,16 + lwi r16,r5,20 + lwi r17,r5,24 + lwi r18,r5,28 + lwi r19,r5,32 + lwi r20,r5,36 + lwi r21,r5,40 + lwi r22,r5,44 + lwi r23,r5,48 + lwi r24,r5,52 + lwi r25,r5,56 + lwi r26,r5,60 + lwi r27,r5,64 + lwi r28,r5,68 + lwi r29,r5,72 + lwi r30,r5,76 + lwi r31,r5,80 + addk r3,r6,r0 + beqi r3,L(return_1) + rtsd r15,8 + nop +L(return_1): + rtsd r15,8 + addik r3,r0,1 /* delay slot. */ +END(__longjmp) diff --git a/sysdeps/microblaze/_mcount.S b/sysdeps/microblaze/_mcount.S new file mode 100644 index 0000000000..b3be87e35d --- /dev/null +++ b/sysdeps/microblaze/_mcount.S @@ -0,0 +1,91 @@ +/* Copyright (C) 1997-2014 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 + <http://www.gnu.org/licenses/>. */ + + .global _mcount + .type _mcount, @function +_mcount: + # Save regs. + addik r1, r1,-4 * 24 + swi r31, r1, 4 * 23 + swi r30, r1, 4 * 22 + swi r29, r1, 4 * 21 + swi r28, r1, 4 * 20 + swi r27, r1, 4 * 19 + swi r26, r1, 4 * 18 + swi r25, r1, 4 * 17 + swi r24, r1, 4 * 16 + swi r23, r1, 4 * 15 + swi r22, r1, 4 * 14 + swi r21, r1, 4 * 13 + swi r20, r1, 4 * 12 + swi r19, r1, 4 * 11 + swi r15, r1, 4 * 10 + swi r12, r1, 4 * 9 + swi r11, r1, 4 * 8 + swi r10, r1, 4 * 7 + swi r8, r1, 4 * 6 + swi r7, r1, 4 * 5 + swi r6, r1, 4 * 4 + swi r5, r1, 4 * 3 + swi r4, r1, 4 * 2 + swi r3, r1, 4 * 1 + swi r2, r1, 4 * 0 + +#ifdef SHARED + mfs r20,rpc + addik r20,r20,_GLOBAL_OFFSET_TABLE_+8 + addk r6, r0, r15 # callee is in r15. + brlid r15, __mcount_internal@PLT + lwi r5, r1, 4 * 24 # caller is on the stack. +#else + # Pass from/to in r5 and r6. + addk r6, r0, r15 # callee is in r15. + bralid r15, __mcount_internal + lwi r5, r1, 4 * 24 # caller is on the stack. +#endif + + # Reload regs + lwi r31, r1, 4 * 23 + lwi r30, r1, 4 * 22 + lwi r29, r1, 4 * 21 + lwi r28, r1, 4 * 20 + lwi r27, r1, 4 * 19 + lwi r26, r1, 4 * 18 + lwi r25, r1, 4 * 17 + lwi r24, r1, 4 * 16 + lwi r23, r1, 4 * 15 + lwi r22, r1, 4 * 14 + lwi r21, r1, 4 * 13 + lwi r20, r1, 4 * 12 + lwi r19, r1, 4 * 11 + lwi r15, r1, 4 * 10 + lwi r12, r1, 4 * 9 + lwi r11, r1, 4 * 8 + lwi r10, r1, 4 * 7 + lwi r8, r1, 4 * 6 + lwi r7, r1, 4 * 5 + lwi r6, r1, 4 * 4 + lwi r5, r1, 4 * 3 + lwi r4, r1, 4 * 2 + lwi r3, r1, 4 * 1 + lwi r2, r1, 4 * 0 + + rtsd r15, 8 + addik r1, r1, 4 * 24 + + .size _mcount, . - _mcount diff --git a/sysdeps/microblaze/abort-instr.h b/sysdeps/microblaze/abort-instr.h new file mode 100644 index 0000000000..38469d490a --- /dev/null +++ b/sysdeps/microblaze/abort-instr.h @@ -0,0 +1,2 @@ +/* An instruction which should crash any program is `illegal'. */ +#define ABORT_INSTRUCTION asm ("brki r0, -1") diff --git a/sysdeps/microblaze/asm-syntax.h b/sysdeps/microblaze/asm-syntax.h new file mode 100644 index 0000000000..1d60e654a1 --- /dev/null +++ b/sysdeps/microblaze/asm-syntax.h @@ -0,0 +1,24 @@ +/* Copyright (C) 1997-2014 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 + <http://www.gnu.org/licenses/>. */ + +#undef ALIGN +#define ALIGN(log) .align 1<<log + +#define R_(r) %##r +#define R(r) R_(r) +#define L(label) .##label diff --git a/sysdeps/microblaze/backtrace.c b/sysdeps/microblaze/backtrace.c new file mode 100644 index 0000000000..6b0c617b0f --- /dev/null +++ b/sysdeps/microblaze/backtrace.c @@ -0,0 +1,139 @@ +/* Copyright (C) 2005-2014 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 + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <string.h> +#include <sysdep.h> +#include <signal.h> +#include <execinfo.h> + +extern int +_identify_sighandler (unsigned long fp, unsigned long pc, + unsigned long *pprev_fp, unsigned long *pprev_pc, + unsigned long *retaddr); + +inline long +get_frame_size (unsigned long instr) +{ + return abs ((short signed) (instr & 0xFFFF)); +} + +static unsigned long * +find_frame_creation (unsigned long *pc) +{ + int i; + + /* NOTE: Distance to search is arbitrary. + 250 works well for most things, + 750 picks up things like tcp_recvmsg, + 1000 needed for fat_fill_super. */ + for (i = 0; i < 1000; i++, pc--) + { + unsigned long instr; + unsigned long frame_size; + + instr = *pc; + + /* Is the instruction of the form + addik r1, r1, foo ? */ + if ((instr & 0xFFFF0000) != 0x30210000) + continue; + + frame_size = get_frame_size (instr); + + if ((frame_size < 8) || (frame_size & 3)) + return NULL; + + return pc; + } + return NULL; +} + +static int +lookup_prev_stack_frame (unsigned long fp, unsigned long pc, + unsigned long *pprev_fp, unsigned long *pprev_pc, + unsigned long *retaddr) +{ + unsigned long *prologue = NULL; + + int is_signalhandler = _identify_sighandler (fp, pc, pprev_fp, + pprev_pc, retaddr); + + if (!is_signalhandler) + { + prologue = find_frame_creation ((unsigned long *) pc); + + if (prologue) + { + long frame_size = get_frame_size (*prologue); + *pprev_fp = fp + frame_size; + if (*retaddr != 0) + *pprev_pc = *retaddr; + else + *pprev_pc = *(unsigned long *) fp; + + *retaddr = 0; + if (!*pprev_pc || (*pprev_pc & 3)) + prologue=0; + } + else + { + *pprev_pc = 0; + *pprev_fp = fp; + *retaddr = 0; + } + } + return (!*pprev_pc || (*pprev_pc & 3)) ? -1 : 0; +} + +int +__backtrace (void **array, int size) +{ + unsigned long pc, fp; + unsigned long ppc, pfp; + /* Return address(r15) is required in the signal handler case, since the + return address of the function which causes the signal may not be + recorded in the stack. */ + unsigned long retaddr; + + int count; + int rc = 0; + + __asm__ __volatile__ ("mfs %0, rpc" + : "=r"(pc)); + + __asm__ __volatile__ ("add %0, r1, r0" + : "=r"(fp)); + + array[0] = (void *) pc; + retaddr = 0; + for (count = 1; count < size; count++) + { + rc = lookup_prev_stack_frame (fp, pc, &pfp, &ppc, &retaddr); + + fp = pfp; + pc = ppc; + array[count] = (void *) pc; + if (rc) + return count; + } + return count; +} + +weak_alias (__backtrace, backtrace) +libc_hidden_def (__backtrace) diff --git a/sysdeps/microblaze/backtrace_linux.c b/sysdeps/microblaze/backtrace_linux.c new file mode 100644 index 0000000000..309d7ef000 --- /dev/null +++ b/sysdeps/microblaze/backtrace_linux.c @@ -0,0 +1,59 @@ +/* Copyright (C) 2005-2014 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 + <http://www.gnu.org/licenses/>. */ + +#include <stddef.h> +#include <asm/sigcontext.h> +#include <linux/signal.h> +#include <asm-generic/ucontext.h> +#include <asm/unistd.h> + +int +_identify_sighandler (unsigned long fp, unsigned long pc, + unsigned long *pprev_fp, unsigned long *pprev_pc, + unsigned long *retaddr) +{ |
