Skip to content

Commit

Permalink
[ARM] 5383/2: unwind: Add core support for ARM stack unwinding
Browse files Browse the repository at this point in the history
This patch adds the main functionality for parsing the stack unwinding
information generated by the ARM EABI toolchains. The unwinding
information consists of an index with a pair of words per function and a
table with unwinding instructions. For more information, see "Exception
Handling ABI for the ARM Architecture" at:

http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Catalin Marinas authored and Russell King committed Feb 19, 2009
1 parent 2d7c11b commit bff595c
Show file tree
Hide file tree
Showing 6 changed files with 540 additions and 0 deletions.
5 changes: 5 additions & 0 deletions arch/arm/boot/compressed/vmlinux.lds.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
/DISCARD/ : {
*(.ARM.exidx*)
*(.ARM.extab*)
}

. = TEXT_START;
_text = .;

Expand Down
69 changes: 69 additions & 0 deletions arch/arm/include/asm/unwind.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* arch/arm/include/asm/unwind.h
*
* Copyright (C) 2008 ARM Limited
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#ifndef __ASM_UNWIND_H
#define __ASM_UNWIND_H

#ifndef __ASSEMBLY__

/* Unwind reason code according the the ARM EABI documents */
enum unwind_reason_code {
URC_OK = 0, /* operation completed successfully */
URC_CONTINUE_UNWIND = 8,
URC_FAILURE = 9 /* unspecified failure of some kind */
};

struct unwind_idx {
unsigned long addr;
unsigned long insn;
};

struct unwind_table {
struct list_head list;
struct unwind_idx *start;
struct unwind_idx *stop;
unsigned long begin_addr;
unsigned long end_addr;
};

extern struct unwind_table *unwind_table_add(unsigned long start,
unsigned long size,
unsigned long text_addr,
unsigned long text_size);
extern void unwind_table_del(struct unwind_table *tab);
extern void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk);

#ifdef CONFIG_ARM_UNWIND
extern int __init unwind_init(void);
#else
static inline int __init unwind_init(void)
{
return 0;
}
#endif

#endif /* !__ASSEMBLY__ */

#ifdef CONFIG_ARM_UNWIND
#define UNWIND(code...) code
#else
#define UNWIND(code...)
#endif

#endif /* __ASM_UNWIND_H */
3 changes: 3 additions & 0 deletions arch/arm/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/traps.h>
#include <asm/unwind.h>

#include "compat.h"
#include "atags.h"
Expand Down Expand Up @@ -684,6 +685,8 @@ void __init setup_arch(char **cmdline_p)
struct machine_desc *mdesc;
char *from = default_command_line;

unwind_init();

setup_processor();
mdesc = setup_machine(machine_arch_type);
machine_name = mdesc->name;
Expand Down
10 changes: 10 additions & 0 deletions arch/arm/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <asm/system.h>
#include <asm/unistd.h>
#include <asm/traps.h>
#include <asm/unwind.h>

#include "ptrace.h"
#include "signal.h"
Expand Down Expand Up @@ -61,6 +62,7 @@ void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long
dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
}

#ifndef CONFIG_ARM_UNWIND
/*
* Stack pointers should always be within the kernels view of
* physical memory. If it is not there, then we can't dump
Expand All @@ -74,6 +76,7 @@ static int verify_stack(unsigned long sp)

return 0;
}
#endif

/*
* Dump out the contents of some memory nicely...
Expand Down Expand Up @@ -150,6 +153,12 @@ static void dump_instr(struct pt_regs *regs)
set_fs(fs);
}

#ifdef CONFIG_ARM_UNWIND
static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
unwind_backtrace(regs, tsk);
}
#else
static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
unsigned int fp, mode;
Expand Down Expand Up @@ -184,6 +193,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
if (ok)
c_backtrace(fp, mode);
}
#endif

void dump_stack(void)
{
Expand Down
Loading

0 comments on commit bff595c

Please sign in to comment.