mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-30 13:34:27 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			100 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| commit 2952c70804b48bb5c87eea21df5e401969dc4ec1
 | |
| Author: Kevin Cernekee <cernekee@gmail.com>
 | |
| Date:   Tue Jun 5 15:05:20 2012 -0700
 | |
| 
 | |
|     MIPS: Use $a0 instead of $v0 for __syscall_error() argument
 | |
|     
 | |
|     $a0 is saved across _dl_runtime_resolve(); $v0 is not.  Unfortunately,
 | |
|     __syscall_error() uses $v0 for its argument, not $a0 as is the MIPS ABI
 | |
|     standard.  This means that if lazy binding was used for __syscall_error(),
 | |
|     the errno value in $v0 could get corrupted.
 | |
|     
 | |
|     The problem can be easily seen in testcases where syscalls in librt fail;
 | |
|     when librt tries to call __syscall_error() in libc, the argument gets
 | |
|     lost and errno gets set to a bogus value:
 | |
|     
 | |
|         # ./tst-mqueue1 ; echo $?
 | |
|         mq_receive on O_WRONLY mqd_t did not fail with EBADF: Unknown error 2004684208
 | |
|         1
 | |
|         # ./tst-mqueue2 ; echo $?
 | |
|         mq_timedreceive with too small msg_len did not fail with EMSGSIZE: Unknown error 1997360560
 | |
|         1
 | |
|         # ./tst-mqueue4 ; echo $?
 | |
|         mq_timedsend did not fail with ETIMEDOUT: Unknown error 2008747440
 | |
|         1
 | |
|     
 | |
|     When _dl_runtime_resolve() was taken out of the equation, the same test
 | |
|     cases passed:
 | |
|     
 | |
|         # LD_BIND_NOW=y ./tst-mqueue1 ; echo $?
 | |
|         0
 | |
|         # LD_BIND_NOW=y ./tst-mqueue2 ; echo $?
 | |
|         0
 | |
|         # LD_BIND_NOW=y ./tst-mqueue4 ; echo $?
 | |
|         0
 | |
|     
 | |
|     Changing __syscall_error() to look at $a0 instead of $v0 fixed the
 | |
|     problem.
 | |
|     
 | |
|     (Note that there is also a "__syscall_error.c" file which presumably
 | |
|     uses the standard C calling conventions, but I do not think it is used
 | |
|     on MIPS.)
 | |
|     
 | |
|     Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
 | |
|     Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
 | |
| 
 | |
| commit 3c58d95d918c7e2fda374c37a52f81b34b81e4ca
 | |
| Author: Kevin Cernekee <cernekee@gmail.com>
 | |
| Date:   Tue Jun 5 15:05:19 2012 -0700
 | |
| 
 | |
|     MIPS: Convert __syscall_error() callers to use $a0 for argument
 | |
|     
 | |
|     Some callers passed the first argument in $v0, while others used $a0.
 | |
|     Change the callers to use $a0 consistently.
 | |
|     
 | |
|     Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
 | |
|     Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
 | |
| 
 | |
| --- a/libc/sysdeps/linux/mips/vfork.S
 | |
| +++ b/libc/sysdeps/linux/mips/vfork.S
 | |
| @@ -84,6 +84,7 @@ NESTED(__vfork,FRAMESZ,sp)
 | |
|  
 | |
|  	/* Something bad happened -- no child created.  */
 | |
|  L(error):
 | |
| +	move	a0, v0
 | |
|  #ifdef __PIC__
 | |
|  	PTR_LA		t9, __syscall_error
 | |
|  	RESTORE_GP64
 | |
| --- a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h
 | |
| +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h
 | |
| @@ -31,7 +31,7 @@
 | |
|  # undef PSEUDO
 | |
|  # define PSEUDO(name, syscall_name, args)				      \
 | |
|    .align 2;								      \
 | |
| -  99:									      \
 | |
| +  99: move a0, v0; 							      \
 | |
|    PTR_LA t9,__syscall_error;					 	      \
 | |
|    /* manual cpreturn.  */						      \
 | |
|    REG_L gp, STKOFF_GP(sp);						      \
 | |
| --- a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/vfork.S
 | |
| +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/vfork.S
 | |
| @@ -80,6 +80,7 @@ NESTED(__vfork,FRAMESZ,sp)
 | |
|  
 | |
|  	/* Something bad happened -- no child created.  */
 | |
|  L(error):
 | |
| +	move		a0, v0
 | |
|  #ifdef __PIC__
 | |
|  	PTR_LA		t9, __syscall_error
 | |
|  	RESTORE_GP64
 | |
| --- a/libc/sysdeps/linux/mips/syscall_error.S
 | |
| +++ b/libc/sysdeps/linux/mips/syscall_error.S
 | |
| @@ -43,7 +43,7 @@ ENTRY(__syscall_error)
 | |
|  #ifdef __PIC__
 | |
|  	SAVE_GP(GPOFF)
 | |
|  #endif
 | |
| -	REG_S	v0, V0OFF(sp)
 | |
| +	REG_S	a0, V0OFF(sp)
 | |
|  	REG_S	ra, RAOFF(sp)
 | |
|  
 | |
|  	/* Find our per-thread errno address  */
 |