146 lines
		
	
	
	
		
			2.5 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
		
		
			
		
	
	
			146 lines
		
	
	
	
		
			2.5 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * arch/alpha/lib/copy_user.S
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copy to/from user space, handling exceptions as we go..  This
							 | 
						||
| 
								 | 
							
								 * isn't exactly pretty.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This is essentially the same as "memcpy()", but with a few twists.
							 | 
						||
| 
								 | 
							
								 * Notably, we have to make sure that $0 is always up-to-date and
							 | 
						||
| 
								 | 
							
								 * contains the right "bytes left to copy" value (and that it is updated
							 | 
						||
| 
								 | 
							
								 * only _after_ a successful copy). There is also some rather minor
							 | 
						||
| 
								 | 
							
								 * exception setup stuff..
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * NOTE! This is not directly C-callable, because the calling semantics are
							 | 
						||
| 
								 | 
							
								 * different:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Inputs:
							 | 
						||
| 
								 | 
							
								 *	length in $0
							 | 
						||
| 
								 | 
							
								 *	destination address in $6
							 | 
						||
| 
								 | 
							
								 *	source address in $7
							 | 
						||
| 
								 | 
							
								 *	return address in $28
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Outputs:
							 | 
						||
| 
								 | 
							
								 *	bytes left to copy in $0
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Clobbers:
							 | 
						||
| 
								 | 
							
								 *	$1,$2,$3,$4,$5,$6,$7
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Allow an exception for an insn; exit if we get one.  */
							 | 
						||
| 
								 | 
							
								#define EXI(x,y...)			\
							 | 
						||
| 
								 | 
							
									99: x,##y;			\
							 | 
						||
| 
								 | 
							
									.section __ex_table,"a";	\
							 | 
						||
| 
								 | 
							
									.long 99b - .;			\
							 | 
						||
| 
								 | 
							
									lda $31, $exitin-99b($31);	\
							 | 
						||
| 
								 | 
							
									.previous
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define EXO(x,y...)			\
							 | 
						||
| 
								 | 
							
									99: x,##y;			\
							 | 
						||
| 
								 | 
							
									.section __ex_table,"a";	\
							 | 
						||
| 
								 | 
							
									.long 99b - .;			\
							 | 
						||
| 
								 | 
							
									lda $31, $exitout-99b($31);	\
							 | 
						||
| 
								 | 
							
									.previous
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									.set noat
							 | 
						||
| 
								 | 
							
									.align 4
							 | 
						||
| 
								 | 
							
									.globl __copy_user
							 | 
						||
| 
								 | 
							
									.ent __copy_user
							 | 
						||
| 
								 | 
							
								__copy_user:
							 | 
						||
| 
								 | 
							
									.prologue 0
							 | 
						||
| 
								 | 
							
									and $6,7,$3
							 | 
						||
| 
								 | 
							
									beq $0,$35
							 | 
						||
| 
								 | 
							
									beq $3,$36
							 | 
						||
| 
								 | 
							
									subq $3,8,$3
							 | 
						||
| 
								 | 
							
									.align 4
							 | 
						||
| 
								 | 
							
								$37:
							 | 
						||
| 
								 | 
							
									EXI( ldq_u $1,0($7) )
							 | 
						||
| 
								 | 
							
									EXO( ldq_u $2,0($6) )
							 | 
						||
| 
								 | 
							
									extbl $1,$7,$1
							 | 
						||
| 
								 | 
							
									mskbl $2,$6,$2
							 | 
						||
| 
								 | 
							
									insbl $1,$6,$1
							 | 
						||
| 
								 | 
							
									addq $3,1,$3
							 | 
						||
| 
								 | 
							
									bis $1,$2,$1
							 | 
						||
| 
								 | 
							
									EXO( stq_u $1,0($6) )
							 | 
						||
| 
								 | 
							
									subq $0,1,$0
							 | 
						||
| 
								 | 
							
									addq $6,1,$6
							 | 
						||
| 
								 | 
							
									addq $7,1,$7
							 | 
						||
| 
								 | 
							
									beq $0,$41
							 | 
						||
| 
								 | 
							
									bne $3,$37
							 | 
						||
| 
								 | 
							
								$36:
							 | 
						||
| 
								 | 
							
									and $7,7,$1
							 | 
						||
| 
								 | 
							
									bic $0,7,$4
							 | 
						||
| 
								 | 
							
									beq $1,$43
							 | 
						||
| 
								 | 
							
									beq $4,$48
							 | 
						||
| 
								 | 
							
									EXI( ldq_u $3,0($7) )
							 | 
						||
| 
								 | 
							
									.align 4
							 | 
						||
| 
								 | 
							
								$50:
							 | 
						||
