Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 173400
b: refs/heads/master
c: ac4fac8
h: refs/heads/master
v: v3
  • Loading branch information
Paul Mundt committed Oct 13, 2009
1 parent bbfdaf6 commit b1ff8f8
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 43 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5852b203ef1b85a8eacc1cc686ed9bac11ee31cc
refs/heads/master: ac4fac8cb24ab209ae373a3e3e9995dff7d0c394
5 changes: 5 additions & 0 deletions trunk/arch/sh/include/asm/dwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@
#define DWARF_ARCH_RA_REG 17

#ifndef __ASSEMBLY__

#include <linux/compiler.h>
#include <linux/bug.h>
#include <linux/list.h>

/*
* Read either the frame pointer (r14) or the stack pointer (r15).
* NOTE: this MUST be inlined.
Expand Down
50 changes: 8 additions & 42 deletions trunk/arch/sh/include/asm/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,52 +32,18 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
return addr;
}


#ifdef CONFIG_DWARF_UNWINDER
#include <asm/dwarf.h>
/* arch/sh/kernel/return_address.c */
extern void *return_address(unsigned int);

#define HAVE_ARCH_CALLER_ADDR

static inline unsigned long dwarf_return_address(int depth)
{
struct dwarf_frame *frame;
unsigned long ra;
int i;

for (i = 0, frame = NULL, ra = 0; i <= depth; i++) {
struct dwarf_frame *tmp;

tmp = dwarf_unwind_stack(ra, frame);

if (frame)
dwarf_free_frame(frame);

frame = tmp;

if (!frame || !frame->return_addr)
break;

ra = frame->return_addr;
}

/* Failed to unwind the stack to the specified depth. */
WARN_ON(i != depth + 1);

if (frame)
dwarf_free_frame(frame);

return ra;
}

#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
#define CALLER_ADDR1 dwarf_return_address(1)
#define CALLER_ADDR2 dwarf_return_address(2)
#define CALLER_ADDR3 dwarf_return_address(3)
#define CALLER_ADDR4 dwarf_return_address(4)
#define CALLER_ADDR5 dwarf_return_address(5)
#define CALLER_ADDR6 dwarf_return_address(6)

#endif /* CONFIG_DWARF_UNWINDER */
#define CALLER_ADDR1 ((unsigned long)return_address(1))
#define CALLER_ADDR2 ((unsigned long)return_address(2))
#define CALLER_ADDR3 ((unsigned long)return_address(3))
#define CALLER_ADDR4 ((unsigned long)return_address(4))
#define CALLER_ADDR5 ((unsigned long)return_address(5))
#define CALLER_ADDR6 ((unsigned long)return_address(6))

#endif /* __ASSEMBLY__ */
#endif /* CONFIG_FUNCTION_TRACER */
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/sh/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ endif

obj-y := debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o \
machvec.o nmi_debug.o process_$(BITS).o ptrace_$(BITS).o \
return_address.o \
setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o \
syscalls_$(BITS).o time.o topology.o traps.o \
traps_$(BITS).o unwinder.o
Expand Down
54 changes: 54 additions & 0 deletions trunk/arch/sh/kernel/return_address.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* arch/sh/kernel/return_address.c
*
* Copyright (C) 2009 Matt Fleming
* Copyright (C) 2009 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/kernel.h>
#include <asm/dwarf.h>

#ifdef CONFIG_DWARF_UNWINDER

void *return_address(unsigned int depth)
{
struct dwarf_frame *frame;
unsigned long ra;
int i;

for (i = 0, frame = NULL, ra = 0; i <= depth; i++) {
struct dwarf_frame *tmp;

tmp = dwarf_unwind_stack(ra, frame);

if (frame)
dwarf_free_frame(frame);

frame = tmp;

if (!frame || !frame->return_addr)
break;

ra = frame->return_addr;
}

/* Failed to unwind the stack to the specified depth. */
WARN_ON(i != depth + 1);

if (frame)
dwarf_free_frame(frame);

return (void *)ra;
}

#else

void *return_address(unsigned int depth)
{
return NULL;
}

#endif

0 comments on commit b1ff8f8

Please sign in to comment.