sh: gcc4 support.
authorStuart Menefy <stuart.menefy@st.com>
Tue, 21 Nov 2006 02:16:57 +0000 (11:16 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Wed, 6 Dec 2006 01:45:38 +0000 (10:45 +0900)
This fixes up the kernel for gcc4. The existing exception handlers
needed some wrapping for pt_regs access, acessing the registers
via a RELOC_HIDE() pointer.

The strcpy() issues popped up here too, so add -ffreestanding and
kill off the symbol export.

Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/Makefile
arch/sh/kernel/cpu/sh4/fpu.c
arch/sh/kernel/irq.c
arch/sh/kernel/process.c
arch/sh/kernel/sh_ksyms.c
arch/sh/kernel/signal.c
arch/sh/kernel/sys_sh.c
arch/sh/kernel/traps.c

index 6b3af5c..7f4516c 100644 (file)
@@ -43,7 +43,7 @@ cflags-$(CONFIG_CPU_SH4A)             := -m4a $(call cc-option,-m4a-nofpu,)
 cflags-$(CONFIG_CPU_BIG_ENDIAN)                += -mb
 cflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += -ml
 
-cflags-y       += $(call as-option,-Wa$(comma)-isa=$(isa-y),)
+cflags-y       += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding
 
 cflags-$(CONFIG_SH_DSP)                        += -Wa,-dsp
 cflags-$(CONFIG_SH_KGDB)               += -g
index f486c07..378b488 100644 (file)
@@ -296,16 +296,17 @@ ieee_fpe_handler (struct pt_regs *regs)
 }
 
 asmlinkage void
-do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7,
-            struct pt_regs regs)
+do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6,
+            unsigned long r7, struct pt_regs __regs)
 {
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        struct task_struct *tsk = current;
 
-       if (ieee_fpe_handler (&regs))
+       if (ieee_fpe_handler(regs))
                return;
 
-       regs.pc += 2;
-       save_fpu(tsk, &regs);
+       regs->pc += 2;
+       save_fpu(tsk, regs);
        tsk->thread.trap_no = 11;
        tsk->thread.error_code = 0;
        force_sig(SIGFPE, tsk);
@@ -313,12 +314,13 @@ do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long
 
 asmlinkage void
 do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6,
-                    unsigned long r7, struct pt_regs regs)
+                    unsigned long r7, struct pt_regs __regs)
 {
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        struct task_struct *tsk = current;
 
-       grab_fpu(&regs);
-       if (!user_mode(&regs)) {
+       grab_fpu(regs);
+       if (!user_mode(regs)) {
                printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
                return;
        }
index 944128c..edf4d2d 100644 (file)
@@ -84,9 +84,10 @@ static union irq_ctx *softirq_ctx[NR_CPUS];
 
 asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
                      unsigned long r6, unsigned long r7,
-                     struct pt_regs regs)
+                     struct pt_regs __regs)
 {
-       struct pt_regs *old_regs = set_irq_regs(&regs);
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
+       struct pt_regs *old_regs = set_irq_regs(regs);
        int irq;
 #ifdef CONFIG_4KSTACKS
        union irq_ctx *curctx, *irqctx;
index a52b13a..f3e2631 100644 (file)
@@ -385,10 +385,11 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
 
 asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
                        unsigned long r6, unsigned long r7,
-                       struct pt_regs regs)
+                       struct pt_regs __regs)
 {
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
 #ifdef CONFIG_MMU
-       return do_fork(SIGCHLD, regs.regs[15], &regs, 0, NULL, NULL);
+       return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL);
 #else
        /* fork almost works, enough to trick you into looking elsewhere :-( */
        return -EINVAL;
@@ -398,11 +399,12 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
 asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
                         unsigned long parent_tidptr,
                         unsigned long child_tidptr,
-                        struct pt_regs regs)
+                        struct pt_regs __regs)
 {
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        if (!newsp)
-               newsp = regs.regs[15];
-       return do_fork(clone_flags, newsp, &regs, 0,
+               newsp = regs->regs[15];
+       return do_fork(clone_flags, newsp, regs, 0,
                        (int __user *)parent_tidptr, (int __user *)child_tidptr);
 }
 
@@ -418,9 +420,10 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
  */
 asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
                         unsigned long r6, unsigned long r7,
-                        struct pt_regs regs)
+                        struct pt_regs __regs)
 {
-       return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], &regs,
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
+       return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->regs[15], regs,
                       0, NULL, NULL);
 }
 
