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
e8f263df
Commit
e8f263df
authored
Jan 26, 2010
by
Mike Frysinger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Blackfin: initial tracehook support
Signed-off-by:
Mike Frysinger
<
vapier@gentoo.org
>
parent
e50e2f25
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
144 additions
and
62 deletions
+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
No files found.
arch/blackfin/Kconfig
View file @
e8f263df
...
@@ -24,6 +24,7 @@ config RWSEM_XCHGADD_ALGORITHM
...
@@ -24,6 +24,7 @@ config RWSEM_XCHGADD_ALGORITHM
config BLACKFIN
config BLACKFIN
def_bool y
def_bool y
select HAVE_ARCH_KGDB
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
...
...
arch/blackfin/include/asm/ptrace.h
View file @
e8f263df
...
@@ -24,6 +24,8 @@
...
@@ -24,6 +24,8 @@
#ifndef __ASSEMBLY__
#ifndef __ASSEMBLY__
struct
task_struct
;
/* this struct defines the way the registers are stored on the
/* this struct defines the way the registers are stored on the
stack during a system call. */
stack during a system call. */
...
@@ -101,9 +103,30 @@ struct pt_regs {
...
@@ -101,9 +103,30 @@ struct pt_regs {
master interrupt enable. */
master interrupt enable. */
#define user_mode(regs) (!(((regs)->ipend & ~0x10) & (((regs)->ipend & ~0x10) - 1)))
#define user_mode(regs) (!(((regs)->ipend & ~0x10) & (((regs)->ipend & ~0x10) - 1)))
#define instruction_pointer(regs) ((regs)->pc)
#define instruction_pointer(regs) ((regs)->pc)
#define user_stack_pointer(regs) ((regs)->usp)
#define profile_pc(regs) instruction_pointer(regs)
#define profile_pc(regs) instruction_pointer(regs)
extern
void
show_regs
(
struct
pt_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
/* __KERNEL__ */
#endif
/* __ASSEMBLY__ */
#endif
/* __ASSEMBLY__ */
...
...
arch/blackfin/include/asm/syscall.h
0 → 100644
View file @
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
View file @
e8f263df
/*
/*
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
* 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
* Licensed under the GPL-2
*/
*/
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
#include <linux/user.h>
#include <linux/user.h>
#include <linux/regset.h>
#include <linux/regset.h>
#include <linux/signal.h>
#include <linux/signal.h>
#include <linux/tracehook.h>
#include <linux/uaccess.h>
#include <linux/uaccess.h>
#include <asm/page.h>
#include <asm/page.h>
...
@@ -32,25 +33,6 @@
...
@@ -32,25 +33,6 @@
* in exit.c or in signal.c.
* 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.
* 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)
...
@@ -234,18 +216,13 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
return
&
user_bfin_native_view
;
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
);
struct
pt_regs
*
regs
=
task_pt_regs
(
child
);
regs
->
syscfg
|=
SYSCFG_SSSTEP
;
regs
->
syscfg
|=
SYSCFG_SSSTEP
;
}
}
/*
void
user_disable_single_step
(
struct
task_struct
*
child
)
* Called by kernel/ptrace.c when detaching..
*
* Make sure the single step bit is not set.
*/
void
ptrace_disable
(
struct
task_struct
*
child
)
{
{
struct
pt_regs
*
regs
=
task_pt_regs
(
child
);
struct
pt_regs
*
regs
=
task_pt_regs
(
child
);
regs
->
syscfg
&=
~
SYSCFG_SSSTEP
;
regs
->
syscfg
&=
~
SYSCFG_SSSTEP
;
...
@@ -412,27 +389,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
...
@@ -412,27 +389,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return
ret
;
return
ret
;
}
}
asmlinkage
void
syscall_trace
(
void
)
asmlinkage
int
syscall_trace_enter
(
struct
pt_regs
*
regs
)
{
{
if
(
!
test_thread_flag
(
TIF_SYSCALL_TRACE
))
int
ret
=
0
;
return
;
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
))
if
(
!
(
current
->
ptrace
&
PT_PTRACED
))
ret
=
tracehook_report_syscall_entry
(
regs
);
return
;
return
ret
;
/* the 0x80 provides a way for the tracing parent to distinguish
}
* between a syscall stop and SIGTRAP delivery
*/
asmlinkage
void
syscall_trace_leave
(
struct
pt_regs
*
regs
)
ptrace_notify
(
SIGTRAP
|
((
current
->
ptrace
&
PT_TRACESYSGOOD
)
{
?
0x80
:
0
));
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
))
tracehook_report_syscall_exit
(
regs
,
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
;
}
}
}
arch/blackfin/kernel/signal.c
View file @
e8f263df
/*
/*
* Copyright 2004-20
09
Analog Devices Inc.
* Copyright 2004-20
10
Analog Devices Inc.
*
*
* Licensed under the GPL-2 or later
* Licensed under the GPL-2 or later
*/
*/
...
@@ -206,16 +206,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
...
@@ -206,16 +206,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
regs
->
r1
=
(
unsigned
long
)(
&
frame
->
info
);
regs
->
r1
=
(
unsigned
long
)(
&
frame
->
info
);
regs
->
r2
=
(
unsigned
long
)(
&
frame
->
uc
);
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
;
return
0
;
give_sigsegv:
give_sigsegv:
...
@@ -315,6 +305,8 @@ asmlinkage void do_signal(struct pt_regs *regs)
...
@@ -315,6 +305,8 @@ asmlinkage void do_signal(struct pt_regs *regs)
* clear the TIF_RESTORE_SIGMASK flag */
* clear the TIF_RESTORE_SIGMASK flag */
if
(
test_thread_flag
(
TIF_RESTORE_SIGMASK
))
if
(
test_thread_flag
(
TIF_RESTORE_SIGMASK
))
clear_thread_flag
(
TIF_RESTORE_SIGMASK
);
clear_thread_flag
(
TIF_RESTORE_SIGMASK
);
tracehook_signal_handler
(
signr
,
&
info
,
&
ka
,
regs
,
1
);
}
}
return
;
return
;
...
...
arch/blackfin/mach-common/entry.S
View file @
e8f263df
...
@@ -736,7 +736,8 @@ ENDPROC(_system_call)
...
@@ -736,7 +736,8 @@ ENDPROC(_system_call)
*
this
symbol
need
not
be
global
anyways
,
so
...
*
this
symbol
need
not
be
global
anyways
,
so
...
*/
*/
_sys_trace
:
_sys_trace
:
pseudo_long_call
_syscall_trace
,
p5
;
r0
=
sp
;
pseudo_long_call
_syscall_trace_enter
,
p5
;
/
*
Execute
the
appropriate
system
call
*/
/
*
Execute
the
appropriate
system
call
*/
...
@@ -760,7 +761,8 @@ _sys_trace:
...
@@ -760,7 +761,8 @@ _sys_trace:
SP
+=
24
;
SP
+=
24
;
[
sp
+
PT_R0
]
=
r0
;
[
sp
+
PT_R0
]
=
r0
;
pseudo_long_call
_syscall_trace
,
p5
;
r0
=
sp
;
pseudo_long_call
_syscall_trace_leave
,
p5
;
jump
.
Lresume_userspace
;
jump
.
Lresume_userspace
;
ENDPROC
(
_sys_trace
)
ENDPROC
(
_sys_trace
)
...
...
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