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
718dbf37
Commit
718dbf37
authored
Aug 14, 2009
by
Paul Mundt
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'sh/dwarf-unwinder'
parents
f54aab4a
f8264667
Changes
13
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1363 additions
and
1 deletion
+1363
-1
arch/sh/Kconfig.debug
arch/sh/Kconfig.debug
+8
-0
arch/sh/Makefile
arch/sh/Makefile
+4
-0
arch/sh/include/asm/dwarf.h
arch/sh/include/asm/dwarf.h
+402
-0
arch/sh/include/asm/entry-macros.S
arch/sh/include/asm/entry-macros.S
+12
-0
arch/sh/include/asm/sections.h
arch/sh/include/asm/sections.h
+1
-0
arch/sh/include/asm/vmlinux.lds.h
arch/sh/include/asm/vmlinux.lds.h
+17
-0
arch/sh/kernel/Makefile_32
arch/sh/kernel/Makefile_32
+1
-0
arch/sh/kernel/Makefile_64
arch/sh/kernel/Makefile_64
+1
-0
arch/sh/kernel/cpu/sh3/entry.S
arch/sh/kernel/cpu/sh3/entry.S
+1
-0
arch/sh/kernel/dwarf.c
arch/sh/kernel/dwarf.c
+901
-0
arch/sh/kernel/entry-common.S
arch/sh/kernel/entry-common.S
+8
-0
arch/sh/kernel/irq.c
arch/sh/kernel/irq.c
+4
-0
arch/sh/kernel/vmlinux.lds.S
arch/sh/kernel/vmlinux.lds.S
+3
-1
No files found.
arch/sh/Kconfig.debug
View file @
718dbf37
...
...
@@ -110,6 +110,14 @@ config DUMP_CODE
Those looking for more verbose debugging output should say Y.
config DWARF_UNWINDER
bool "Enable the DWARF unwinder for stacktraces"
select FRAME_POINTER
default n
help
Enabling this option will make stacktraces more accurate, at
the cost of an increase in overall kernel size.
config SH_NO_BSS_INIT
bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)"
depends on DEBUG_KERNEL
...
...
arch/sh/Makefile
View file @
718dbf37
...
...
@@ -191,6 +191,10 @@ ifeq ($(CONFIG_MCOUNT),y)
KBUILD_CFLAGS
+=
-pg
endif
ifeq
($(CONFIG_DWARF_UNWINDER),y)
KBUILD_CFLAGS
+=
-fasynchronous-unwind-tables
endif
libs-$(CONFIG_SUPERH32)
:=
arch
/sh/lib/
$
(
libs-y
)
libs-$(CONFIG_SUPERH64)
:=
arch
/sh/lib64/
$
(
libs-y
)
...
...
arch/sh/include/asm/dwarf.h
0 → 100644
View file @
718dbf37
/*
* Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
*
* 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.
*
*/
#ifndef __ASM_SH_DWARF_H
#define __ASM_SH_DWARF_H
#ifdef CONFIG_DWARF_UNWINDER
/*
* DWARF expression operations
*/
#define DW_OP_addr 0x03
#define DW_OP_deref 0x06
#define DW_OP_const1u 0x08
#define DW_OP_const1s 0x09
#define DW_OP_const2u 0x0a
#define DW_OP_const2s 0x0b
#define DW_OP_const4u 0x0c
#define DW_OP_const4s 0x0d
#define DW_OP_const8u 0x0e
#define DW_OP_const8s 0x0f
#define DW_OP_constu 0x10
#define DW_OP_consts 0x11
#define DW_OP_dup 0x12
#define DW_OP_drop 0x13
#define DW_OP_over 0x14
#define DW_OP_pick 0x15
#define DW_OP_swap 0x16
#define DW_OP_rot 0x17
#define DW_OP_xderef 0x18
#define DW_OP_abs 0x19
#define DW_OP_and 0x1a
#define DW_OP_div 0x1b
#define DW_OP_minus 0x1c
#define DW_OP_mod 0x1d
#define DW_OP_mul 0x1e
#define DW_OP_neg 0x1f
#define DW_OP_not 0x20
#define DW_OP_or 0x21
#define DW_OP_plus 0x22
#define DW_OP_plus_uconst 0x23
#define DW_OP_shl 0x24
#define DW_OP_shr 0x25
#define DW_OP_shra 0x26
#define DW_OP_xor 0x27
#define DW_OP_skip 0x2f
#define DW_OP_bra 0x28
#define DW_OP_eq 0x29
#define DW_OP_ge 0x2a
#define DW_OP_gt 0x2b
#define DW_OP_le 0x2c
#define DW_OP_lt 0x2d
#define DW_OP_ne 0x2e
#define DW_OP_lit0 0x30
#define DW_OP_lit1 0x31
#define DW_OP_lit2 0x32
#define DW_OP_lit3 0x33
#define DW_OP_lit4 0x34
#define DW_OP_lit5 0x35
#define DW_OP_lit6 0x36
#define DW_OP_lit7 0x37
#define DW_OP_lit8 0x38
#define DW_OP_lit9 0x39
#define DW_OP_lit10 0x3a
#define DW_OP_lit11 0x3b
#define DW_OP_lit12 0x3c
#define DW_OP_lit13 0x3d
#define DW_OP_lit14 0x3e
#define DW_OP_lit15 0x3f
#define DW_OP_lit16 0x40
#define DW_OP_lit17 0x41
#define DW_OP_lit18 0x42
#define DW_OP_lit19 0x43
#define DW_OP_lit20 0x44
#define DW_OP_lit21 0x45
#define DW_OP_lit22 0x46
#define DW_OP_lit23 0x47
#define DW_OP_lit24 0x48
#define DW_OP_lit25 0x49
#define DW_OP_lit26 0x4a
#define DW_OP_lit27 0x4b
#define DW_OP_lit28 0x4c
#define DW_OP_lit29 0x4d
#define DW_OP_lit30 0x4e
#define DW_OP_lit31 0x4f
#define DW_OP_reg0 0x50
#define DW_OP_reg1 0x51
#define DW_OP_reg2 0x52
#define DW_OP_reg3 0x53
#define DW_OP_reg4 0x54
#define DW_OP_reg5 0x55
#define DW_OP_reg6 0x56
#define DW_OP_reg7 0x57
#define DW_OP_reg8 0x58
#define DW_OP_reg9 0x59
#define DW_OP_reg10 0x5a
#define DW_OP_reg11 0x5b
#define DW_OP_reg12 0x5c
#define DW_OP_reg13 0x5d
#define DW_OP_reg14 0x5e
#define DW_OP_reg15 0x5f
#define DW_OP_reg16 0x60
#define DW_OP_reg17 0x61
#define DW_OP_reg18 0x62
#define DW_OP_reg19 0x63
#define DW_OP_reg20 0x64
#define DW_OP_reg21 0x65
#define DW_OP_reg22 0x66
#define DW_OP_reg23 0x67
#define DW_OP_reg24 0x68
#define DW_OP_reg25 0x69
#define DW_OP_reg26 0x6a
#define DW_OP_reg27 0x6b
#define DW_OP_reg28 0x6c
#define DW_OP_reg29 0x6d
#define DW_OP_reg30 0x6e
#define DW_OP_reg31 0x6f
#define DW_OP_breg0 0x70
#define DW_OP_breg1 0x71
#define DW_OP_breg2 0x72
#define DW_OP_breg3 0x73
#define DW_OP_breg4 0x74
#define DW_OP_breg5 0x75
#define DW_OP_breg6 0x76
#define DW_OP_breg7 0x77
#define DW_OP_breg8 0x78
#define DW_OP_breg9 0x79
#define DW_OP_breg10 0x7a
#define DW_OP_breg11 0x7b
#define DW_OP_breg12 0x7c
#define DW_OP_breg13 0x7d
#define DW_OP_breg14 0x7e
#define DW_OP_breg15 0x7f
#define DW_OP_breg16 0x80
#define DW_OP_breg17 0x81
#define DW_OP_breg18 0x82
#define DW_OP_breg19 0x83
#define DW_OP_breg20 0x84
#define DW_OP_breg21 0x85
#define DW_OP_breg22 0x86
#define DW_OP_breg23 0x87
#define DW_OP_breg24 0x88
#define DW_OP_breg25 0x89
#define DW_OP_breg26 0x8a
#define DW_OP_breg27 0x8b
#define DW_OP_breg28 0x8c
#define DW_OP_breg29 0x8d
#define DW_OP_breg30 0x8e
#define DW_OP_breg31 0x8f
#define DW_OP_regx 0x90
#define DW_OP_fbreg 0x91
#define DW_OP_bregx 0x92
#define DW_OP_piece 0x93
#define DW_OP_deref_size 0x94
#define DW_OP_xderef_size 0x95
#define DW_OP_nop 0x96
#define DW_OP_push_object_address 0x97
#define DW_OP_call2 0x98
#define DW_OP_call4 0x99
#define DW_OP_call_ref 0x9a
#define DW_OP_form_tls_address 0x9b
#define DW_OP_call_frame_cfa 0x9c
#define DW_OP_bit_piece 0x9d
#define DW_OP_lo_user 0xe0
#define DW_OP_hi_user 0xff
/*
* Addresses used in FDE entries in the .eh_frame section may be encoded
* using one of the following encodings.
*/
#define DW_EH_PE_absptr 0x00
#define DW_EH_PE_omit 0xff
#define DW_EH_PE_uleb128 0x01
#define DW_EH_PE_udata2 0x02
#define DW_EH_PE_udata4 0x03
#define DW_EH_PE_udata8 0x04
#define DW_EH_PE_sleb128 0x09
#define DW_EH_PE_sdata2 0x0a
#define DW_EH_PE_sdata4 0x0b
#define DW_EH_PE_sdata8 0x0c
#define DW_EH_PE_signed 0x09
#define DW_EH_PE_pcrel 0x10
/*
* The architecture-specific register number that contains the return
* address in the .debug_frame table.
*/
#define DWARF_ARCH_RA_REG 17
#ifndef __ASSEMBLY__
/*
* Read either the frame pointer (r14) or the stack pointer (r15).
* NOTE: this MUST be inlined.
*/
static
__always_inline
unsigned
long
dwarf_read_arch_reg
(
unsigned
int
reg
)
{
unsigned
long
value
;
switch
(
reg
)
{
case
14
:
__asm__
__volatile__
(
"mov r14, %0
\n
"
:
"=r"
(
value
));
break
;
case
15
:
__asm__
__volatile__
(
"mov r15, %0
\n
"
:
"=r"
(
value
));
break
;
default:
BUG
();
}
return
value
;
}
/**
* dwarf_cie - Common Information Entry
*/
struct
dwarf_cie
{
unsigned
long
length
;
unsigned
long
cie_id
;
unsigned
char
version
;
const
char
*
augmentation
;
unsigned
int
code_alignment_factor
;
int
data_alignment_factor
;
/* Which column in the rule table represents return addr of func. */
unsigned
int
return_address_reg
;
unsigned
char
*
initial_instructions
;
unsigned
char
*
instructions_end
;
unsigned
char
encoding
;
unsigned
long
cie_pointer
;
struct
list_head
link
;
unsigned
long
flags
;
#define DWARF_CIE_Z_AUGMENTATION (1 << 0)
};
/**
* dwarf_fde - Frame Description Entry
*/
struct
dwarf_fde
{
unsigned
long
length
;
unsigned
long
cie_pointer
;
struct
dwarf_cie
*
cie
;
unsigned
long
initial_location
;
unsigned
long
address_range
;
unsigned
char
*
instructions
;
unsigned
char
*
end
;
struct
list_head
link
;
};
/**
* dwarf_frame - DWARF information for a frame in the call stack
*/
struct
dwarf_frame
{
struct
dwarf_frame
*
prev
,
*
next
;
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? */
unsigned
long
cfa
;
/* Valid when DW_FRAME_CFA_REG_OFFSET is set in flags */
unsigned
int
cfa_register
;
unsigned
int
cfa_offset
;
/* Valid when DW_FRAME_CFA_REG_EXP is set in flags */
unsigned
char
*
cfa_expr
;
unsigned
int
cfa_expr_len
;
unsigned
long
flags
;
#define DWARF_FRAME_CFA_REG_OFFSET (1 << 0)
#define DWARF_FRAME_CFA_REG_EXP (1 << 1)
unsigned
long
return_addr
;
};
/**
* dwarf_reg - DWARF register
* @flags: Describes how to calculate the value of this register
*/
struct
dwarf_reg
{
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
;
};
/*
* Call Frame instruction opcodes.
*/
#define DW_CFA_advance_loc 0x40
#define DW_CFA_offset 0x80
#define DW_CFA_restore 0xc0
#define DW_CFA_nop 0x00
#define DW_CFA_set_loc 0x01
#define DW_CFA_advance_loc1 0x02
#define DW_CFA_advance_loc2 0x03
#define DW_CFA_advance_loc4 0x04
#define DW_CFA_offset_extended 0x05
#define DW_CFA_restore_extended 0x06
#define DW_CFA_undefined 0x07
#define DW_CFA_same_value 0x08
#define DW_CFA_register 0x09
#define DW_CFA_remember_state 0x0a
#define DW_CFA_restore_state 0x0b
#define DW_CFA_def_cfa 0x0c
#define DW_CFA_def_cfa_register 0x0d
#define DW_CFA_def_cfa_offset 0x0e
#define DW_CFA_def_cfa_expression 0x0f
#define DW_CFA_expression 0x10
#define DW_CFA_offset_extended_sf 0x11
#define DW_CFA_def_cfa_sf 0x12
#define DW_CFA_def_cfa_offset_sf 0x13
#define DW_CFA_val_offset 0x14
#define DW_CFA_val_offset_sf 0x15
#define DW_CFA_val_expression 0x16
#define DW_CFA_lo_user 0x1c
#define DW_CFA_hi_user 0x3f
/*
* Some call frame instructions encode their operands in the opcode. We
* need some helper functions to extract both the opcode and operands
* from an instruction.
*/
static
inline
unsigned
int
DW_CFA_opcode
(
unsigned
long
insn
)
{
return
(
insn
&
0xc0
);
}
static
inline
unsigned
int
DW_CFA_operand
(
unsigned
long
insn
)
{
return
(
insn
&
0x3f
);
}
#define DW_EH_FRAME_CIE 0
/* .eh_frame CIE IDs are 0 */
#define DW_CIE_ID 0xffffffff
#define DW64_CIE_ID 0xffffffffffffffffULL
/*
* DWARF FDE/CIE length field values.
*/
#define DW_EXT_LO 0xfffffff0
#define DW_EXT_HI 0xffffffff
#define DW_EXT_DWARF64 DW_EXT_HI
extern
void
dwarf_unwinder_init
(
void
);
extern
struct
dwarf_frame
*
dwarf_unwind_stack
(
unsigned
long
,
struct
dwarf_frame
*
);
#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
#else
/*
* Use the asm comment character to ignore the rest of the line.
*/
#define CFI_IGNORE !
#define CFI_STARTPROC CFI_IGNORE
#define CFI_ENDPROC CFI_IGNORE
#define CFI_DEF_CFA CFI_IGNORE
#define CFI_REGISTER CFI_IGNORE
#define CFI_REL_OFFSET CFI_IGNORE
#ifndef __ASSEMBLY__
static
inline
void
dwarf_unwinder_init
(
void
)
{
}
#endif
#endif
/* CONFIG_DWARF_UNWINDER */
#endif
/* __ASM_SH_DWARF_H */
arch/sh/include/asm/entry-macros.S
View file @
718dbf37
...
...
@@ -108,3 +108,15 @@
#else
# define PREF(x) nop
#endif
/
*
*
Macro
for
use
within
assembly
.
Because
the
DWARF
unwinder
*
needs
to
use
the
frame
register
to
unwind
the
stack
,
we
*
need
to
setup
r14
with
the
value
of
the
stack
pointer
as
*
the
return
address
is
usually
on
the
stack
somewhere
.
*/
.
macro
setup_frame_reg
#ifdef CONFIG_DWARF_UNWINDER
mov
r15
,
r14
#endif
.
endm
arch/sh/include/asm/sections.h
View file @
718dbf37
...
...
@@ -7,6 +7,7 @@ extern void __nosave_begin, __nosave_end;
extern
long
__machvec_start
,
__machvec_end
;
extern
char
__uncached_start
,
__uncached_end
;
extern
char
_ebss
[];
extern
char
__start_eh_frame
[],
__stop_eh_frame
[];
#endif
/* __ASM_SH_SECTIONS_H */
arch/sh/include/asm/vmlinux.lds.h
0 → 100644
View file @
718dbf37
#ifndef __ASM_SH_VMLINUX_LDS_H
#define __ASM_SH_VMLINUX_LDS_H
#include <asm-generic/vmlinux.lds.h>
#ifdef CONFIG_DWARF_UNWINDER
#define DWARF_EH_FRAME \
.eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start_eh_frame) = .; \
*(.eh_frame) \
VMLINUX_SYMBOL(__stop_eh_frame) = .; \
}
#else
#define DWARF_EH_FRAME
#endif
#endif
/* __ASM_SH_VMLINUX_LDS_H */
arch/sh/kernel/Makefile_32
View file @
718dbf37
...
...
@@ -33,6 +33,7 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
obj-$(CONFIG_DUMP_CODE) += disassemble.o
obj-$(CONFIG_HIBERNATION) += swsusp.o
obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
...
...
arch/sh/kernel/Makefile_64
View file @
718dbf37
...
...
@@ -13,6 +13,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
...
...
arch/sh/kernel/cpu/sh3/entry.S
View file @
718dbf37
...
...
@@ -137,6 +137,7 @@ ENTRY(tlb_protection_violation_store)
mov
#
1
,
r5
call_dpf
:
setup_frame_reg
mov.l
1
f
,
r0
mov
r5
,
r8
mov.l
@
r0
,
r6
...
...
arch/sh/kernel/dwarf.c
0 → 100644
View file @
718dbf37
This diff is collapsed.
Click to expand it.
arch/sh/kernel/entry-common.S
View file @
718dbf37
...
...
@@ -43,6 +43,7 @@
*
syscall
#
*
*/
#include <asm/dwarf.h>
#if defined(CONFIG_PREEMPT)
# define preempt_stop() cli ; TRACE_IRQS_OFF
...
...
@@ -66,6 +67,11 @@ ENTRY(exception_error)
.
align
2
ret_from_exception
:
CFI_STARTPROC
simple
CFI_DEF_CFA
r14
,
0
CFI_REL_OFFSET
17
,
64
CFI_REL_OFFSET
15
,
0
CFI_REL_OFFSET
14
,
56
preempt_stop
()
ENTRY
(
ret_from_irq
)
!
...
...
@@ -240,6 +246,7 @@ debug_trap:
nop
bra
__restore_all
nop
CFI_ENDPROC
.
align
2
1
:
.
long
debug_trap_table
...
...
@@ -285,6 +292,7 @@ ret_from_fork:
*
system
calls
and
debug
traps
through
their
respective
jump
tables
.
*/
ENTRY
(
system_call
)
setup_frame_reg
#if !defined(CONFIG_CPU_SH2)
mov.l
1
f
,
r9
mov.l
@
r9
,
r8
!
Read
from
TRA
(
Trap
Address
)
Register
...
...
arch/sh/kernel/irq.c
View file @
718dbf37
...
...
@@ -14,6 +14,7 @@
#include <asm/processor.h>
#include <asm/machvec.h>
#include <asm/uaccess.h>
#include <asm/dwarf.h>
#include <asm/thread_info.h>
#include <cpu/mmu_context.h>
...
...
@@ -261,6 +262,9 @@ void __init init_IRQ(void)
sh_mv
.
mv_init_irq
();
irq_ctx_init
(
smp_processor_id
());
/* This needs to be early, but not too early.. */
dwarf_unwinder_init
();
}
#ifdef CONFIG_SPARSE_IRQ
...
...
arch/sh/kernel/vmlinux.lds.S
View file @
718dbf37
...
...
@@ -12,7 +12,7 @@ OUTPUT_ARCH(sh)
#include <asm/thread_info.h>
#include <asm/cache.h>
#include <asm
-generic
/vmlinux.lds.h>
#include <asm/vmlinux.lds.h>
ENTRY
(
_start
)
SECTIONS
...
...
@@ -70,6 +70,8 @@ SECTIONS
_edata
=
.
; /* End of data section */
DWARF_EH_FRAME
.
=
ALIGN
(
PAGE_SIZE
)
; /* Init code and data */
__init_begin
=
.
;
INIT_TEXT_SECTION
(
PAGE_SIZE
)
...
...
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