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
Kirill Smelkov
linux
Commits
259d66a9
Commit
259d66a9
authored
Mar 03, 2003
by
David Mosberger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ia64; Improve debug output from kernel unwinder. Based on patch by
Keith Owens.
parent
9f319191
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
106 additions
and
65 deletions
+106
-65
arch/ia64/kernel/unwind.c
arch/ia64/kernel/unwind.c
+106
-65
No files found.
arch/ia64/kernel/unwind.c
View file @
259d66a9
...
@@ -51,18 +51,24 @@
...
@@ -51,18 +51,24 @@
#define UNW_LOG_HASH_SIZE (UNW_LOG_CACHE_SIZE + 1)
#define UNW_LOG_HASH_SIZE (UNW_LOG_CACHE_SIZE + 1)
#define UNW_HASH_SIZE (1 << UNW_LOG_HASH_SIZE)
#define UNW_HASH_SIZE (1 << UNW_LOG_HASH_SIZE)
#define UNW_DEBUG 0
#define UNW_STATS 0
/* WARNING: this disabled interrupts for long time-spans!! */
#define UNW_STATS 0
/* WARNING: this disabled interrupts for long time-spans!! */
#if UNW_DEBUG
#ifdef UNW_DEBUG
static
long
unw_debug_level
=
255
;
static
unsigned
int
unw_debug_level
=
UNW_DEBUG
;
# define debug(level,format...) if (unw_debug_level > level) printk(format)
# ifdef CONFIG_KDB
# define dprintk(format...) printk(format)
# include <linux/kdb.h>
# define UNW_DEBUG_ON(n) (unw_debug_level >= n && !KDB_IS_RUNNING())
# define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) kdb_printf(__VA_ARGS__)
# else
/* !CONFIG_KDB */
# define UNW_DEBUG_ON(n) unw_debug_level >= n
/* Do not code a printk level, not all debug lines end in newline */
# define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__)
# endif
/* CONFIG_KDB */
# define inline
# define inline
#else
#else
/* !UNW_DEBUG */
#
define debug(level,format...)
#
define UNW_DEBUG_ON(n) 0
#
define dprintk(format
...)
#
define UNW_DPRINT(n,
...)
#endif
#endif
/* UNW_DEBUG */
#if UNW_STATS
#if UNW_STATS
# define STAT(x...) x
# define STAT(x...) x
...
@@ -111,7 +117,7 @@ static struct {
...
@@ -111,7 +117,7 @@ static struct {
/* script cache: */
/* script cache: */
struct
unw_script
cache
[
UNW_CACHE_SIZE
];
struct
unw_script
cache
[
UNW_CACHE_SIZE
];
# if UNW_DEBUG
# if
def
UNW_DEBUG
const
char
*
preg_name
[
UNW_NUM_REGS
];
const
char
*
preg_name
[
UNW_NUM_REGS
];
# endif
# endif
# if UNW_STATS
# if UNW_STATS
...
@@ -190,7 +196,7 @@ static struct {
...
@@ -190,7 +196,7 @@ static struct {
struct_offset
(
struct
unw_frame_info
,
fr_loc
[
31
-
16
])
/
8
,
struct_offset
(
struct
unw_frame_info
,
fr_loc
[
31
-
16
])
/
8
,
},
},
.
hash
=
{
[
0
...
UNW_HASH_SIZE
-
1
]
=
-
1
},
.
hash
=
{
[
0
...
UNW_HASH_SIZE
-
1
]
=
-
1
},
#if UNW_DEBUG
#if
def
UNW_DEBUG
.
preg_name
=
{
.
preg_name
=
{
"pri_unat_gr"
,
"pri_unat_mem"
,
"bsp"
,
"bspstore"
,
"ar.pfs"
,
"ar.rnat"
,
"psp"
,
"rp"
,
"pri_unat_gr"
,
"pri_unat_mem"
,
"bsp"
,
"bspstore"
,
"ar.pfs"
,
"ar.rnat"
,
"psp"
,
"rp"
,
"r4"
,
"r5"
,
"r6"
,
"r7"
,
"r4"
,
"r5"
,
"r6"
,
"r7"
,
...
@@ -223,7 +229,7 @@ pt_regs_off (unsigned long reg)
...
@@ -223,7 +229,7 @@ pt_regs_off (unsigned long reg)
else
if
(
reg
<=
31
)
else
if
(
reg
<=
31
)
off
=
struct_offset
(
struct
pt_regs
,
r16
)
+
8
*
(
reg
-
16
);
off
=
struct_offset
(
struct
pt_regs
,
r16
)
+
8
*
(
reg
-
16
);
else
else
dprintk
(
"unwind: bad scratch reg r%lu
\n
"
,
reg
);
UNW_DPRINT
(
0
,
"unwind.%s: bad scratch reg r%lu
\n
"
,
__FUNCTION__
,
reg
);
return
off
;
return
off
;
}
}
...
@@ -232,9 +238,12 @@ dump_info_pt(struct unw_frame_info *info, const char *func)
...
@@ -232,9 +238,12 @@ dump_info_pt(struct unw_frame_info *info, const char *func)
{
{
/* WAR for no struct pt_regs, may be caused by bad unwind data. KAO */
/* WAR for no struct pt_regs, may be caused by bad unwind data. KAO */
if
(
!
info
->
pt
)
{
if
(
!
info
->
pt
)
{
dprintk
(
"unwind.%s: sp 0x%lx pt 0x%lx, set to 0x%lx
\n
"
,
func
,
info
->
sp
,
info
->
pt
,
info
->
sp
-
16
);
UNW_DPRINT
(
0
,
"unwind.%s: sp 0x%lx pt 0x%lx, set to 0x%lx
\n
"
,
func
,
info
->
sp
,
info
->
pt
,
info
->
sp
-
16
);
info
->
pt
=
info
->
sp
-
16
;
info
->
pt
=
info
->
sp
-
16
;
}
}
else
{
UNW_DPRINT
(
3
,
"unwind.%s: sp 0x%lx pt 0x%lx
\n
"
,
func
,
info
->
sp
,
info
->
pt
);
}
}
}
int
int
...
@@ -244,7 +253,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
...
@@ -244,7 +253,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
struct
unw_ireg
*
ireg
;
struct
unw_ireg
*
ireg
;
if
((
unsigned
)
regnum
-
1
>=
127
)
{
if
((
unsigned
)
regnum
-
1
>=
127
)
{
dprintk
(
"unwind: trying to access non-existent r%u
\n
"
,
regnum
);
UNW_DPRINT
(
0
,
"unwind.%s: trying to access non-existent r%u
\n
"
,
__FUNCTION__
,
regnum
);
return
-
1
;
return
-
1
;
}
}
...
@@ -289,8 +298,9 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
...
@@ -289,8 +298,9 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
if
((
unsigned
long
)
addr
<
info
->
regstk
.
limit
if
((
unsigned
long
)
addr
<
info
->
regstk
.
limit
||
(
unsigned
long
)
addr
>=
info
->
regstk
.
top
)
||
(
unsigned
long
)
addr
>=
info
->
regstk
.
top
)
{
{
dprintk
(
"unwind: %p outside of regstk "
UNW_DPRINT
(
0
,
"unwind.%s: %p outside of regstk "
"[0x%lx-0x%lx)
\n
"
,
(
void
*
)
addr
,
"[0x%lx-0x%lx)
\n
"
,
__FUNCTION__
,
(
void
*
)
addr
,
info
->
regstk
.
limit
,
info
->
regstk
.
limit
,
info
->
regstk
.
top
);
info
->
regstk
.
top
);
return
-
1
;
return
-
1
;
...
@@ -322,7 +332,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
...
@@ -322,7 +332,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
if
((
unsigned
long
)
addr
<
info
->
regstk
.
limit
if
((
unsigned
long
)
addr
<
info
->
regstk
.
limit
||
(
unsigned
long
)
addr
>=
info
->
regstk
.
top
)
||
(
unsigned
long
)
addr
>=
info
->
regstk
.
top
)
{
{
dprintk
(
"unwind: ignoring attempt to access register outside of rbs
\n
"
);
UNW_DPRINT
(
0
,
"unwind.%s: ignoring attempt to access register outside of rbs
\n
"
,
__FUNCTION__
);
return
-
1
;
return
-
1
;
}
}
if
((
unsigned
long
)
nat_addr
>=
info
->
regstk
.
top
)
if
((
unsigned
long
)
nat_addr
>=
info
->
regstk
.
top
)
...
@@ -370,7 +380,7 @@ unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int
...
@@ -370,7 +380,7 @@ unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int
break
;
break
;
default:
default:
dprintk
(
"unwind: trying to access non-existent b%u
\n
"
,
regnum
);
UNW_DPRINT
(
0
,
"unwind.%s: trying to access non-existent b%u
\n
"
,
__FUNCTION__
,
regnum
);
return
-
1
;
return
-
1
;
}
}
if
(
write
)
if
(
write
)
...
@@ -387,7 +397,7 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val,
...
@@ -387,7 +397,7 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val,
struct
pt_regs
*
pt
;
struct
pt_regs
*
pt
;
if
((
unsigned
)
(
regnum
-
2
)
>=
126
)
{
if
((
unsigned
)
(
regnum
-
2
)
>=
126
)
{
dprintk
(
"unwind: trying to access non-existent f%u
\n
"
,
regnum
);
UNW_DPRINT
(
0
,
"unwind.%s: trying to access non-existent f%u
\n
"
,
__FUNCTION__
,
regnum
);
return
-
1
;
return
-
1
;
}
}
...
@@ -495,7 +505,7 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int
...
@@ -495,7 +505,7 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int
break
;
break
;
default:
default:
dprintk
(
"unwind: trying to access non-existent ar%u
\n
"
,
regnum
);
UNW_DPRINT
(
0
,
"unwind.%s: trying to access non-existent ar%u
\n
"
,
__FUNCTION__
,
regnum
);
return
-
1
;
return
-
1
;
}
}
...
@@ -612,7 +622,7 @@ decode_abreg (unsigned char abreg, int memory)
...
@@ -612,7 +622,7 @@ decode_abreg (unsigned char abreg, int memory)
default:
default:
break
;
break
;
}
}
dprintk
(
"unwind: bad abreg=0x%x
\n
"
,
abreg
);
UNW_DPRINT
(
0
,
"unwind.%s: bad abreg=0x%x
\n
"
,
__FUNCTION__
,
abreg
);
return
UNW_REG_LC
;
return
UNW_REG_LC
;
}
}
...
@@ -652,7 +662,7 @@ spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim, unw_word
...
@@ -652,7 +662,7 @@ spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim, unw_word
return
;
return
;
}
}
}
}
dprintk
(
"unwind: excess spill!
\n
"
);
UNW_DPRINT
(
0
,
"unwind.%s: excess spill!
\n
"
,
__FUNCTION__
);
}
}
static
inline
void
static
inline
void
...
@@ -765,10 +775,13 @@ desc_prologue (int body, unw_word rlen, unsigned char mask, unsigned char grsave
...
@@ -765,10 +775,13 @@ desc_prologue (int body, unw_word rlen, unsigned char mask, unsigned char grsave
static
inline
void
static
inline
void
desc_abi
(
unsigned
char
abi
,
unsigned
char
context
,
struct
unw_state_record
*
sr
)
desc_abi
(
unsigned
char
abi
,
unsigned
char
context
,
struct
unw_state_record
*
sr
)
{
{
if
(
abi
==
0
&&
context
==
'i'
)
if
(
abi
==
0
&&
context
==
'i'
)
{
sr
->
flags
|=
UNW_FLAG_INTERRUPT_FRAME
;
sr
->
flags
|=
UNW_FLAG_INTERRUPT_FRAME
;
UNW_DPRINT
(
3
,
"unwind.%s: interrupt frame
\n
"
,
__FUNCTION__
);
}
else
else
dprintk
(
"unwind: ignoring unwabi(abi=0x%x,context=0x%x)
\n
"
,
abi
,
context
);
UNW_DPRINT
(
0
,
"unwind%s: ignoring unwabi(abi=0x%x,context=0x%x)
\n
"
,
__FUNCTION__
,
abi
,
context
);
}
}
static
inline
void
static
inline
void
...
@@ -1136,6 +1149,9 @@ script_lookup (struct unw_frame_info *info)
...
@@ -1136,6 +1149,9 @@ script_lookup (struct unw_frame_info *info)
unsigned
short
index
;
unsigned
short
index
;
unsigned
long
ip
,
pr
;
unsigned
long
ip
,
pr
;
if
(
UNW_DEBUG_ON
(
0
))
return
0
;
/* Always regenerate scripts in debug mode */
STAT
(
++
unw
.
stat
.
cache
.
lookups
);
STAT
(
++
unw
.
stat
.
cache
.
lookups
);
ip
=
info
->
ip
;
ip
=
info
->
ip
;
...
@@ -1260,8 +1276,8 @@ static inline void
...
@@ -1260,8 +1276,8 @@ static inline void
script_emit
(
struct
unw_script
*
script
,
struct
unw_insn
insn
)
script_emit
(
struct
unw_script
*
script
,
struct
unw_insn
insn
)
{
{
if
(
script
->
count
>=
UNW_MAX_SCRIPT_LEN
)
{
if
(
script
->
count
>=
UNW_MAX_SCRIPT_LEN
)
{
dprintk
(
"unwind
: script exceeds maximum size of %u instructions!
\n
"
,
UNW_DPRINT
(
0
,
"unwind.%s
: script exceeds maximum size of %u instructions!
\n
"
,
UNW_MAX_SCRIPT_LEN
);
__FUNCTION__
,
UNW_MAX_SCRIPT_LEN
);
return
;
return
;
}
}
script
->
insn
[
script
->
count
++
]
=
insn
;
script
->
insn
[
script
->
count
++
]
=
insn
;
...
@@ -1302,7 +1318,7 @@ emit_nat_info (struct unw_state_record *sr, int i, struct unw_script *script)
...
@@ -1302,7 +1318,7 @@ emit_nat_info (struct unw_state_record *sr, int i, struct unw_script *script)
break
;
break
;
default:
default:
dprintk
(
"unwind: don't know how to emit nat info for where = %u
\n
"
,
r
->
where
);
UNW_DPRINT
(
0
,
"unwind.%s: don't know how to emit nat info for where = %u
\n
"
,
__FUNCTION__
,
r
->
where
);
return
;
return
;
}
}
insn
.
opc
=
opc
;
insn
.
opc
=
opc
;
...
@@ -1355,7 +1371,7 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script)
...
@@ -1355,7 +1371,7 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script)
if
(
rval
<=
9
)
if
(
rval
<=
9
)
val
=
struct_offset
(
struct
pt_regs
,
f6
)
+
16
*
(
rval
-
6
);
val
=
struct_offset
(
struct
pt_regs
,
f6
)
+
16
*
(
rval
-
6
);
else
else
dprintk
(
"unwind: kernel may not touch f%lu
\n
"
,
rval
);
UNW_DPRINT
(
0
,
"unwind.%s: kernel may not touch f%lu
\n
"
,
__FUNCTION__
,
rval
);
}
}
break
;
break
;
...
@@ -1382,7 +1398,7 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script)
...
@@ -1382,7 +1398,7 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script)
break
;
break
;
default:
default:
dprintk
(
"unwind: register %u has unexpected `where' value of %u
\n
"
,
i
,
r
->
where
);
UNW_DPRINT
(
0
,
"unwind%s: register %u has unexpected `where' value of %u
\n
"
,
__FUNCTION__
,
i
,
r
->
where
);
break
;
break
;
}
}
insn
.
opc
=
opc
;
insn
.
opc
=
opc
;
...
@@ -1455,9 +1471,10 @@ build_script (struct unw_frame_info *info)
...
@@ -1455,9 +1471,10 @@ build_script (struct unw_frame_info *info)
r
->
when
=
UNW_WHEN_NEVER
;
r
->
when
=
UNW_WHEN_NEVER
;
sr
.
pr_val
=
info
->
pr
;
sr
.
pr_val
=
info
->
pr
;
UNW_DPRINT
(
3
,
"unwind.%s: ip 0x%lx
\n
"
,
__FUNCTION__
,
ip
);
script
=
script_new
(
ip
);
script
=
script_new
(
ip
);
if
(
!
script
)
{
if
(
!
script
)
{
dprintk
(
"unwind: failed to create unwind script
\n
"
);
UNW_DPRINT
(
0
,
"unwind.%s: failed to create unwind script
\n
"
,
__FUNCTION__
);
STAT
(
unw
.
stat
.
script
.
build_time
+=
ia64_get_itc
()
-
start
);
STAT
(
unw
.
stat
.
script
.
build_time
+=
ia64_get_itc
()
-
start
);
return
0
;
return
0
;
}
}
...
@@ -1475,8 +1492,8 @@ build_script (struct unw_frame_info *info)
...
@@ -1475,8 +1492,8 @@ build_script (struct unw_frame_info *info)
}
}
if
(
!
e
)
{
if
(
!
e
)
{
/* no info, return default unwinder (leaf proc, no mem stack, no saved regs) */
/* no info, return default unwinder (leaf proc, no mem stack, no saved regs) */
dprintk
(
"unwind: no unwind info for ip=0x%lx (prev ip=0x%lx)
\n
"
,
ip
,
UNW_DPRINT
(
1
,
"unwind.%s: no unwind info for ip=0x%lx (prev ip=0x%lx)
\n
"
,
unw
.
cache
[
info
->
prev_script
].
ip
);
__FUNCTION__
,
ip
,
unw
.
cache
[
info
->
prev_script
].
ip
);
sr
.
curr
.
reg
[
UNW_REG_RP
].
where
=
UNW_WHERE_BR
;
sr
.
curr
.
reg
[
UNW_REG_RP
].
where
=
UNW_WHERE_BR
;
sr
.
curr
.
reg
[
UNW_REG_RP
].
when
=
-
1
;
sr
.
curr
.
reg
[
UNW_REG_RP
].
when
=
-
1
;
sr
.
curr
.
reg
[
UNW_REG_RP
].
val
=
0
;
sr
.
curr
.
reg
[
UNW_REG_RP
].
val
=
0
;
...
@@ -1524,26 +1541,28 @@ build_script (struct unw_frame_info *info)
...
@@ -1524,26 +1541,28 @@ build_script (struct unw_frame_info *info)
sr
.
curr
.
reg
[
UNW_REG_RP
].
where
=
UNW_WHERE_BR
;
sr
.
curr
.
reg
[
UNW_REG_RP
].
where
=
UNW_WHERE_BR
;
sr
.
curr
.
reg
[
UNW_REG_RP
].
when
=
-
1
;
sr
.
curr
.
reg
[
UNW_REG_RP
].
when
=
-
1
;
sr
.
curr
.
reg
[
UNW_REG_RP
].
val
=
sr
.
return_link_reg
;
sr
.
curr
.
reg
[
UNW_REG_RP
].
val
=
sr
.
return_link_reg
;
UNW_DPRINT
(
1
,
"unwind.%s: using default for rp at ip=0x%lx where=%d val=0x%lx
\n
"
,
__FUNCTION__
,
ip
,
sr
.
curr
.
reg
[
UNW_REG_RP
].
where
,
sr
.
curr
.
reg
[
UNW_REG_RP
].
val
);
}
}
#if UNW_DEBUG
#if
def
UNW_DEBUG
printk
(
"unwind
: state record for func 0x%lx, t=%u:
\n
"
,
UNW_DPRINT
(
1
,
"unwind.%s
: state record for func 0x%lx, t=%u:
\n
"
,
table
->
segment_base
+
e
->
start_offset
,
sr
.
when_target
);
__FUNCTION__
,
table
->
segment_base
+
e
->
start_offset
,
sr
.
when_target
);
for
(
r
=
sr
.
curr
.
reg
;
r
<
sr
.
curr
.
reg
+
UNW_NUM_REGS
;
++
r
)
{
for
(
r
=
sr
.
curr
.
reg
;
r
<
sr
.
curr
.
reg
+
UNW_NUM_REGS
;
++
r
)
{
if
(
r
->
where
!=
UNW_WHERE_NONE
||
r
->
when
!=
UNW_WHEN_NEVER
)
{
if
(
r
->
where
!=
UNW_WHERE_NONE
||
r
->
when
!=
UNW_WHEN_NEVER
)
{
printk
(
" %s <- "
,
unw
.
preg_name
[
r
-
sr
.
curr
.
reg
]);
UNW_DPRINT
(
1
,
" %s <- "
,
unw
.
preg_name
[
r
-
sr
.
curr
.
reg
]);
switch
(
r
->
where
)
{
switch
(
r
->
where
)
{
case
UNW_WHERE_GR
:
printk
(
"r%lu"
,
r
->
val
);
break
;
case
UNW_WHERE_GR
:
UNW_DPRINT
(
1
,
"r%lu"
,
r
->
val
);
break
;
case
UNW_WHERE_FR
:
printk
(
"f%lu"
,
r
->
val
);
break
;
case
UNW_WHERE_FR
:
UNW_DPRINT
(
1
,
"f%lu"
,
r
->
val
);
break
;
case
UNW_WHERE_BR
:
printk
(
"b%lu"
,
r
->
val
);
break
;
case
UNW_WHERE_BR
:
UNW_DPRINT
(
1
,
"b%lu"
,
r
->
val
);
break
;
case
UNW_WHERE_SPREL
:
printk
(
"[sp+0x%lx]"
,
r
->
val
);
break
;
case
UNW_WHERE_SPREL
:
UNW_DPRINT
(
1
,
"[sp+0x%lx]"
,
r
->
val
);
break
;
case
UNW_WHERE_PSPREL
:
printk
(
"[psp+0x%lx]"
,
r
->
val
);
break
;
case
UNW_WHERE_PSPREL
:
UNW_DPRINT
(
1
,
"[psp+0x%lx]"
,
r
->
val
);
break
;
case
UNW_WHERE_NONE
:
case
UNW_WHERE_NONE
:
printk
(
"%s+0x%lx"
,
unw
.
preg_name
[
r
-
sr
.
curr
.
reg
],
r
->
val
);
UNW_DPRINT
(
1
,
"%s+0x%lx"
,
unw
.
preg_name
[
r
-
sr
.
curr
.
reg
],
r
->
val
);
break
;
break
;
default:
printk
(
"BADWHERE(%d)"
,
r
->
where
);
break
;
default:
UNW_DPRINT
(
1
,
"BADWHERE(%d)"
,
r
->
where
);
break
;
}
}
printk
(
"
\t\t
%d
\n
"
,
r
->
when
);
UNW_DPRINT
(
1
,
"
\t\t
%d
\n
"
,
r
->
when
);
}
}
}
}
#endif
#endif
...
@@ -1648,7 +1667,7 @@ run_script (struct unw_script *script, struct unw_frame_info *state)
...
@@ -1648,7 +1667,7 @@ run_script (struct unw_script *script, struct unw_frame_info *state)
}
}
else
{
else
{
s
[
dst
]
=
0
;
s
[
dst
]
=
0
;
dprintk
(
"unwind.%s: no state->pt, dst=%ld, val=%ld
\n
"
,
__FUNCTION__
,
dst
,
val
);
UNW_DPRINT
(
0
,
"unwind.%s: no state->pt, dst=%ld, val=%ld
\n
"
,
__FUNCTION__
,
dst
,
val
);
}
}
break
;
break
;
...
@@ -1677,11 +1696,11 @@ run_script (struct unw_script *script, struct unw_frame_info *state)
...
@@ -1677,11 +1696,11 @@ run_script (struct unw_script *script, struct unw_frame_info *state)
break
;
break
;
case
UNW_INSN_LOAD
:
case
UNW_INSN_LOAD
:
#if UNW_DEBUG
#if
def
UNW_DEBUG
if
((
s
[
val
]
&
(
local_cpu_data
->
unimpl_va_mask
|
0x7
))
!=
0
if
((
s
[
val
]
&
(
local_cpu_data
->
unimpl_va_mask
|
0x7
))
!=
0
||
s
[
val
]
<
TASK_SIZE
)
||
s
[
val
]
<
TASK_SIZE
)
{
{
debug
(
1
,
"unwind: rejecting bad psp=0x%lx
\n
"
,
s
[
val
]);
UNW_DPRINT
(
0
,
"unwind.%s: rejecting bad psp=0x%lx
\n
"
,
__FUNCTION__
,
s
[
val
]);
break
;
break
;
}
}
#endif
#endif
...
@@ -1714,7 +1733,8 @@ find_save_locs (struct unw_frame_info *info)
...
@@ -1714,7 +1733,8 @@ find_save_locs (struct unw_frame_info *info)
if
((
info
->
ip
&
(
local_cpu_data
->
unimpl_va_mask
|
0xf
))
||
info
->
ip
<
TASK_SIZE
)
{
if
((
info
->
ip
&
(
local_cpu_data
->
unimpl_va_mask
|
0xf
))
||
info
->
ip
<
TASK_SIZE
)
{
/* don't let obviously bad addresses pollute the cache */
/* don't let obviously bad addresses pollute the cache */
debug
(
1
,
"unwind: rejecting bad ip=0x%lx
\n
"
,
info
->
ip
);
/* FIXME: should really be level 0 but it occurs too often. KAO */
UNW_DPRINT
(
1
,
"unwind.%s: rejecting bad ip=0x%lx
\n
"
,
__FUNCTION__
,
info
->
ip
);
info
->
rp_loc
=
0
;
info
->
rp_loc
=
0
;
return
-
1
;
return
-
1
;
}
}
...
@@ -1723,8 +1743,8 @@ find_save_locs (struct unw_frame_info *info)
...
@@ -1723,8 +1743,8 @@ find_save_locs (struct unw_frame_info *info)
if
(
!
scr
)
{
if
(
!
scr
)
{
scr
=
build_script
(
info
);
scr
=
build_script
(
info
);
if
(
!
scr
)
{
if
(
!
scr
)
{
dprintk
(
"unwind
: failed to locate/build unwind script for ip %lx
\n
"
,
UNW_DPRINT
(
0
,
"unwind.%s
: failed to locate/build unwind script for ip %lx
\n
"
,
info
->
ip
);
__FUNCTION__
,
info
->
ip
);
return
-
1
;
return
-
1
;
}
}
have_write_lock
=
1
;
have_write_lock
=
1
;
...
@@ -1757,7 +1777,8 @@ unw_unwind (struct unw_frame_info *info)
...
@@ -1757,7 +1777,8 @@ unw_unwind (struct unw_frame_info *info)
/* restore the ip */
/* restore the ip */
if
(
!
info
->
rp_loc
)
{
if
(
!
info
->
rp_loc
)
{
debug
(
1
,
"unwind: failed to locate return link (ip=0x%lx)!
\n
"
,
info
->
ip
);
/* FIXME: should really be level 0 but it occurs too often. KAO */
UNW_DPRINT
(
1
,
"unwind.%s: failed to locate return link (ip=0x%lx)!
\n
"
,
__FUNCTION__
,
info
->
ip
);
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
return
-
1
;
return
-
1
;
}
}
...
@@ -1767,14 +1788,14 @@ unw_unwind (struct unw_frame_info *info)
...
@@ -1767,14 +1788,14 @@ unw_unwind (struct unw_frame_info *info)
* We don't have unwind info for the gate page, so we consider that part
* We don't have unwind info for the gate page, so we consider that part
* of user-space for the purpose of unwinding.
* of user-space for the purpose of unwinding.
*/
*/
debug
(
1
,
"unwind: reached user-space (ip=0x%lx)
\n
"
,
ip
);
UNW_DPRINT
(
2
,
"unwind.%s: reached user-space (ip=0x%lx)
\n
"
,
__FUNCTION__
,
ip
);
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
return
-
1
;
return
-
1
;
}
}
/* restore the cfm: */
/* restore the cfm: */
if
(
!
info
->
pfs_loc
)
{
if
(
!
info
->
pfs_loc
)
{
dprintk
(
"unwind: failed to locate ar.pfs!
\n
"
);
UNW_DPRINT
(
0
,
"unwind.%s: failed to locate ar.pfs!
\n
"
,
__FUNCTION__
);
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
return
-
1
;
return
-
1
;
}
}
...
@@ -1789,12 +1810,13 @@ unw_unwind (struct unw_frame_info *info)
...
@@ -1789,12 +1810,13 @@ unw_unwind (struct unw_frame_info *info)
num_regs
=
*
info
->
cfm_loc
&
0x7f
;
/* size of frame */
num_regs
=
*
info
->
cfm_loc
&
0x7f
;
/* size of frame */
info
->
pfs_loc
=
info
->
pfs_loc
=
(
unsigned
long
*
)
(
info
->
pt
+
struct_offset
(
struct
pt_regs
,
ar_pfs
));
(
unsigned
long
*
)
(
info
->
pt
+
struct_offset
(
struct
pt_regs
,
ar_pfs
));
UNW_DPRINT
(
3
,
"unwind.%s: interrupt_frame pt 0x%lx
\n
"
,
__FUNCTION__
,
info
->
pt
);
}
else
}
else
num_regs
=
(
*
info
->
cfm_loc
>>
7
)
&
0x7f
;
/* size of locals */
num_regs
=
(
*
info
->
cfm_loc
>>
7
)
&
0x7f
;
/* size of locals */
info
->
bsp
=
(
unsigned
long
)
ia64_rse_skip_regs
((
unsigned
long
*
)
info
->
bsp
,
-
num_regs
);
info
->
bsp
=
(
unsigned
long
)
ia64_rse_skip_regs
((
unsigned
long
*
)
info
->
bsp
,
-
num_regs
);
if
(
info
->
bsp
<
info
->
regstk
.
limit
||
info
->
bsp
>
info
->
regstk
.
top
)
{
if
(
info
->
bsp
<
info
->
regstk
.
limit
||
info
->
bsp
>
info
->
regstk
.
top
)
{
dprintk
(
"unwind
: bsp (0x%lx) out of range [0x%lx-0x%lx]
\n
"
,
UNW_DPRINT
(
0
,
"unwind.%s
: bsp (0x%lx) out of range [0x%lx-0x%lx]
\n
"
,
info
->
bsp
,
info
->
regstk
.
limit
,
info
->
regstk
.
top
);
__FUNCTION__
,
info
->
bsp
,
info
->
regstk
.
limit
,
info
->
regstk
.
top
);
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
return
-
1
;
return
-
1
;
}
}
...
@@ -1802,14 +1824,14 @@ unw_unwind (struct unw_frame_info *info)
...
@@ -1802,14 +1824,14 @@ unw_unwind (struct unw_frame_info *info)
/* restore the sp: */
/* restore the sp: */
info
->
sp
=
info
->
psp
;
info
->
sp
=
info
->
psp
;
if
(
info
->
sp
<
info
->
memstk
.
top
||
info
->
sp
>
info
->
memstk
.
limit
)
{
if
(
info
->
sp
<
info
->
memstk
.
top
||
info
->
sp
>
info
->
memstk
.
limit
)
{
dprintk
(
"unwind
: sp (0x%lx) out of range [0x%lx-0x%lx]
\n
"
,
UNW_DPRINT
(
0
,
"unwind.%s
: sp (0x%lx) out of range [0x%lx-0x%lx]
\n
"
,
info
->
sp
,
info
->
memstk
.
top
,
info
->
memstk
.
limit
);
__FUNCTION__
,
info
->
sp
,
info
->
memstk
.
top
,
info
->
memstk
.
limit
);
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
return
-
1
;
return
-
1
;
}
}
if
(
info
->
ip
==
prev_ip
&&
info
->
sp
==
prev_sp
&&
info
->
bsp
==
prev_bsp
)
{
if
(
info
->
ip
==
prev_ip
&&
info
->
sp
==
prev_sp
&&
info
->
bsp
==
prev_bsp
)
{
dprintk
(
"unwind: ip, sp, bsp remain unchanged; stopping here (ip=0x%lx)
\n
"
,
ip
);
UNW_DPRINT
(
0
,
"unwind.%s: ip, sp, bsp remain unchanged; stopping here (ip=0x%lx)
\n
"
,
__FUNCTION__
,
ip
);
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
STAT
(
unw
.
stat
.
api
.
unwind_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
return
-
1
;
return
-
1
;
}
}
...
@@ -1833,7 +1855,7 @@ unw_unwind_to_user (struct unw_frame_info *info)
...
@@ -1833,7 +1855,7 @@ unw_unwind_to_user (struct unw_frame_info *info)
while
(
unw_unwind
(
info
)
>=
0
)
{
while
(
unw_unwind
(
info
)
>=
0
)
{
if
(
unw_get_rp
(
info
,
&
ip
)
<
0
)
{
if
(
unw_get_rp
(
info
,
&
ip
)
<
0
)
{
unw_get_ip
(
info
,
&
ip
);
unw_get_ip
(
info
,
&
ip
);
dprintk
(
"unwind: failed to read return pointer (ip=0x%lx)
\n
"
,
ip
);
UNW_DPRINT
(
0
,
"unwind.%s: failed to read return pointer (ip=0x%lx)
\n
"
,
__FUNCTION__
,
ip
);
return
-
1
;
return
-
1
;
}
}
/*
/*
...
@@ -1844,7 +1866,7 @@ unw_unwind_to_user (struct unw_frame_info *info)
...
@@ -1844,7 +1866,7 @@ unw_unwind_to_user (struct unw_frame_info *info)
return
0
;
return
0
;
}
}
unw_get_ip
(
info
,
&
ip
);
unw_get_ip
(
info
,
&
ip
);
dprintk
(
"unwind: failed to unwind to user-level (ip=0x%lx)
\n
"
,
ip
);
UNW_DPRINT
(
0
,
"unwind.%s: failed to unwind to user-level (ip=0x%lx)
\n
"
,
__FUNCTION__
,
ip
);
return
-
1
;
return
-
1
;
}
}
...
@@ -1891,6 +1913,24 @@ unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct
...
@@ -1891,6 +1913,24 @@ unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct
info
->
bsp
=
(
unsigned
long
)
ia64_rse_skip_regs
((
unsigned
long
*
)
info
->
regstk
.
top
,
-
sol
);
info
->
bsp
=
(
unsigned
long
)
ia64_rse_skip_regs
((
unsigned
long
*
)
info
->
regstk
.
top
,
-
sol
);
info
->
ip
=
sw
->
b0
;
info
->
ip
=
sw
->
b0
;
info
->
pr
=
sw
->
pr
;
info
->
pr
=
sw
->
pr
;
UNW_DPRINT
(
3
,
"unwind.%s
\n
"
" rbslimit 0x%lx
\n
"
" rbstop 0x%lx
\n
"
" stklimit 0x%lx
\n
"
" stktop 0x%lx
\n
"
" task 0x%lx
\n
"
" sw 0x%lx
\n
"
,
__FUNCTION__
,
rbslimit
,
rbstop
,
stklimit
,
stktop
,
(
unsigned
long
)(
info
->
task
),
(
unsigned
long
)(
info
->
sw
));
UNW_DPRINT
(
3
,
" sp/psp 0x%lx
\n
"
" sol 0x%lx
\n
"
" bsp 0x%lx
\n
"
" ip 0x%lx
\n
"
" pr 0x%lx
\n
"
,
info
->
sp
,
sol
,
info
->
bsp
,
info
->
ip
,
info
->
pr
);
find_save_locs
(
info
);
find_save_locs
(
info
);
STAT
(
unw
.
stat
.
api
.
init_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
STAT
(
unw
.
stat
.
api
.
init_time
+=
ia64_get_itc
()
-
start
;
local_irq_restore
(
flags
));
...
@@ -1901,6 +1941,7 @@ unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t)
...
@@ -1901,6 +1941,7 @@ unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t)
{
{
struct
switch_stack
*
sw
=
(
struct
switch_stack
*
)
(
t
->
thread
.
ksp
+
16
);
struct
switch_stack
*
sw
=
(
struct
switch_stack
*
)
(
t
->
thread
.
ksp
+
16
);
UNW_DPRINT
(
1
,
"unwind.%s
\n
"
,
__FUNCTION__
);
unw_init_frame_info
(
info
,
t
,
sw
);
unw_init_frame_info
(
info
,
t
,
sw
);
}
}
...
@@ -1928,7 +1969,7 @@ unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned lon
...
@@ -1928,7 +1969,7 @@ unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned lon
unsigned
long
flags
;
unsigned
long
flags
;
if
(
end
-
start
<=
0
)
{
if
(
end
-
start
<=
0
)
{
dprintk
(
"unwind: ignoring attempt to insert empty unwind table
\n
"
);
UNW_DPRINT
(
0
,
"unwind.%s: ignoring attempt to insert empty unwind table
\n
"
,
__FUNCTION__
);
return
0
;
return
0
;
}
}
...
@@ -1958,13 +1999,13 @@ unw_remove_unwind_table (void *handle)
...
@@ -1958,13 +1999,13 @@ unw_remove_unwind_table (void *handle)
long
index
;
long
index
;
if
(
!
handle
)
{
if
(
!
handle
)
{
dprintk
(
"unwind: ignoring attempt to remove non-existent unwind table
\n
"
);
UNW_DPRINT
(
0
,
"unwind.%s: ignoring attempt to remove non-existent unwind table
\n
"
,
__FUNCTION__
);
return
;
return
;
}
}
table
=
handle
;
table
=
handle
;
if
(
table
==
&
unw
.
kernel_table
)
{
if
(
table
==
&
unw
.
kernel_table
)
{
dprintk
(
"unwind: sorry, freeing the kernel's unwind table is a no-can-do!
\n
"
);
UNW_DPRINT
(
0
,
"unwind.%s: sorry, freeing the kernel's unwind table is a no-can-do!
\n
"
,
__FUNCTION__
);
return
;
return
;
}
}
...
@@ -1976,7 +2017,7 @@ unw_remove_unwind_table (void *handle)
...
@@ -1976,7 +2017,7 @@ unw_remove_unwind_table (void *handle)
if
(
prev
->
next
==
table
)
if
(
prev
->
next
==
table
)
break
;
break
;
if
(
!
prev
)
{
if
(
!
prev
)
{
dprintk
(
"unwind: failed to find unwind table %p
\n
"
,
(
void
*
)
table
);
UNW_DPRINT
(
0
,
"unwind.%s: failed to find unwind table %p
\n
"
,
__FUNCTION__
,
(
void
*
)
table
);
spin_unlock_irqrestore
(
&
unw
.
lock
,
flags
);
spin_unlock_irqrestore
(
&
unw
.
lock
,
flags
);
return
;
return
;
}
}
...
...
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