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