[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: kernel softfloat emulation



浦田です。

At Tue, 23 Nov 1999 16:00:40 +0900,
Shuichiro URATA <ur@a-r.org> wrote:
> > 具体的には、エラーチェックが不充分(*)なため、本来はsegmentation
> > violation等で異常終了するはずのプログラムが異常終了しないことがあると思
> > います。
> > 
> > 	* fpemu.cのlw命令のエミュレーション等でfuword()を用いているが、
> > 	  fuword()ではエラーチェックができない。
> 
> うーん、確かにそうですね。検討してみます。

直しました。あと、SOFTFLOATがない場合にfpemu.cがmakeのターゲットに
ならないようにしました。

で、篠原さんのサンプルがSIGSEGVでcore吐いて死ぬのは確認したんですが、
実はepcの処理を命令実行前にやっているためにgdbで死因を見ようとすると
死んだ場所ではなく次に実行すべき命令をさしてしまいます。
これじゃちょっとデバッグ大変ですね。後で直します。

---
Shuichiro URATA
ur@a-r.org

diff -crN sys.orig/arch/mips/conf/files.mips sys/arch/mips/conf/files.mips
*** sys.orig/arch/mips/conf/files.mips	Thu Nov 18 04:15:48 1999
--- sys/arch/mips/conf/files.mips	Tue Nov 23 12:36:21 1999
***************
*** 12,18 ****
  file	arch/mips/mips/mips_mcclock.c	mcclock	# CPU speed via mcclock
  file	arch/mips/mips/pmap.c
  file	arch/mips/mips/trap.c			# interrupt, trap handlers
- file	arch/mips/mips/fpemu.c			# FPU emulation
  file	arch/mips/mips/vm_machdep.c
  file	arch/mips/mips/mips_machdep.c		# shared mips machdep.c
  file	arch/mips/mips/sys_machdep.c		# shared mips sys_machdep
--- 12,17 ----
***************
*** 20,25 ****
--- 19,26 ----
  
  file	arch/mips/mips/in_cksum.c	inet
  file	netns/ns_cksum.c		ns
+ 
+ file	arch/mips/mips/fpemu.c		softfloat
  
  # Binary compatibility with previous NetBSD releases (COMPAT_XX)
  file	arch/mips/mips/compat_13_machdep.c	compat_13 | compat_ultrix
diff -crN sys.orig/arch/mips/mips/fpemu.c sys/arch/mips/mips/fpemu.c
*** sys.orig/arch/mips/mips/fpemu.c	Mon Nov 22 04:14:26 1999
--- sys/arch/mips/mips/fpemu.c	Tue Nov 23 12:41:25 1999
***************
*** 26,54 ****
   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   */
  
- #ifdef SOFTFLOAT
  #include <sys/param.h>
  #include <sys/systm.h>
- #include <sys/device.h>
  #include <sys/proc.h>
- #include <sys/kernel.h>
- #include <sys/signalvar.h>
- #include <sys/syscall.h>
  #include <sys/user.h>
- #include <sys/buf.h>
- #include <sys/reboot.h>
- #ifdef KTRACE
- #include <sys/ktrace.h>
- #endif
  
  #include <mips/locore.h>
  #include <mips/mips_opcode.h>
  
  #include <machine/cpu.h>
- #include <mips/trap.h>
- #include <machine/psl.h>
  #include <mips/reg.h>
  #include <mips/regnum.h>			/* symbolic register indices */
  extern struct proc *fpcurproc;
  
  int	MachEmulateLWC1 __P((unsigned inst, mips_reg_t *frame));
--- 26,43 ----
   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   */
  
  #include <sys/param.h>
  #include <sys/systm.h>
  #include <sys/proc.h>
  #include <sys/user.h>
  
  #include <mips/locore.h>
  #include <mips/mips_opcode.h>
  
  #include <machine/cpu.h>
  #include <mips/reg.h>
  #include <mips/regnum.h>			/* symbolic register indices */
+ 
  extern struct proc *fpcurproc;
  
  int	MachEmulateLWC1 __P((unsigned inst, mips_reg_t *frame));
***************
*** 83,88 ****
--- 72,79 ----
  	/* segment and alignment check */
  	if (vaddr & 0x80000003)
  		return SIGSEGV;
+ 	if (badaddr((void *)vaddr, 4) < 0)
+ 		return SIGSEGV;
  
  	x = fuword((void *)vaddr);
  	fpcurproc->p_addr->u_pcb.pcb_fpregs.r_regs[(inst>>16)&0x1F] = x;
***************
*** 105,110 ****
--- 96,105 ----
  	/* segment and alignment check */
  	if (vaddr & 0x80000007)
  		return SIGSEGV;
+ 	if (badaddr((void *)vaddr, 4) < 0)
+ 		return SIGSEGV;
+ 	if (badaddr((void *)(vaddr+4), 4) < 0)
+ 		return SIGSEGV;
  
  	x = fuword((void *)vaddr);
  	fpcurproc->p_addr->u_pcb.pcb_fpregs.r_regs[(inst>>16)&0x1F] = x;
***************
*** 131,137 ****
  		return SIGSEGV;
  
  	x = fpcurproc->p_addr->u_pcb.pcb_fpregs.r_regs[(inst>>16)&0x1F];
! 	suword((void *)vaddr, x);
  
  	return 0;
  }
--- 126,133 ----
  		return SIGSEGV;
  
  	x = fpcurproc->p_addr->u_pcb.pcb_fpregs.r_regs[(inst>>16)&0x1F];
! 	if (suword((void *)vaddr, x) < 0)
! 		return SIGSEGV;
  
  	return 0;
  }
***************
*** 153,161 ****
  		return SIGSEGV;
  
  	x = fpcurproc->p_addr->u_pcb.pcb_fpregs.r_regs[(inst>>16)&0x1F];