| 
								 | 
							
									EXI( ldq_u $2,8($7) )
							 | 
						||
| 
								 | 
							
									subq $4,8,$4
							 | 
						||
| 
								 | 
							
									extql $3,$7,$3
							 | 
						||
| 
								 | 
							
									extqh $2,$7,$1
							 | 
						||
| 
								 | 
							
									bis $3,$1,$1
							 | 
						||
| 
								 | 
							
									EXO( stq $1,0($6) )
							 | 
						||
| 
								 | 
							
									addq $7,8,$7
							 | 
						||
| 
								 | 
							
									subq $0,8,$0
							 | 
						||
| 
								 | 
							
									addq $6,8,$6
							 | 
						||
| 
								 | 
							
									bis $2,$2,$3
							 | 
						||
| 
								 | 
							
									bne $4,$50
							 | 
						||
| 
								 | 
							
								$48:
							 | 
						||
| 
								 | 
							
									beq $0,$41
							 | 
						||
| 
								 | 
							
									.align 4
							 | 
						||
| 
								 | 
							
								$57:
							 | 
						||
| 
								 | 
							
									EXI( ldq_u $1,0($7) )
							 | 
						||
| 
								 | 
							
									EXO( ldq_u $2,0($6) )
							 | 
						||
| 
								 | 
							
									extbl $1,$7,$1
							 | 
						||
| 
								 | 
							
									mskbl $2,$6,$2
							 | 
						||
| 
								 | 
							
									insbl $1,$6,$1
							 | 
						||
| 
								 | 
							
									bis $1,$2,$1
							 | 
						||
| 
								 | 
							
									EXO( stq_u $1,0($6) )
							 | 
						||
| 
								 | 
							
									subq $0,1,$0
							 | 
						||
| 
								 | 
							
									addq $6,1,$6
							 | 
						||
| 
								 | 
							
									addq $7,1,$7
							 | 
						||
| 
								 | 
							
									bne $0,$57
							 | 
						||
| 
								 | 
							
									br $31,$41
							 | 
						||
| 
								 | 
							
									.align 4
							 | 
						||
| 
								 | 
							
								$43:
							 | 
						||
| 
								 | 
							
									beq $4,$65
							 | 
						||
| 
								 | 
							
									.align 4
							 | 
						||
| 
								 | 
							
								$66:
							 | 
						||
| 
								 | 
							
									EXI( ldq $1,0($7) )
							 | 
						||
| 
								 | 
							
									subq $4,8,$4
							 | 
						||
| 
								 | 
							
									EXO( stq $1,0($6) )
							 | 
						||
| 
								 | 
							
									addq $7,8,$7
							 | 
						||
| 
								 | 
							
									subq $0,8,$0
							 | 
						||
| 
								 | 
							
									addq $6,8,$6
							 | 
						||
| 
								 | 
							
									bne $4,$66
							 | 
						||
| 
								 | 
							
								$65:
							 | 
						||
| 
								 | 
							
									beq $0,$41
							 | 
						||
| 
								 | 
							
									EXI( ldq $2,0($7) )
							 | 
						||
| 
								 | 
							
									EXO( ldq $1,0($6) )
							 | 
						||
| 
								 | 
							
									mskql $2,$0,$2
							 | 
						||
| 
								 | 
							
									mskqh $1,$0,$1
							 | 
						||
| 
								 | 
							
									bis $2,$1,$2
							 | 
						||
| 
								 | 
							
									EXO( stq $2,0($6) )
							 | 
						||
| 
								 | 
							
									bis $31,$31,$0
							 | 
						||
| 
								 | 
							
								$41:
							 | 
						||
| 
								 | 
							
								$35:
							 | 
						||
| 
								 | 
							
								$exitout:
							 | 
						||
| 
								 | 
							
									ret $31,($28),1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								$exitin:
							 | 
						||
| 
								 | 
							
									/* A stupid byte-by-byte zeroing of the rest of the output
							 | 
						||
| 
								 | 
							
									   buffer.  This cures security holes by never leaving 
							 | 
						||
| 
								 | 
							
									   random kernel data around to be copied elsewhere.  */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									mov $0,$1
							 | 
						||
| 
								 | 
							
								$101:
							 | 
						||
| 
								 | 
							
									EXO ( ldq_u $2,0($6) )
							 | 
						||
| 
								 | 
							
									subq $1,1,$1
							 | 
						||
| 
								 | 
							
									mskbl $2,$6,$2
							 | 
						||
| 
								 | 
							
									EXO ( stq_u $2,0($6) )
							 | 
						||
| 
								 | 
							
									addq $6,1,$6
							 | 
						||
| 
								 | 
							
									bgt $1,$101
							 | 
						||
| 
								 | 
							
									ret $31,($28),1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									.end __copy_user
							 |