@@ -429,8 +432,9 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
  */
 asmlinkage int sys_execve(char *ufilename, char **uargv,
                          char **uenvp, unsigned long r7,
-                         struct pt_regs regs)
+                         struct pt_regs __regs)
 {
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        int error;
        char *filename;
 
@@ -442,7 +446,7 @@ asmlinkage int sys_execve(char *ufilename, char **uargv,
        error = do_execve(filename,
                          (char __user * __user *)uargv,
                          (char __user * __user *)uenvp,
-                         &regs);
+                         regs);
        if (error == 0) {
                task_lock(current);
                current->ptrace &= ~PT_DTRACE;
@@ -472,9 +476,7 @@ unsigned long get_wchan(struct task_struct *p)
        return pc;
 }
 
-asmlinkage void break_point_trap(unsigned long r4, unsigned long r5,
-                                unsigned long r6, unsigned long r7,
-                                struct pt_regs regs)
+asmlinkage void break_point_trap(void)
 {
        /* Clear tracing.  */
 #if defined(CONFIG_CPU_SH4A)
@@ -492,8 +494,10 @@ asmlinkage void break_point_trap(unsigned long r4, unsigned long r5,
 
 asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5,
                                          unsigned long r6, unsigned long r7,
-                                         struct pt_regs regs)
+                                         struct pt_regs __regs)
 {
-       regs.pc -= 2;
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
+
+       regs->pc -= 2;
        force_sig(SIGTRAP, current);
 }
index 8a2fd19..c706f3b 100644 (file)
@@ -73,8 +73,6 @@ DECLARE_EXPORT(__lshrdi3);
 DECLARE_EXPORT(__movstr);
 DECLARE_EXPORT(__movstrSI16);
 
-EXPORT_SYMBOL(strcpy);
-
 #ifdef CONFIG_CPU_SH4
 DECLARE_EXPORT(__movstr_i4_even);
 DECLARE_EXPORT(__movstr_i4_odd);
index 764886b..50d7c49 100644 (file)
@@ -37,7 +37,7 @@
 asmlinkage int
 sys_sigsuspend(old_sigset_t mask,
               unsigned long r5, unsigned long r6, unsigned long r7,
-              struct pt_regs regs)
+              struct pt_regs __regs)
 {
        mask &= _BLOCKABLE;
        spin_lock_irq(&current->sighand->siglock);
@@ -52,7 +52,7 @@ sys_sigsuspend(old_sigset_t mask,
        return -ERESTARTNOHAND;
 }
 
-asmlinkage int 
+asmlinkage int
 sys_sigaction(int sig, const struct old_sigaction __user *act,
              struct old_sigaction __user *oact)
 {
@@ -87,9 +87,11 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
 asmlinkage int
 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
                unsigned long r6, unsigned long r7,
-               struct pt_regs regs)
+               struct pt_regs __regs)
 {
-       return do_sigaltstack(uss, uoss, regs.regs[15]);
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
+
+       return do_sigaltstack(uss, uoss, regs->regs[15]);
 }
 
 
@@ -198,9 +200,10 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
 
 asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
                             unsigned long r6, unsigned long r7,
