aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-03-31 09:25:27 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-03-31 09:25:27 -0700
commit8076e48f4e178830f6f9cdc1752ab8f4de1b19b3 (patch)
tree789ae6900808f21474a46e1cbab3269fc9b945e8
parent35dda1ebbb0c58dc76e3b534611c3bdcb06e2248 (diff)
downloadsyslinux.git-8076e48f4e178830f6f9cdc1752ab8f4de1b19b3.tar.gz
syslinux.git-8076e48f4e178830f6f9cdc1752ab8f4de1b19b3.tar.xz
syslinux.git-8076e48f4e178830f6f9cdc1752ab8f4de1b19b3.zip
shuffer: make the new shuffler not pollute unrelated memory
Keep the shuffler from polluting memory outside its own "safe area". This means being more clever about the relocation code, but it should make it a lot easier to use for our own uses. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--core/bcopyxx.inc58
1 files changed, 41 insertions, 17 deletions
diff --git a/core/bcopyxx.inc b/core/bcopyxx.inc
index aacf5a6d..cab02c5f 100644
--- a/core/bcopyxx.inc
+++ b/core/bcopyxx.inc
@@ -29,6 +29,17 @@
bits 32
section .bcopyxx
+ align 16
+bcopyxx_before:
+ ; target > source, need reverse copy
+ lea esi,[esi+ecx-4]
+ lea edi,[edx+ecx-4]
+ std
+ rep movsd
+ cld
+ jmp eax
+
+ align 4
bcopyxx_start equ $
;
; pm_bcopy:
@@ -188,28 +199,34 @@ pm_bcopy:
;
; If len == 0: this marks the end of the list; dst indicates
; the entry point and src the mode (0 = pm, 1 = rm)
+;
+;
+; Note: we're hideously strict with the relocation, so we never touch
+; any memory we don't need to. This is important for our own internal
+; use of the code.
+;
pm_shuffle:
+ mov edi,edx
mov esi,bcopyxx_start
- mov edi,bcopyxx_end
+ mov ecx,bcopyxx_dwords
+ lea eax,[edx+.safe-bcopyxx_start] ; Resume point
+ cmp edx,bcopyxx_end
+ jae .no_overlap ; Safe area start >= end
+ lea ebp,[edx+bcopyxx_len]
+ cmp edi,ebp
+ jae .no_overlap ; Safe area end <= start
cmp edx,esi
- je .safe ; This was too easy
- cmp edx,edi
- jae .at_end ; Safe area >= end
+ je .safe ; OK, this was too easy
- ; Safe area < end; we may have an overlap, so copy
- ; ourselves to a safe distance beyond the end...
- mov ecx,bcopyxx_dwords
- lea edi,[esi+ecx*8]
- mov eax,edi
- rep movsd
- mov esi,eax
- jmp .at_end+(8*bcopyxx_dwords) ; Relative jump, is safe
+ ; OK, we have some overlap one way or the other.
+ ; We bounce this to one of two routines *outside*
+ ; the safe area... one on each side.
+ ja bcopyxx_before ; target > source
+ jmp bcopyxx_after ; source > target
-.at_end:
- mov ecx,bcopyxx_dwords
- mov edi,edx
+.no_overlap:
+ ; No overlap, do the copying inside the safe area
rep movsd
- lea eax,[edx+.safe-bcopyxx_start]
jmp eax ; Jump to safe location
.safe:
; Give ourselves a safe stack
@@ -305,7 +322,7 @@ bcopy_gdt:
bcopy_gdt_size: equ $-bcopy_gdt
align 4, db 0
-bcopyxx_end equ $
+bcopyxx_end equ $ ; *Must* be dword-aligned!
bcopyxx_len equ $-bcopyxx_start
bcopyxx_dwords equ bcopyxx_len >> 2
@@ -319,5 +336,12 @@ bcopyxx_safe equ bcopyxx_len + bcopyxx_stack
;
DummyTSS equ 0x800
+ bits 32
+ align 4
+bcopyxx_after:
+ ; source > target, forward copy
+ rep movsd
+ jmp eax
+
bits 16
section .text