Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
e8f263df
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
e8f263df
编写于
1月 26, 2010
作者:
M
Mike Frysinger
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Blackfin: initial tracehook support
Signed-off-by:
N
Mike Frysinger
<
vapier@gentoo.org
>
上级
e50e2f25
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
144 addition
and
62 deletion
+144
-62
arch/blackfin/Kconfig
arch/blackfin/Kconfig
+1
-0
arch/blackfin/include/asm/ptrace.h
arch/blackfin/include/asm/ptrace.h
+23
-0
arch/blackfin/include/asm/syscall.h
arch/blackfin/include/asm/syscall.h
+96
-0
arch/blackfin/kernel/ptrace.c
arch/blackfin/kernel/ptrace.c
+17
-49
arch/blackfin/kernel/signal.c
arch/blackfin/kernel/signal.c
+3
-11
arch/blackfin/mach-common/entry.S
arch/blackfin/mach-common/entry.S
+4
-2
未找到文件。
arch/blackfin/Kconfig
浏览文件 @
e8f263df
...
...
@@ -24,6 +24,7 @@ config RWSEM_XCHGADD_ALGORITHM
config BLACKFIN
def_bool y
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
...
...
arch/blackfin/include/asm/ptrace.h
浏览文件 @
e8f263df
...
...
@@ -24,6 +24,8 @@
#ifndef __ASSEMBLY__
struct
task_struct
;
/* this struct defines the way the registers are stored on the
stack during a system call. */
...
...
@@ -101,9 +103,30 @@ struct pt_regs {
master interrupt enable. */
#define user_mode(regs) (!(((regs)->ipend & ~0x10) & (((regs)->ipend & ~0x10) - 1)))
#define instruction_pointer(regs) ((regs)->pc)
#define user_stack_pointer(regs) ((regs)->usp)
#define profile_pc(regs) instruction_pointer(regs)
extern
void
show_regs
(
struct
pt_regs
*
);
#define arch_has_single_step() (1)
extern
void
user_enable_single_step
(
struct
task_struct
*
child
);
extern
void
user_disable_single_step
(
struct
task_struct
*
child
);
/* common code demands this function */
#define ptrace_disable(child) user_disable_single_step(child)
/*
* Get the address of the live pt_regs for the specified task.
* These are saved onto the top kernel stack when the process
* is not running.
*
* Note: if a user thread is execve'd from kernel space, the
* kernel stack will not be empty on entry to the kernel, so
* ptracing these tasks will fail.
*/
#define task_pt_regs(task) \
(struct pt_regs *) \
((unsigned long)task_stack_page(task) + \
(THREAD_SIZE - sizeof(struct pt_regs)))
#endif
/* __KERNEL__ */
#endif
/* __ASSEMBLY__ */
...
...
arch/blackfin/include/asm/syscall.h
0 → 100644
浏览文件 @
e8f263df
/*
* Magic syscall break down functions
*
* Copyright 2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
#ifndef __ASM_BLACKFIN_SYSCALL_H__
#define __ASM_BLACKFIN_SYSCALL_H__
/*
* Blackfin syscalls are simple:
* enter:
* p0: syscall number
* r{0,1,2,3,4,5}: syscall args 0,1,2,3,4,5
* exit:
* r0: return/error value
*/
#include <linux/err.h>
#include <linux/sched.h>
#include <asm/ptrace.h>
static
inline
long
syscall_get_nr
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
)
{
return
regs
->
p0
;
}
static
inline
void
syscall_rollback
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
)
{
regs
->
p0
=
regs
->
orig_p0
;
}
static
inline
long
syscall_get_error
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
)
{
return
IS_ERR_VALUE
(
regs
->
r0
)
?
regs
->
r0
:
0
;
}
static
inline
long
syscall_get_return_value
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
)
{
return
regs
->
r0
;
}
static
inline
void
syscall_set_return_value
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
,
int
error
,
long
val
)
{
regs
->
r0
=
error
?
-
error
:
val
;
}
/**
* syscall_get_arguments()
* @task: unused
* @regs: the register layout to extract syscall arguments from
* @i: first syscall argument to extract
* @n: number of syscall arguments to extract
* @args: array to return the syscall arguments in
*
* args[0] gets i'th argument, args[n - 1] gets the i+n-1'th argument
*/
static
inline
void
syscall_get_arguments
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
,
unsigned
int
i
,
unsigned
int
n
,
unsigned
long
*
args
)
{
/*
* Assume the ptrace layout doesn't change -- r5 is first in memory,
* then r4, ..., then r0. So we simply reverse the ptrace register
* array in memory to store into the args array.
*/
long
*
aregs
=
&
regs
->
r0
-
i
;
BUG_ON
(
i
>
5
||
i
+
n
>
6
);
while
(
n
--
)
*
args
++
=
*
aregs
--
;
}
/* See syscall_get_arguments() comments */
static
inline
void
syscall_set_arguments
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
,
unsigned
int
i
,
unsigned
int
n
,
const
unsigned
long
*
args
)
{
long
*
aregs
=
&
regs
->
r0
-
i
;
BUG_ON
(
i
>
5
||
i
+
n
>
6
);
while
(
n
--
)
*
aregs
--
=
*
args
++
;
}
#endif
arch/blackfin/kernel/ptrace.c
浏览文件 @
e8f263df
/*
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
* these modifications are Copyright 2004-20
09
Analog Devices Inc.
* these modifications are Copyright 2004-20
10
Analog Devices Inc.
*
* Licensed under the GPL-2
*/
...
...
@@ -15,6 +15,7 @@
#include <linux/user.h>
#include <linux/regset.h>
#include <linux/signal.h>
#include <linux/tracehook.h>
#include <linux/uaccess.h>
#include <asm/page.h>
...
...
@@ -32,25 +33,6 @@
* in exit.c or in signal.c.
*/
/* Find the stack offset for a register, relative to thread.esp0. */
#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
/*
* Get the address of the live pt_regs for the specified task.
* These are saved onto the top kernel stack when the process
* is not running.
*
* Note: if a user thread is execve'd from kernel space, the
* kernel stack will not be empty on entry to the kernel, so
* ptracing these tasks will fail.
*/
static
inline
struct
pt_regs
*
task_pt_regs
(
struct
task_struct
*
task
)
{
return
(
struct
pt_regs
*
)
((
unsigned
long
)
task_stack_page
(
task
)
+
(
THREAD_SIZE
-
sizeof
(
struct
pt_regs
)));
}
/*
* Get contents of register REGNO in task TASK.
*/
...
...
@@ -234,18 +216,13 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
return
&
user_bfin_native_view
;
}
void
ptrace_enable
(
struct
task_struct
*
child
)
void
user_enable_single_step
(
struct
task_struct
*
child
)
{
struct
pt_regs
*
regs
=
task_pt_regs
(
child
);
regs
->
syscfg
|=
SYSCFG_SSSTEP
;
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure the single step bit is not set.
*/
void
ptrace_disable
(
struct
task_struct
*
child
)
void
user_disable_single_step
(
struct
task_struct
*
child
)
{
struct
pt_regs
*
regs
=
task_pt_regs
(
child
);
regs
->
syscfg
&=
~
SYSCFG_SSSTEP
;
...
...
@@ -412,27 +389,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return
ret
;
}
asmlinkage
void
syscall_trace
(
void
)
asmlinkage
int
syscall_trace_enter
(
struct
pt_regs
*
regs
)
{
if
(
!
test_thread_flag
(
TIF_SYSCALL_TRACE
))
return
;
if
(
!
(
current
->
ptrace
&
PT_PTRACED
))
return
;
/* the 0x80 provides a way for the tracing parent to distinguish
* between a syscall stop and SIGTRAP delivery
*/
ptrace_notify
(
SIGTRAP
|
((
current
->
ptrace
&
PT_TRACESYSGOOD
)
?
0x80
:
0
));
/*
* this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
* stopping signal is not SIGTRAP. -brl
*/
if
(
current
->
exit_code
)
{
send_sig
(
current
->
exit_code
,
current
,
1
);
current
->
exit_code
=
0
;
}
int
ret
=
0
;
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
))
ret
=
tracehook_report_syscall_entry
(
regs
);
return
ret
;
}
asmlinkage
void
syscall_trace_leave
(
struct
pt_regs
*
regs
)
{
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
))
tracehook_report_syscall_exit
(
regs
,
0
);
}
arch/blackfin/kernel/signal.c
浏览文件 @
e8f263df
/*
* Copyright 2004-20
09
Analog Devices Inc.
* Copyright 2004-20
10
Analog Devices Inc.
*
* Licensed under the GPL-2 or later
*/
...
...
@@ -206,16 +206,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
regs
->
r1
=
(
unsigned
long
)(
&
frame
->
info
);
regs
->
r2
=
(
unsigned
long
)(
&
frame
->
uc
);
/*
* Clear the trace flag when entering the signal handler, but
* notify any tracer that was single-stepping it. The tracer
* may want to single-step inside the handler too.
*/
if
(
regs
->
syscfg
&
TRACE_BITS
)
{
regs
->
syscfg
&=
~
TRACE_BITS
;
ptrace_notify
(
SIGTRAP
);
}
return
0
;
give_sigsegv:
...
...
@@ -315,6 +305,8 @@ asmlinkage void do_signal(struct pt_regs *regs)
* clear the TIF_RESTORE_SIGMASK flag */
if
(
test_thread_flag
(
TIF_RESTORE_SIGMASK
))
clear_thread_flag
(
TIF_RESTORE_SIGMASK
);
tracehook_signal_handler
(
signr
,
&
info
,
&
ka
,
regs
,
1
);
}
return
;
...
...
arch/blackfin/mach-common/entry.S
浏览文件 @
e8f263df
...
...
@@ -736,7 +736,8 @@ ENDPROC(_system_call)
*
this
symbol
need
not
be
global
anyways
,
so
...
*/
_sys_trace
:
pseudo_long_call
_syscall_trace
,
p5
;
r0
=
sp
;
pseudo_long_call
_syscall_trace_enter
,
p5
;
/
*
Execute
the
appropriate
system
call
*/
...
...
@@ -760,7 +761,8 @@ _sys_trace:
SP
+=
24
;
[
sp
+
PT_R0
]
=
r0
;
pseudo_long_call
_syscall_trace
,
p5
;
r0
=
sp
;
pseudo_long_call
_syscall_trace_leave
,
p5
;
jump
.
Lresume_userspace
;
ENDPROC
(
_sys_trace
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录