diff options
Diffstat (limited to 'ports/sysdeps/microblaze/backtrace.c')
-rw-r--r-- | ports/sysdeps/microblaze/backtrace.c | 139 |
1 files changed, 0 insertions, 139 deletions
diff --git a/ports/sysdeps/microblaze/backtrace.c b/ports/sysdeps/microblaze/backtrace.c deleted file mode 100644 index 6b0c617b0f..0000000000 --- a/ports/sysdeps/microblaze/backtrace.c +++ /dev/null @@ -1,139 +0,0 @@ -/* 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) |