linux/arch/sh/include/asm/syscall_32.h
<<
>>
Prefs
   1#ifndef __ASM_SH_SYSCALL_32_H
   2#define __ASM_SH_SYSCALL_32_H
   3
   4#include <uapi/linux/audit.h>
   5#include <linux/kernel.h>
   6#include <linux/sched.h>
   7#include <linux/err.h>
   8#include <asm/ptrace.h>
   9
  10/* The system call number is given by the user in R3 */
  11static inline long syscall_get_nr(struct task_struct *task,
  12                                  struct pt_regs *regs)
  13{
  14        return (regs->tra >= 0) ? regs->regs[3] : -1L;
  15}
  16
  17static inline void syscall_rollback(struct task_struct *task,
  18                                    struct pt_regs *regs)
  19{
  20        /*
  21         * XXX: This needs some thought. On SH we don't
  22         * save away the original r0 value anywhere.
  23         */
  24}
  25
  26static inline long syscall_get_error(struct task_struct *task,
  27                                     struct pt_regs *regs)
  28{
  29        return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0;
  30}
  31
  32static inline long syscall_get_return_value(struct task_struct *task,
  33                                            struct pt_regs *regs)
  34{
  35        return regs->regs[0];
  36}
  37
  38static inline void syscall_set_return_value(struct task_struct *task,
  39                                            struct pt_regs *regs,
  40                                            int error, long val)
  41{
  42        if (error)
  43                regs->regs[0] = -error;
  44        else
  45                regs->regs[0] = val;
  46}
  47
  48static inline void syscall_get_arguments(struct task_struct *task,
  49                                         struct pt_regs *regs,
  50                                         unsigned int i, unsigned int n,
  51                                         unsigned long *args)
  52{
  53        /*
  54         * Do this simply for now. If we need to start supporting
  55         * fetching arguments from arbitrary indices, this will need some
  56         * extra logic. Presently there are no in-tree users that depend
  57         * on this behaviour.
  58         */
  59        BUG_ON(i);
  60
  61        /* Argument pattern is: R4, R5, R6, R7, R0, R1 */
  62        switch (n) {
  63        case 6: args[5] = regs->regs[1];
  64        case 5: args[4] = regs->regs[0];
  65        case 4: args[3] = regs->regs[7];
  66        case 3: args[2] = regs->regs[6];
  67        case 2: args[1] = regs->regs[5];
  68        case 1: args[0] = regs->regs[4];
  69        case 0:
  70                break;
  71        default:
  72                BUG();
  73        }
  74}
  75
  76static inline void syscall_set_arguments(struct task_struct *task,
  77                                         struct pt_regs *regs,
  78                                         unsigned int i, unsigned int n,
  79                                         const unsigned long *args)
  80{
  81        /* Same note as above applies */
  82        BUG_ON(i);
  83
  84        switch (n) {
  85        case 6: regs->regs[1] = args[5];
  86        case 5: regs->regs[0] = args[4];
  87        case 4: regs->regs[7] = args[3];
  88        case 3: regs->regs[6] = args[2];
  89        case 2: regs->regs[5] = args[1];
  90        case 1: regs->regs[4] = args[0];
  91                break;
  92        default:
  93                BUG();
  94        }
  95}
  96
  97static inline int syscall_get_arch(void)
  98{
  99        int arch = AUDIT_ARCH_SH;
 100
 101#ifdef CONFIG_CPU_LITTLE_ENDIAN
 102        arch |= __AUDIT_ARCH_LE;
 103#endif
 104        return arch;
 105}
 106#endif /* __ASM_SH_SYSCALL_32_H */
 107