/*
* Access to user system call parameters and results
*
* 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 .
*
* See asm - generic / syscall . h for descriptions of what we must do here .
*
* Copyright ( C ) 2012 Ralf Baechle < ralf @ linux - mips . org >
*/
#ifndef __ASM_MIPS_SYSCALL_H
#define __ASM_MIPS_SYSCALL_H
#include <linux/compiler.h>
#include <uapi/linux/audit.h>
#include <linux/elf-em.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <asm /ptrace.h>
#include <asm /unistd.h>
#ifndef __NR_syscall /* Only defined if _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_syscall 4000
#endif
static inline bool mips_syscall_is_indirect(struct task_struct *task,
struct pt_regs *regs)
{
/* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */
return (IS_ENABLED(CONFIG_32BIT) ||
test_tsk_thread_flag(task, TIF_32BIT_REGS)) &&
(regs->regs[2 ] == __NR_syscall);
}
static inline long syscall_get_nr(struct task_struct *task,
struct pt_regs *regs)
{
return task_thread_info(task)->syscall;
}
static inline void syscall_set_nr(struct task_struct *task,
struct pt_regs *regs,
int nr)
{
/*
* New syscall number has to be assigned to regs [ 2 ] because
* it is loaded from there unconditionally after return from
* syscall_trace_enter ( ) invocation .
*
* Consequently , if the syscall was indirect and nr ! = _ _ NR_syscall ,
* then after this assignment the syscall will cease to be indirect .
*/
task_thread_info(task)->syscall = regs->regs[2 ] = nr;
}
static inline void mips_syscall_update_nr(struct task_struct *task,
struct pt_regs *regs)
{
/*
* v0 is the system call number , except for O32 ABI syscall ( ) , where it
* ends up in a0 .
*/
if (mips_syscall_is_indirect(task, regs))
task_thread_info(task)->syscall = regs->regs[4 ];
else
task_thread_info(task)->syscall = regs->regs[2 ];
}
static inline void mips_get_syscall_arg(unsigned long *arg,
struct task_struct *task, struct pt_regs *regs, unsigned int n)
{
#ifdef CONFIG_32BIT
switch (n) {
case 0 : case 1 : case 2 : case 3 :
*arg = regs->regs[4 + n];
return ;
case 4 : case 5 : case 6 : case 7 :
*arg = regs->args[n];
return ;
}
#else
*arg = regs->regs[4 + n];
if ((IS_ENABLED(CONFIG_MIPS32_O32) &&
test_tsk_thread_flag(task, TIF_32BIT_REGS)))
*arg = (unsigned int )*arg;
#endif
}
static inline void mips_set_syscall_arg(unsigned long *arg,
struct task_struct *task, struct pt_regs *regs, unsigned int n)
{
#ifdef CONFIG_32BIT
switch (n) {
case 0 : case 1 : case 2 : case 3 :
regs->regs[4 + n] = *arg;
return ;
case 4 : case 5 : case 6 : case 7 :
*arg = regs->args[n] = *arg;
return ;
}
#else
regs->regs[4 + n] = *arg;
#endif
}
static inline long syscall_get_error(struct task_struct *task,
struct pt_regs *regs)
{
return regs->regs[7 ] ? -regs->regs[2 ] : 0 ;
}
static inline long syscall_get_return_value(struct task_struct *task,
struct pt_regs *regs)
{
return regs->regs[2 ];
}
static inline void syscall_rollback(struct task_struct *task,
struct pt_regs *regs)
{
/* Do nothing */
}
static inline void syscall_set_return_value(struct task_struct *task,
struct pt_regs *regs,
int error, long val)
{
if (error) {
regs->regs[2 ] = -error;
regs->regs[7 ] = 1 ;
} else {
regs->regs[2 ] = val;
regs->regs[7 ] = 0 ;
}
}
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
unsigned long *args)
{
unsigned int i = 0 ;
unsigned int n = 6 ;
/* O32 ABI syscall() */
if (mips_syscall_is_indirect(task, regs))
i++;
while (n--)
mips_get_syscall_arg(args++, task, regs, i++);
}
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
unsigned long *args)
{
unsigned int i = 0 ;
unsigned int n = 6 ;
while (n--)
mips_set_syscall_arg(args++, task, regs, i++);
}
extern const unsigned long sys_call_table[];
extern const unsigned long sys32_call_table[];
extern const unsigned long sysn32_call_table[];
static inline int syscall_get_arch(struct task_struct *task)
{
int arch = AUDIT_ARCH_MIPS;
#ifdef CONFIG_64BIT
if (!test_tsk_thread_flag(task, TIF_32BIT_REGS)) {
arch |= __AUDIT_ARCH_64BIT;
/* N32 sets only TIF_32BIT_ADDR */
if (test_tsk_thread_flag(task, TIF_32BIT_ADDR))
arch |= __AUDIT_ARCH_CONVENTION_MIPS64_N32;
}
#endif
#if defined (__LITTLE_ENDIAN)
arch |= __AUDIT_ARCH_LE;
#endif
return arch;
}
#endif /* __ASM_MIPS_SYSCALL_H */
Messung V0.5 in Prozent C=98 H=84 G=91
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.10Bemerkung:
(vorverarbeitet am 2026-09-28)
¤
*Bot Zugriff