! 	suword((void *)vaddr, x);
  	x = fpcurproc->p_addr->u_pcb.pcb_fpregs.r_regs[((inst>>16)&0x1F)+1];
! 	suword((void *)(vaddr+4), x);
  
  	return 0;
  }
--- 149,159 ----
  		return SIGSEGV;
  
  	x = fpcurproc->p_addr->u_pcb.pcb_fpregs.r_regs[(inst>>16)&0x1F];
! 	if (suword((void *)vaddr, x) < 0)
! 		return SIGSEGV;
  	x = fpcurproc->p_addr->u_pcb.pcb_fpregs.r_regs[((inst>>16)&0x1F)+1];
! 	if (suword((void *)(vaddr+4), x) < 0)
! 		return SIGSEGV;
  
  	return 0;
  }
***************
*** 174,179 ****
--- 172,179 ----
  	/* segment check */
  	if (vaddr & 0x80000000)
  		return SIGSEGV;
+ 	if (badaddr((void *)vaddr, 1) < 0)
+ 		return SIGSEGV;
  
  	x = fubyte((void *)vaddr);
  	if (x & 0x80)
***************
*** 197,202 ****
--- 197,204 ----
  	/* segment check */
  	if (vaddr & 0x80000000)
  		return SIGSEGV;
+ 	if (badaddr((void *)vaddr, 1) < 0)
+ 		return SIGSEGV;
  
  	frame[(inst>>16)&0x1F] = fubyte((void *)vaddr);
  
***************
*** 217,222 ****
--- 219,226 ----
  	/* segment and alignment check */
  	if (vaddr & 0x80000001)
  		return SIGSEGV;
+ 	if (badaddr((void *)vaddr, 2) < 0)
+ 		return SIGSEGV;
  
  	x = fusword((void *)vaddr);
  	if (x & 0x8000)
***************
*** 240,245 ****
--- 244,251 ----
  	/* segment and alignment check */
  	if (vaddr & 0x80000001)
  		return SIGSEGV;
+ 	if (badaddr((void *)vaddr, 2) < 0)
+ 		return SIGSEGV;
  
  	frame[(inst>>16)&0x1F] = fusword((void *)vaddr);
  
***************
*** 260,265 ****
--- 266,273 ----
  	/* segment and alignment check */
  	if (vaddr & 0x80000003)
  		return SIGSEGV;
+ 	if (badaddr((void *)vaddr, 4) < 0)
+ 		return SIGSEGV;
  
  	frame[(inst>>16)&0x1F] = fuword((void *)vaddr);
  
***************
*** 280,285 ****
--- 288,295 ----
  	/* segment check */
  	if (vaddr & 0x80000000)
  		return SIGSEGV;
+ 	if (badaddr((void *)(vaddr & ~0x3), 4) < 0)
+ 		return SIGSEGV;
  
  	a = fuword((void *)(vaddr & ~0x3));
  	x = frame[(inst>>16)&0x1F];
***************
*** 308,313 ****
--- 318,325 ----
  	/* segment check */
  	if (vaddr & 0x80000000)
  		return SIGSEGV;
+ 	if (badaddr((void *)(vaddr & ~0x3), 4) < 0)
+ 		return SIGSEGV;
  
  	a = fuword((void *)(vaddr & ~0x3));
  	x = frame[(inst>>16)&0x1F];
***************
*** 337,343 ****
  	if (vaddr & 0x80000000)
  		return SIGSEGV;
  
! 	subyte((void *)vaddr, frame[(inst>>16)&0x1F]);
  
  	return 0;
  }
--- 349,356 ----
  	if (vaddr & 0x80000000)
  		return SIGSEGV;
  
! 	if (subyte((void *)vaddr, frame[(inst>>16)&0x1F]) < 0)
! 		return SIGSEGV;
  
  	return 0;
  }
***************
*** 357,363 ****
  	if (vaddr & 0x80000001)
  		return SIGSEGV;
  
! 	susword((void *)vaddr, frame[(inst>>16)&0x1F]);
  
  	return 0;
  }
--- 370,377 ----
  	if (vaddr & 0x80000001)
  		return SIGSEGV;
  
! 	if (susword((void *)vaddr, frame[(inst>>16)&0x1F]) < 0)
! 		return SIGSEGV;
  
  	return 0;
  }
***************
*** 377,383 ****
  	if (vaddr & 0x80000003)
  		return SIGSEGV;
  
! 	suword((void *)vaddr, frame[(inst>>16)&0x1F]);
  
  	return 0;
  }
--- 391,398 ----
  	if (vaddr & 0x80000003)
  		return SIGSEGV;
  
! 	if (suword((void *)vaddr, frame[(inst>>16)&0x1F]) < 0)
! 		return SIGSEGV;
  
  	return 0;
  }
***************
*** 396,401 ****
--- 411,418 ----
  	/* segment check */
  	if (vaddr & 0x80000000)
  		return SIGSEGV;
+ 	if (badaddr((void *)(vaddr & ~0x3), 4) < 0)
+ 		return SIGSEGV;
  
  	a = fuword((void *)(vaddr & ~0x3));
  	x = frame[(inst>>16)&0x1F];
***************
*** 424,429 ****
--- 441,448 ----
  	/* segment check */
  	if (vaddr & 0x80000000)
  		return SIGSEGV;
+ 	if (badaddr((void *)(vaddr & ~0x3), 4) < 0)
+ 		return SIGSEGV;
  
  	a = fuword((void *)(vaddr & ~0x3));
  	x = frame[(inst>>16)&0x1F];
***************
*** 437,440 ****
  
  	return 0;
  }
- #endif /* SOFTFLOAT */
--- 456,458 ----