Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
c153a58e
Commit
c153a58e
authored
Aug 22, 2009
by
Paul Mundt
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'sh/dwarf-unwinder' of
git://github.com/mfleming/linux-2.6
into sh/dwarf-unwinder
parents
4ab8f241
5580e904
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
252 additions
and
105 deletions
+252
-105
arch/sh/include/asm/bug.h
arch/sh/include/asm/bug.h
+25
-0
arch/sh/include/asm/dwarf.h
arch/sh/include/asm/dwarf.h
+10
-16
arch/sh/include/asm/system.h
arch/sh/include/asm/system.h
+5
-0
arch/sh/include/asm/unwinder.h
arch/sh/include/asm/unwinder.h
+6
-0
arch/sh/kernel/cpu/sh3/entry.S
arch/sh/kernel/cpu/sh3/entry.S
+2
-0
arch/sh/kernel/debugtraps.S
arch/sh/kernel/debugtraps.S
+5
-1
arch/sh/kernel/dwarf.c
arch/sh/kernel/dwarf.c
+166
-80
arch/sh/kernel/traps.c
arch/sh/kernel/traps.c
+5
-2
arch/sh/kernel/traps_32.c
arch/sh/kernel/traps_32.c
+1
-0
arch/sh/kernel/unwinder.c
arch/sh/kernel/unwinder.c
+27
-6
No files found.
arch/sh/include/asm/bug.h
View file @
c153a58e
#ifndef __ASM_SH_BUG_H
#define __ASM_SH_BUG_H
#define TRAPA_UNWINDER_BUG_OPCODE 0xc33b
/* trapa #0x3b */
#define TRAPA_BUG_OPCODE 0xc33e
/* trapa #0x3e */
#ifdef CONFIG_GENERIC_BUG
...
...
@@ -72,6 +73,30 @@ do { \
unlikely(__ret_warn_on); \
})
#define UNWINDER_BUG() \
do { \
__asm__ __volatile__ ( \
"1:\t.short %O0\n" \
_EMIT_BUG_ENTRY \
: \
: "n" (TRAPA_UNWINDER_BUG_OPCODE), \
"i" (__FILE__), \
"i" (__LINE__), "i" (0), \
"i" (sizeof(struct bug_entry))); \
} while (0)
#define UNWINDER_BUG_ON(x) ({ \
int __ret_unwinder_on = !!(x); \
if (__builtin_constant_p(__ret_unwinder_on)) { \
if (__ret_unwinder_on) \
UNWINDER_BUG(); \
} else { \
if (unlikely(__ret_unwinder_on)) \
UNWINDER_BUG(); \
} \
unlikely(__ret_unwinder_on); \
})
#endif
/* CONFIG_GENERIC_BUG */
#include <asm-generic/bug.h>
...
...
arch/sh/include/asm/dwarf.h
View file @
c153a58e
...
...
@@ -265,10 +265,7 @@ struct dwarf_frame {
unsigned
long
pc
;
struct
dwarf_reg
*
regs
;
unsigned
int
num_regs
;
/* how many regs are allocated? */
unsigned
int
depth
;
/* what level are we in the callstack? */
struct
list_head
reg_list
;
unsigned
long
cfa
;
...
...
@@ -292,20 +289,15 @@ struct dwarf_frame {
* @flags: Describes how to calculate the value of this register
*/
struct
dwarf_reg
{
struct
list_head
link
;
unsigned
int
number
;
unsigned
long
addr
;
unsigned
long
flags
;
#define DWARF_REG_OFFSET (1 << 0)
};
/**
* dwarf_stack - a DWARF stack contains a collection of DWARF frames
* @depth: the number of frames in the stack
* @level: an array of DWARF frames, indexed by stack level
*
*/
struct
dwarf_stack
{
unsigned
int
depth
;
struct
dwarf_frame
**
level
;
#define DWARF_VAL_OFFSET (1 << 1)
#define DWARF_UNDEFINED (1 << 2)
};
/*
...
...
@@ -372,13 +364,14 @@ static inline unsigned int DW_CFA_operand(unsigned long insn)
extern
struct
dwarf_frame
*
dwarf_unwind_stack
(
unsigned
long
,
struct
dwarf_frame
*
);
#endif
/* __ASSEMBLY__ */
#endif
/*
!
__ASSEMBLY__ */
#define CFI_STARTPROC .cfi_startproc
#define CFI_ENDPROC .cfi_endproc
#define CFI_DEF_CFA .cfi_def_cfa
#define CFI_REGISTER .cfi_register
#define CFI_REL_OFFSET .cfi_rel_offset
#define CFI_UNDEFINED .cfi_undefined
#else
...
...
@@ -392,6 +385,7 @@ extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
#define CFI_DEF_CFA CFI_IGNORE
#define CFI_REGISTER CFI_IGNORE
#define CFI_REL_OFFSET CFI_IGNORE
#define CFI_UNDEFINED CFI_IGNORE
#ifndef __ASSEMBLY__
static
inline
void
dwarf_unwinder_init
(
void
)
...
...
arch/sh/include/asm/system.h
View file @
c153a58e
...
...
@@ -181,6 +181,11 @@ BUILD_TRAP_HANDLER(breakpoint);
BUILD_TRAP_HANDLER
(
singlestep
);
BUILD_TRAP_HANDLER
(
fpu_error
);
BUILD_TRAP_HANDLER
(
fpu_state_restore
);
BUILD_TRAP_HANDLER
(
unwinder
);
#ifdef CONFIG_BUG
extern
void
handle_BUG
(
struct
pt_regs
*
);
#endif
#define arch_align_stack(x) (x)
...
...
arch/sh/include/asm/unwinder.h
View file @
c153a58e
...
...
@@ -22,4 +22,10 @@ extern void stack_reader_dump(struct task_struct *, struct pt_regs *,
unsigned
long
*
,
const
struct
stacktrace_ops
*
,
void
*
);
/*
* Used by fault handling code to signal to the unwinder code that it
* should switch to a different unwinder.
*/
extern
int
unwinder_faulted
;
#endif
/* _LINUX_UNWINDER_H */
arch/sh/kernel/cpu/sh3/entry.S
View file @
c153a58e
...
...
@@ -508,6 +508,8 @@ ENTRY(handle_interrupt)
bsr
save_regs
!
needs
original
pr
value
in
k3
mov
#-
1
,
k2
!
default
vector
kept
in
k2
setup_frame_reg
!
Setup
return
address
and
jump
to
do_IRQ
mov.l
4
f
,
r9
!
fetch
return
address
lds
r9
,
pr
!
put
return
address
in
pr
...
...
arch/sh/kernel/debugtraps.S
View file @
c153a58e
...
...
@@ -19,6 +19,10 @@
#if !defined(CONFIG_SH_STANDARD_BIOS)
#define sh_bios_handler debug_trap_handler
#endif
#if !defined(CONFIG_DWARF_UNWINDER)
#define unwinder_trap_handler debug_trap_handler
#endif
.
data
...
...
@@ -35,7 +39,7 @@ ENTRY(debug_trap_table)
.
long
debug_trap_handler
/*
0x38
*/
.
long
debug_trap_handler
/*
0x39
*/
.
long
debug_trap_handler
/*
0x3a
*/
.
long
debug
_trap_handler
/*
0x3b
*/
.
long
unwinder
_trap_handler
/*
0x3b
*/
.
long
breakpoint_trap_handler
/*
0x3c
*/
.
long
singlestep_trap_handler
/*
0x3d
*/
.
long
bug_trap_handler
/*
0x3e
*/
...
...
arch/sh/kernel/dwarf.c
View file @
c153a58e
This diff is collapsed.
Click to expand it.
arch/sh/kernel/traps.c
View file @
c153a58e
...
...
@@ -8,7 +8,7 @@
#include <asm/system.h>
#ifdef CONFIG_BUG
static
void
handle_BUG
(
struct
pt_regs
*
regs
)
void
handle_BUG
(
struct
pt_regs
*
regs
)
{
enum
bug_trap_type
tt
;
tt
=
report_bug
(
regs
->
pc
,
regs
);
...
...
@@ -29,7 +29,10 @@ int is_valid_bugaddr(unsigned long addr)
if
(
probe_kernel_address
((
insn_size_t
*
)
addr
,
opcode
))
return
0
;
return
opcode
==
TRAPA_BUG_OPCODE
;
if
(
opcode
==
TRAPA_BUG_OPCODE
||
opcode
==
TRAPA_UNWINDER_BUG_OPCODE
)
return
1
;
return
0
;
}
#endif
...
...
arch/sh/kernel/traps_32.c
View file @
c153a58e
...
...
@@ -136,6 +136,7 @@ static void die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
regs
->
pc
=
fixup
->
fixup
;
return
;
}
die
(
str
,
regs
,
err
);
}
}
...
...
arch/sh/kernel/unwinder.c
View file @
c153a58e
...
...
@@ -54,8 +54,6 @@ static struct list_head unwinder_list = {
static
DEFINE_SPINLOCK
(
unwinder_lock
);
static
atomic_t
unwinder_running
=
ATOMIC_INIT
(
0
);
/**
* select_unwinder - Select the best registered stack unwinder.
*
...
...
@@ -123,6 +121,8 @@ int unwinder_register(struct unwinder *u)
return
ret
;
}
int
unwinder_faulted
=
0
;
/*
* Unwind the call stack and pass information to the stacktrace_ops
* functions. Also handle the case where we need to switch to a new
...
...
@@ -145,20 +145,41 @@ void unwind_stack(struct task_struct *task, struct pt_regs *regs,
* Hopefully this will give us a semi-reliable stacktrace so we
* can diagnose why curr_unwinder->dump() faulted.
*/
if
(
atomic_inc_return
(
&
unwinder_running
)
!=
1
)
{
if
(
unwinder_faulted
)
{
spin_lock_irqsave
(
&
unwinder_lock
,
flags
);
if
(
!
list_is_singular
(
&
unwinder_list
))
{
/* Make sure no one beat us to changing the unwinder */
if
(
unwinder_faulted
&&
!
list_is_singular
(
&
unwinder_list
))
{
list_del
(
&
curr_unwinder
->
list
);
curr_unwinder
=
select_unwinder
();
unwinder_faulted
=
0
;
}
spin_unlock_irqrestore
(
&
unwinder_lock
,
flags
);
atomic_dec
(
&
unwinder_running
);
}
curr_unwinder
->
dump
(
task
,
regs
,
sp
,
ops
,
data
);
}
/*
* Trap handler for UWINDER_BUG() statements. We must switch to the
* unwinder with the next highest rating.
*/
BUILD_TRAP_HANDLER
(
unwinder
)
{
insn_size_t
insn
;
TRAP_HANDLER_DECL
;
/* Rewind */
regs
->
pc
-=
instruction_size
(
ctrl_inw
(
regs
->
pc
-
4
));
insn
=
*
(
insn_size_t
*
)
instruction_pointer
(
regs
);
/* Switch unwinders when unwind_stack() is called */
unwinder_faulted
=
1
;
atomic_dec
(
&
unwinder_running
);
#ifdef CONFIG_BUG
handle_BUG
(
regs
);
#endif
}
EXPORT_SYMBOL_GPL
(
unwind_stack
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment