Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 374982
b: refs/heads/master
c: 3ae908c
h: refs/heads/master
v: v3
  • Loading branch information
Max Filippov authored and Chris Zankel committed May 9, 2013
1 parent affed09 commit b0598c1
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 2 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: 3e4196a5cc9cff50900f3dc8acc3d41e5963fd50
refs/heads/master: 3ae908c99e944a7a5c4f4b2d8c603a6bc57b728b
34 changes: 33 additions & 1 deletion trunk/arch/xtensa/include/asm/ftrace.h
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
/* empty */
/*
* arch/xtensa/include/asm/ftrace.h
*
* 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.
*
* Copyright (C) 2013 Tensilica Inc.
*/
#ifndef _XTENSA_FTRACE_H
#define _XTENSA_FTRACE_H

#include <asm/processor.h>

#define HAVE_ARCH_CALLER_ADDR
#define CALLER_ADDR0 ({ unsigned long a0, a1; \
__asm__ __volatile__ ( \
"mov %0, a0\n" \
"mov %1, a1\n" \
: "=r"(a0), "=r"(a1) : : ); \
MAKE_PC_FROM_RA(a0, a1); })
#ifdef CONFIG_FRAME_POINTER
extern unsigned long return_address(unsigned level);
#define CALLER_ADDR1 return_address(1)
#define CALLER_ADDR2 return_address(2)
#define CALLER_ADDR3 return_address(3)
#else
#define CALLER_ADDR1 (0)
#define CALLER_ADDR2 (0)
#define CALLER_ADDR3 (0)
#endif

#endif /* _XTENSA_FTRACE_H */
33 changes: 33 additions & 0 deletions trunk/arch/xtensa/kernel/stacktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,36 @@ void save_stack_trace(struct stack_trace *trace)
EXPORT_SYMBOL_GPL(save_stack_trace);

#endif

#ifdef CONFIG_FRAME_POINTER

struct return_addr_data {
unsigned long addr;
unsigned skip;
};

static int return_address_cb(struct stackframe *frame, void *data)
{
struct return_addr_data *r = data;

if (r->skip) {
--r->skip;
return 0;
}
if (!kernel_text_address(frame->pc))
return 0;
r->addr = frame->pc;
return 1;
}

unsigned long return_address(unsigned level)
{
struct return_addr_data r = {
.skip = level + 1,
};
walk_stackframe(stack_pointer(NULL), return_address_cb, &r);
return r.addr;
}
EXPORT_SYMBOL(return_address);

#endif

0 comments on commit b0598c1

Please sign in to comment.