summary refs log tree commit diff stats
path: root/linux-user
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-12-19 23:18:01 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-12-19 23:18:01 +0000
commite80cfcfc8884400e826328b772971913a14d0f44 (patch)
treef9bbe461ff5dd6f13fbdbd781053309564c0b872 /linux-user
parent9772c73bbc9f24a66bf060e16c0625a258b1bb41 (diff)
downloadfocaccia-qemu-e80cfcfc8884400e826328b772971913a14d0f44.tar.gz
focaccia-qemu-e80cfcfc8884400e826328b772971913a14d0f44.zip
SPARC merge
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1179 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/elfload.c16
-rw-r--r--linux-user/main.c2
-rw-r--r--linux-user/signal.c79
3 files changed, 55 insertions, 42 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index cfc4256974..09c33aa90b 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -841,6 +841,7 @@ static void load_symbols(struct elfhdr *hdr, int fd)
     unsigned int i;
     struct elf_shdr sechdr, symtab, strtab;
     char *strings;
+    struct syminfo *s;
 
     lseek(fd, hdr->e_shoff, SEEK_SET);
     for (i = 0; i < hdr->e_shnum; i++) {
@@ -866,24 +867,27 @@ static void load_symbols(struct elfhdr *hdr, int fd)
 
  found:
     /* Now know where the strtab and symtab are.  Snarf them. */
-    disas_symtab = malloc(symtab.sh_size);
-    disas_strtab = strings = malloc(strtab.sh_size);
-    if (!disas_symtab || !disas_strtab)
+    s = malloc(sizeof(*s));
+    s->disas_symtab = malloc(symtab.sh_size);
+    s->disas_strtab = strings = malloc(strtab.sh_size);
+    if (!s->disas_symtab || !s->disas_strtab)
 	return;
 	
     lseek(fd, symtab.sh_offset, SEEK_SET);
-    if (read(fd, disas_symtab, symtab.sh_size) != symtab.sh_size)
+    if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size)
 	return;
 
 #ifdef BSWAP_NEEDED
     for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
-	bswap_sym(disas_symtab + sizeof(struct elf_sym)*i);
+	bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i);
 #endif
 
     lseek(fd, strtab.sh_offset, SEEK_SET);
     if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
 	return;
-    disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
+    s->disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
+    s->next = syminfos;
+    syminfos = s;
 }
 
 static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
diff --git a/linux-user/main.c b/linux-user/main.c
index 6ab024e0bf..3d99dda1ad 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -497,6 +497,8 @@ void cpu_loop (CPUSPARCState *env)
         case TT_WIN_UNF: /* window underflow */
             restore_window(env);
             break;
+	case 0x100: // XXX, why do we get these?
+	    break;
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
             cpu_dump_state(env, stderr, fprintf, 0);
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 50f2ba10a0..49278208c5 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -1354,13 +1354,14 @@ struct target_rt_signal_frame {
 	__siginfo_fpu_t		fpu_state;
 };
 
-#define UREG_O0        0
-#define UREG_O6        6
-#define UREG_I0        16
-#define UREG_I1        17
-#define UREG_I2        18
-#define UREG_I6        22
-#define UREG_I7        23
+#define UREG_O0        16
+#define UREG_O6        22
+#define UREG_I0        0
+#define UREG_I1        1
+#define UREG_I2        2
+#define UREG_I6        6
+#define UREG_I7        7
+#define UREG_L0	       8
 #define UREG_FP        UREG_I6
 #define UREG_SP        UREG_O6
 
@@ -1385,23 +1386,20 @@ setup___siginfo(__siginfo_t *si, CPUState *env, target_ulong mask)
 {
 	int err = 0, i;
 
-	fprintf(stderr, "2.a %lx psr: %lx regs: %lx\n", si, env->psr, si->si_regs.psr);
 	err |= __put_user(env->psr, &si->si_regs.psr);
-	fprintf(stderr, "2.a1 pc:%lx\n", si->si_regs.pc);
 	err |= __put_user(env->pc, &si->si_regs.pc);
 	err |= __put_user(env->npc, &si->si_regs.npc);
 	err |= __put_user(env->y, &si->si_regs.y);
-	fprintf(stderr, "2.b\n");
 	for (i=0; i < 7; i++) {
 		err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
 	}
 	for (i=0; i < 7; i++) {
-		err |= __put_user(env->regwptr[i+16], &si->si_regs.u_regs[i+8]);
+		err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
 	}
-	fprintf(stderr, "2.c\n");
 	err |= __put_user(mask, &si->si_mask);
 	return err;
 }