-                            struct pt_regs regs)
+                            struct pt_regs __regs)
 {
-       struct sigframe __user *frame = (struct sigframe __user *)regs.regs[15];
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
+       struct sigframe __user *frame = (struct sigframe __user *)regs->regs[15];
        sigset_t set;
        int r0;
 
@@ -220,7 +223,7 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       if (restore_sigcontext(&regs, &frame->sc, &r0))
+       if (restore_sigcontext(regs, &frame->sc, &r0))
                goto badframe;
        return r0;
 
@@ -231,9 +234,10 @@ badframe:
 
 asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
                                unsigned long r6, unsigned long r7,
-                               struct pt_regs regs)
+                               struct pt_regs __regs)
 {
-       struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs.regs[15];
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
+       struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->regs[15];
        sigset_t set;
        stack_t st;
        int r0;
@@ -250,14 +254,14 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       if (restore_sigcontext(&regs, &frame->uc.uc_mcontext, &r0))
+       if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
                goto badframe;
 
        if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
                goto badframe;
        /* It is more difficult to avoid calling this function than to
           call it and ignore errors.  */
-       do_sigaltstack(&st, NULL, regs.regs[15]);
+       do_sigaltstack(&st, NULL, regs->regs[15]);
 
        return r0;
 
index 07f2b57..5083b6e 100644 (file)
  */
 asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
        unsigned long r6, unsigned long r7,
-       struct pt_regs regs)
+       struct pt_regs __regs)
 {
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        int fd[2];
        int error;
 
        error = do_pipe(fd);
        if (!error) {
-               regs.regs[1] = fd[1];
+               regs->regs[1] = fd[1];
                return fd[0];
        }
        return error;
index f558748..b52037b 100644 (file)
@@ -23,8 +23,8 @@
 
 #ifdef CONFIG_SH_KGDB
 #include <asm/kgdb.h>
-#define CHK_REMOTE_DEBUG(regs)                         \
-{                                              \
+#define CHK_REMOTE_DEBUG(regs)                 \
+{                                              \
        if (kgdb_debug_hook && !user_mode(regs))\
                (*kgdb_debug_hook)(regs);       \
 }
@@ -501,7 +501,7 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
 /*
  * Handle various address error exceptions
  */
-asmlinkage void do_address_error(struct pt_regs *regs, 
+asmlinkage void do_address_error(struct pt_regs *regs,
                                 unsigned long writeaccess,
                                 unsigned long address)
 {
@@ -588,7 +588,7 @@ int is_dsp_inst(struct pt_regs *regs)
 {
        unsigned short inst;
 
-       /* 
+       /*
         * Safe guard if DSP mode is already enabled or we're lacking
         * the DSP altogether.
         */
@@ -612,8 +612,9 @@ int is_dsp_inst(struct pt_regs *regs)
 #ifdef CONFIG_CPU_SH2A
 asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
                                unsigned long r6, unsigned long r7,
-                               struct pt_regs regs)
+                               struct pt_regs __regs)
 {
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        siginfo_t info;
 
        current->thread.trap_no = r4;
@@ -635,12 +636,13 @@ asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
 /* arch/sh/kernel/cpu/sh4/fpu.c */
 extern int do_fpu_inst(unsigned short, struct pt_regs *);
 extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5,
-               unsigned long r6, unsigned long r7, struct pt_regs regs);
+               unsigned long r6, unsigned long r7, struct pt_regs __regs);
 
 asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
                                unsigned long r6, unsigned long r7,
-                               struct pt_regs regs)
+                               struct pt_regs __regs)
 {
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        unsigned long error_code;
        struct task_struct *tsk = current;
 
@@ -648,11 +650,11 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
        unsigned short inst = 0;
        int err;
 
-       get_user(inst, (unsigned short*)regs.pc);
+       get_user(inst, (unsigned short*)regs->pc);
 
-       err = do_fpu_inst(inst, &regs);
+       err = do_fpu_inst(inst, regs);
        if (!err) {
-               regs.pc += 2;
+               regs->pc += 2;
                return;
        }
        /* not a FPU inst. */
@@ -660,9 +662,9 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
 
 #ifdef CONFIG_SH_DSP
        /* Check if it's a DSP instruction */
-       if (is_dsp_inst(&regs)) {
+       if (is_dsp_inst(regs)) {
                /* Enable DSP mode, and restart instruction. */
-               regs.sr |= SR_DSP;
+               regs->sr |= SR_DSP;
                return;
        }
 #endif
@@ -672,9 +674,9 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
        local_irq_enable();
        tsk->thread.error_code = error_code;
        tsk->thread.trap_no = TRAP_RESERVED_INST;
-       CHK_REMOTE_DEBUG(&regs);
+       CHK_REMOTE_DEBUG(regs);
        force_sig(SIGILL, tsk);
-       die_if_no_fixup("reserved instruction", &regs, error_code);
+       die_if_no_fixup("reserved instruction", regs, error_code);
 }
 
 #ifdef CONFIG_SH_FPU_EMU
@@ -722,17 +724,18 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs)
 
 asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
                                unsigned long r6, unsigned long r7,
-                               struct pt_regs regs)
+                               struct pt_regs __regs)
 {
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        unsigned long error_code;
        struct task_struct *tsk = current;
 #ifdef CONFIG_SH_FPU_EMU
        unsigned short inst = 0;
 
-       get_user(inst, (unsigned short *)regs.pc + 1);
-       if (!do_fpu_inst(inst, &regs)) {
-               get_user(inst, (unsigned short *)regs.pc);
-               if (!emulate_branch(inst, &regs))
+       get_user(inst, (unsigned short *)regs->pc + 1);
+       if (!do_fpu_inst(inst, regs)) {
+               get_user(inst, (unsigned short *)regs->pc);
+               if (!emulate_branch(inst, regs))
                        return;
                /* fault in branch.*/
        }
@@ -744,19 +747,20 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
        local_irq_enable();
        tsk->thread.error_code = error_code;
        tsk->thread.trap_no = TRAP_RESERVED_INST;
-       CHK_REMOTE_DEBUG(&regs);
+       CHK_REMOTE_DEBUG(regs);
        force_sig(SIGILL, tsk);
-       die_if_no_fixup("illegal slot instruction", &regs, error_code);
+       die_if_no_fixup("illegal slot instruction", regs, error_code);
 }
 
 asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
                                   unsigned long r6, unsigned long r7,
-                                  struct pt_regs regs)
+                                  struct pt_regs __regs)
 {
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        long ex;
 
        lookup_exception_vector(ex);
-       die_if_kernel("exception", &regs, ex);
+       die_if_kernel("exception", regs, ex);
 }
 
 #if defined(CONFIG_SH_STANDARD_BIOS)
@@ -809,7 +813,7 @@ void *set_exception_table_vec(unsigned int vec, void *handler)
 
 extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5,
                                             unsigned long r6, unsigned long r7,
-                                            struct pt_regs regs);
+                                            struct pt_regs __regs);
 
 void __init trap_init(void)
 {