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
c9b85512
Commit
c9b85512
authored
May 10, 2004
by
David Mosberger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ia64: Add support to the kernel unwinder for the ".save rp, r0" idiom.
Based on patch by Keith Owens.
parent
69aeca90
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
55 additions
and
18 deletions
+55
-18
arch/ia64/kernel/head.S
arch/ia64/kernel/head.S
+2
-4
arch/ia64/kernel/unwind.c
arch/ia64/kernel/unwind.c
+52
-14
arch/ia64/kernel/unwind_i.h
arch/ia64/kernel/unwind_i.h
+1
-0
No files found.
arch/ia64/kernel/head.S
View file @
c9b85512
...
@@ -56,8 +56,7 @@ halt_msg:
...
@@ -56,8 +56,7 @@ halt_msg:
GLOBAL_ENTRY
(
_start
)
GLOBAL_ENTRY
(
_start
)
start_ap
:
start_ap
:
.
prologue
.
prologue
.
save
rp
,
r4
//
terminate
unwind
chain
with
a
NULL
rp
.
save
rp
,
r0
//
terminate
unwind
chain
with
a
NULL
rp
mov
r4
=
r0
.
body
.
body
rsm
psr
.
i
|
psr
.
ic
rsm
psr
.
i
|
psr
.
ic
...
@@ -818,8 +817,7 @@ END(ia64_delay_loop)
...
@@ -818,8 +817,7 @@ END(ia64_delay_loop)
GLOBAL_ENTRY
(
start_kernel_thread
)
GLOBAL_ENTRY
(
start_kernel_thread
)
.
prologue
.
prologue
.
save
rp
,
r4
//
this
is
the
end
of
the
call
-
chain
.
save
rp
,
r0
//
this
is
the
end
of
the
call
-
chain
mov
r4
=
r0
.
body
.
body
alloc
r2
=
ar
.
pfs
,
0
,
0
,
2
,
0
alloc
r2
=
ar
.
pfs
,
0
,
0
,
2
,
0
mov
out0
=
r9
mov
out0
=
r9
...
...
arch/ia64/kernel/unwind.c
View file @
c9b85512
...
@@ -89,6 +89,8 @@ static struct {
...
@@ -89,6 +89,8 @@ static struct {
/* list of unwind tables (one per load-module) */
/* list of unwind tables (one per load-module) */
struct
unw_table
*
tables
;
struct
unw_table
*
tables
;
unsigned
long
r0
;
/* constant 0 for r0 */
/* table of registers that prologues can save (and order in which they're saved): */
/* table of registers that prologues can save (and order in which they're saved): */
const
unsigned
char
save_order
[
8
];
const
unsigned
char
save_order
[
8
];
...
@@ -239,7 +241,11 @@ static struct {
...
@@ -239,7 +241,11 @@ static struct {
#endif
#endif
};
};
/* Unwind accessors. */
static
inline
int
read_only
(
unsigned
long
*
addr
)
{
return
(
addr
==
&
unw
.
r0
);
}
/*
/*
* Returns offset of rREG in struct pt_regs.
* Returns offset of rREG in struct pt_regs.
...
@@ -274,6 +280,8 @@ get_scratch_regs (struct unw_frame_info *info)
...
@@ -274,6 +280,8 @@ get_scratch_regs (struct unw_frame_info *info)
return
(
struct
pt_regs
*
)
info
->
pt
;
return
(
struct
pt_regs
*
)
info
->
pt
;
}
}
/* Unwind accessors. */
int
int
unw_access_gr
(
struct
unw_frame_info
*
info
,
int
regnum
,
unsigned
long
*
val
,
char
*
nat
,
int
write
)
unw_access_gr
(
struct
unw_frame_info
*
info
,
int
regnum
,
unsigned
long
*
val
,
char
*
nat
,
int
write
)
{
{
...
@@ -377,11 +385,15 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
...
@@ -377,11 +385,15 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
}
}
if
(
write
)
{
if
(
write
)
{
*
addr
=
*
val
;
if
(
read_only
(
addr
))
if
(
*
nat
)
UNW_DPRINT
(
0
,
"unwind.%s: ignoring attempt to write read-only location
\n
"
);
*
nat_addr
|=
nat_mask
;
else
{
else
*
addr
=
*
val
;
*
nat_addr
&=
~
nat_mask
;
if
(
*
nat
)
*
nat_addr
|=
nat_mask
;
else
*
nat_addr
&=
~
nat_mask
;
}
}
else
{
}
else
{
if
((
*
nat_addr
&
nat_mask
)
==
0
)
{
if
((
*
nat_addr
&
nat_mask
)
==
0
)
{
*
val
=
*
addr
;
*
val
=
*
addr
;
...
@@ -420,7 +432,10 @@ unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int
...
@@ -420,7 +432,10 @@ unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int
return
-
1
;
return
-
1
;
}
}
if
(
write
)
if
(
write
)
*
addr
=
*
val
;
if
(
read_only
(
addr
))
UNW_DPRINT
(
0
,
"unwind.%s: ignoring attempt to write read-only location
\n
"
);
else
*
addr
=
*
val
;
else
else
*
val
=
*
addr
;
*
val
=
*
addr
;
return
0
;
return
0
;
...
@@ -465,7 +480,10 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val,
...
@@ -465,7 +480,10 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val,
}
}
if
(
write
)
if
(
write
)
*
addr
=
*
val
;
if
(
read_only
(
addr
))
UNW_DPRINT
(
0
,
"unwind.%s: ignoring attempt to write read-only location
\n
"
);
else
*
addr
=
*
val
;
else
else
*
val
=
*
addr
;
*
val
=
*
addr
;
return
0
;
return
0
;
...
@@ -557,9 +575,12 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int
...
@@ -557,9 +575,12 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int
return
-
1
;
return
-
1
;
}
}
if
(
write
)
if
(
write
)
{
*
addr
=
*
val
;
if
(
read_only
(
addr
))
else
UNW_DPRINT
(
0
,
"unwind.%s: ignoring attempt to write read-only location
\n
"
);
else
*
addr
=
*
val
;
}
else
*
val
=
*
addr
;
*
val
=
*
addr
;
return
0
;
return
0
;
}
}
...
@@ -574,9 +595,12 @@ unw_access_pr (struct unw_frame_info *info, unsigned long *val, int write)
...
@@ -574,9 +595,12 @@ unw_access_pr (struct unw_frame_info *info, unsigned long *val, int write)
if
(
!
addr
)
if
(
!
addr
)
addr
=
&
info
->
sw
->
pr
;
addr
=
&
info
->
sw
->
pr
;
if
(
write
)
if
(
write
)
{
*
addr
=
*
val
;
if
(
read_only
(
addr
))
else
UNW_DPRINT
(
0
,
"unwind.%s: ignoring attempt to write read-only location
\n
"
);
else
*
addr
=
*
val
;
}
else
*
val
=
*
addr
;
*
val
=
*
addr
;
return
0
;
return
0
;
}
}
...
@@ -1407,6 +1431,9 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script)
...
@@ -1407,6 +1431,9 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script)
need_nat_info
=
0
;
need_nat_info
=
0
;
}
}
val
=
unw
.
preg_index
[
UNW_REG_R4
+
(
rval
-
4
)];
val
=
unw
.
preg_index
[
UNW_REG_R4
+
(
rval
-
4
)];
}
else
if
(
rval
==
0
)
{
opc
=
UNW_INSN_MOVE_CONST
;
val
=
0
;
}
else
{
}
else
{
/* register got spilled to a scratch register */
/* register got spilled to a scratch register */
opc
=
UNW_INSN_MOVE_SCRATCH
;
opc
=
UNW_INSN_MOVE_SCRATCH
;
...
@@ -1729,6 +1756,17 @@ run_script (struct unw_script *script, struct unw_frame_info *state)
...
@@ -1729,6 +1756,17 @@ run_script (struct unw_script *script, struct unw_frame_info *state)
}
}
break
;
break
;
case
UNW_INSN_MOVE_CONST
:
if
(
val
==
0
)
s
[
dst
]
=
(
unsigned
long
)
&
unw
.
r0
;
else
{
s
[
dst
]
=
0
;
UNW_DPRINT
(
0
,
"unwind.%s: UNW_INSN_MOVE_CONST bad val=%ld
\n
"
,
__FUNCTION__
,
val
);
}
break
;
case
UNW_INSN_MOVE_STACKED
:
case
UNW_INSN_MOVE_STACKED
:
s
[
dst
]
=
(
unsigned
long
)
ia64_rse_skip_regs
((
unsigned
long
*
)
state
->
bsp
,
s
[
dst
]
=
(
unsigned
long
)
ia64_rse_skip_regs
((
unsigned
long
*
)
state
->
bsp
,
val
);
val
);
...
...
arch/ia64/kernel/unwind_i.h
View file @
c9b85512
...
@@ -133,6 +133,7 @@ enum unw_insn_opcode {
...
@@ -133,6 +133,7 @@ enum unw_insn_opcode {
UNW_INSN_SETNAT_TYPE
,
/* s[dst+1].nat.type = val */
UNW_INSN_SETNAT_TYPE
,
/* s[dst+1].nat.type = val */
UNW_INSN_LOAD
,
/* s[dst] = *s[val] */
UNW_INSN_LOAD
,
/* s[dst] = *s[val] */
UNW_INSN_MOVE_SCRATCH
,
/* s[dst] = scratch reg "val" */
UNW_INSN_MOVE_SCRATCH
,
/* s[dst] = scratch reg "val" */
UNW_INSN_MOVE_CONST
,
/* s[dst] = constant reg "val" */
};
};
struct
unw_insn
{
struct
unw_insn
{
...
...
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