+
 static int
 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
 		 CPUState *env, unsigned long mask)
@@ -1434,6 +1432,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
 	sf = (struct target_signal_frame *)
 		get_sigframe(ka, env, sigframe_size);
 
+	//fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
 #if 0
 	if (invalid_frame_pointer(sf, sigframe_size))
 		goto sigill_and_return;
@@ -1451,13 +1450,11 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
 	}
 
 	for (i = 0; i < 7; i++) {
-	  	err |= __put_user(env->regwptr[i + 8], &sf->ss.locals[i]);
+	  	err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
 	}
 	for (i = 0; i < 7; i++) {
-	  	err |= __put_user(env->regwptr[i + 16], &sf->ss.ins[i]);
+	  	err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
 	}
-	//err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
-	//		      sizeof(struct reg_window));
 	if (err)
 		goto sigsegv;
 
@@ -1486,13 +1483,15 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
 
 		/* Flush instruction space. */
 		//flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
-		//tb_flush(env);
+		tb_flush(env);
 	}
+	//cpu_dump_state(env, stderr, fprintf, 0);
 	return;
 
 sigill_and_return:
 	force_sig(TARGET_SIGILL);
 sigsegv:
+	//fprintf(stderr, "force_sig\n");
 	force_sig(TARGET_SIGSEGV);
 }
 static inline int
@@ -1542,13 +1541,16 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
 long do_sigreturn(CPUState *env)
 {
         struct target_signal_frame *sf;
-        unsigned long up_psr, pc, npc;
+        uint32_t up_psr, pc, npc;
         target_sigset_t set;
+        sigset_t host_set;
         __siginfo_fpu_t *fpu_save;
-        int err;
+        int err, i;
 
-        sf = (struct new_signal_frame *) env->regwptr[UREG_FP];
-	fprintf(stderr, "sigreturn sf: %lx\n", &sf);
+        sf = (struct target_signal_frame *) env->regwptr[UREG_FP];
+	fprintf(stderr, "sigreturn\n");
+	fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
+	//cpu_dump_state(env, stderr, fprintf, 0);
 
         /* 1. Make sure we are not getting garbage from the user */
 #if 0
@@ -1567,36 +1569,41 @@ long do_sigreturn(CPUState *env)
                 goto segv_and_exit;
 
         /* 2. Restore the state */
-        up_psr = env->psr;
-        //err |= __copy_from_user(regs, &sf->info.si_regs, sizeof (struct pt_regs)
-	//);
+        err |= __get_user(up_psr, &sf->info.si_regs.psr);
+
         /* User can only change condition codes and FPU enabling in %psr. */
         env->psr = (up_psr & ~(PSR_ICC /* | PSR_EF */))
                   | (env->psr & (PSR_ICC /* | PSR_EF */));
-	fprintf(stderr, "psr: %lx\n", env->psr);
+	fprintf(stderr, "psr: %x\n", env->psr);
+	env->pc = pc-4;
+	env->npc = pc;
+        err |= __get_user(env->y, &sf->info.si_regs.y);
+	for (i=0; i < 7; i++) {
+		err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
+	}
+	for (i=0; i < 7; i++) {
+		err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
+	}
 
         err |= __get_user(fpu_save, &sf->fpu_save);
 
-        if (fpu_save)
-                err |= restore_fpu_state(env, fpu_save);
+        //if (fpu_save)
+        //        err |= restore_fpu_state(env, fpu_save);
 
         /* This is pretty much atomic, no amount locking would prevent
          * the races which exist anyways.
          */
         err |= __get_user(set.sig[0], &sf->info.si_mask);
-        //err |= __copy_from_user(&set.sig[1], &sf->extramask,
-        //                        (_NSIG_WORDS-1) * sizeof(unsigned int));
+        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
+            err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
+        }
+
+        target_to_host_sigset_internal(&host_set, &set);
+        sigprocmask(SIG_SETMASK, &host_set, NULL);
 
         if (err)
                 goto segv_and_exit;
 
-#if 0
-        sigdelsetmask(&set, ~_BLOCKABLE);
-        spin_lock_irq(&current->sigmask_lock);
-        current->blocked = set;
-        recalc_sigpending(current);
-        spin_unlock_irq(&current->sigmask_lock);
-#endif
 	fprintf(stderr, "returning %lx\n", env->regwptr[0]);
         return env->regwptr[0];