The new InternalMemSetMem##() implementations for ARM and AARCH64 in BaseMemoryLibOptDxe fail to take into account that the 'length' argument is not in bytes, but in number of items to be copied. So multiply by the item size before proceeding. Reported-by: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Liming Gao <liming.gao@intel.com> Tested-by: Laszlo Ersek <lersek@redhat.com>
		
			
				
	
	
		
			97 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
| ;------------------------------------------------------------------------------
 | |
| ;
 | |
| ; Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
 | |
| ;
 | |
| ; This program and the accompanying materials are licensed and made available
 | |
| ; under the terms and conditions of the BSD License which accompanies this
 | |
| ; distribution.  The full text of the license may be found at
 | |
| ; http://opensource.org/licenses/bsd-license.php
 | |
| ;
 | |
| ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| ;
 | |
| ;------------------------------------------------------------------------------
 | |
| 
 | |
|     EXPORT  InternalMemZeroMem
 | |
|     EXPORT  InternalMemSetMem
 | |
|     EXPORT  InternalMemSetMem16
 | |
|     EXPORT  InternalMemSetMem32
 | |
|     EXPORT  InternalMemSetMem64
 | |
| 
 | |
|     AREA    SetMem, CODE, READONLY, CODEALIGN, ALIGN=5
 | |
|     THUMB
 | |
| 
 | |
| InternalMemSetMem16
 | |
|     uxth    r2, r2
 | |
|     lsl     r1, r1, #1
 | |
|     orr     r2, r2, r2, lsl #16
 | |
|     b       B0
 | |
| 
 | |
| InternalMemSetMem32
 | |
|     lsl     r1, r1, #2
 | |
|     b       B0
 | |
| 
 | |
| InternalMemSetMem64
 | |
|     lsl     r1, r1, #3
 | |
|     b       B1
 | |
| 
 | |
|     ALIGN   32
 | |
| InternalMemSetMem
 | |
|     uxtb    r2, r2
 | |
|     orr     r2, r2, r2, lsl #8
 | |
|     orr     r2, r2, r2, lsl #16
 | |
|     b       B0
 | |
| 
 | |
| InternalMemZeroMem
 | |
|     movs    r2, #0
 | |
| B0
 | |
|     mov     r3, r2
 | |
| 
 | |
| B1
 | |
|     push    {r4, lr}
 | |
|     cmp     r1, #16                 ; fewer than 16 bytes of input?
 | |
|     add     r1, r1, r0              ; r1 := dst + length
 | |
|     add     lr, r0, #16
 | |
|     blt     L2
 | |
|     bic     lr, lr, #15             ; align output pointer
 | |
| 
 | |
|     str     r2, [r0]                ; potentially unaligned store of 4 bytes
 | |
|     str     r3, [r0, #4]            ; potentially unaligned store of 4 bytes
 | |
|     str     r2, [r0, #8]            ; potentially unaligned store of 4 bytes
 | |
|     str     r3, [r0, #12]           ; potentially unaligned store of 4 bytes
 | |
|     beq     L1
 | |
| 
 | |
| L0
 | |
|     add     lr, lr, #16             ; advance the output pointer by 16 bytes
 | |
|     subs    r4, r1, lr              ; past the output?
 | |
|     blt     L3                      ; break out of the loop
 | |
|     strd    r2, r3, [lr, #-16]      ; aligned store of 16 bytes
 | |
|     strd    r2, r3, [lr, #-8]
 | |
|     bne     L0                      ; goto beginning of loop
 | |
| L1
 | |
|     pop     {r4, pc}
 | |
| 
 | |
| L2
 | |
|     subs    r4, r1, lr
 | |
| L3
 | |
|     adds    r4, r4, #16
 | |
|     subs    r1, r1, #8
 | |
|     cmp     r4, #4                  ; between 4 and 15 bytes?
 | |
|     blt     L4
 | |
|     cmp     r4, #8                  ; between 8 and 15 bytes?
 | |
|     str     r2, [lr, #-16]          ; overlapping store of 4 + (4 + 4) + 4 bytes
 | |
|     itt     gt
 | |
|     strgt   r3, [lr, #-12]
 | |
|     strgt   r2, [r1]
 | |
|     str     r3, [r1, #4]
 | |
|     pop     {r4, pc}
 | |
| 
 | |
| L4
 | |
|     cmp     r4, #2                  ; 2 or 3 bytes?
 | |
|     strb    r2, [lr, #-16]          ; store 1 byte
 | |
|     it      ge
 | |
|     strhge  r2, [r1, #6]            ; store 2 bytes
 | |
|     pop     {r4, pc}
 | |
| 
 | |
|     END
 |