Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
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