installable hooks This patch "sets the stage" for the memdisk kernel to include different "installables": versions of the memdisk hooks. This patch splits the case of the EDD-compiled hook from the non-EDD-compiled hook. Both are available inside the kernel, and the kernel chooses which one to install based on the command-line. It''s possible that other, slightly modified versions of the memdisk hook could be useful to have... --- memdisk/Makefile | 9 +- memdisk/memdisk.asm | 988 +---------------------------------------------- memdisk/memdisk.inc | 987 ++++++++++++++++++++++++++++++++++++++++++++++ memdisk/memdisk_edd.asm | 2 + memdisk/setup.c | 28 +- 5 files changed, 1014 insertions(+), 1000 deletions(-) create mode 100644 memdisk/memdisk.inc create mode 100644 memdisk/memdisk_edd.asm diff --git a/memdisk/Makefile b/memdisk/Makefile index 3776731..b8cb91a 100644 --- a/memdisk/Makefile +++ b/memdisk/Makefile @@ -20,7 +20,7 @@ LDFLAGS =3D $(GCCOPT) -g INCLUDE =3D -I$(topdir)/com32/include NASM =3D nasm NASMOPT =3D -O9999 -NFLAGS =3D -dDATE=3D''"$(DATE)"'' -dWITH_EDD +NFLAGS =3D -dDATE=3D''"$(DATE)"'' NINCLUDE =3D =20 SRCS =3D $(wildcard *.asm *.c *.h) @@ -38,11 +38,11 @@ endif # Important: init.o16 must be first!! OBJS16 =3D init.o16 init32.o OBJS32 =3D start32.o setup.o msetup.o e820func.o conio.o memcpy.o memset.o \ - unzip.o memdisk.o + unzip.o memdisk.o memdisk_edd.o =20 CSRC =3D setup.c msetup.c e820func.c conio.c unzip.c SSRC =3D start32.S memcpy.S memset.S -NASMSRC =3D memdisk.asm memdisk16.asm +NASMSRC =3D memdisk.asm memdisk_edd.asm memdisk16.asm =20 all: memdisk # e820test =20 @@ -110,6 +110,9 @@ e820test: e820test.c e820func.c msetup.c memdisk.o: memdisk.bin $(LD) -r -b binary -o $@ $< =20 +memdisk_edd.o: memdisk_edd.bin + $(LD) -r -b binary -o $@ $< + .depend: rm -f .depend for csrc in *.c ; do $(CC) $(INCLUDE) $(CFLAGS) -MM $$csrc >> .depend ; done diff --git a/memdisk/memdisk.asm b/memdisk/memdisk.asm index 0d48961..daa5c0a 100644 --- a/memdisk/memdisk.asm +++ b/memdisk/memdisk.asm @@ -1,987 +1 @@ -; -*- fundamental -*- (asm-mode sucks) -; **************************************************************************** -; -; memdisk.asm -; -; A program to emulate an INT 13h disk BIOS from a "disk" in extended -; memory. -; -; Copyright 2001-2008 H. Peter Anvin - All Rights Reserved -; -; This program is free software; you can redistribute it and/or modify -; it under the terms of the GNU General Public License as published by -; the Free Software Foundation, Inc., 53 Temple Place Ste 330, -; Boston MA 02111-1307, USA; either version 2 of the License, or -; (at your option) any later version; incorporated herein by reference. -; -; **************************************************************************** - -%ifndef DEPEND -%include "../version.gen" -%endif - -; %define DEBUG_TRACERS ; Uncomment to get debugging tracers - -%ifdef WITH_EDD -%define EDD 1 -%else -%define EDD 0 -%endif - -%ifdef DEBUG_TRACERS - -%macro TRACER 1 - call debug_tracer - db %1 -%endmacro - -%else ; DEBUG_TRACERS - -%macro TRACER 1 -%endmacro - -%endif ; DEBUG_TRACERS - -%define CONFIG_READONLY 0x01 -%define CONFIG_RAW 0x02 -%define CONFIG_SAFEINT 0x04 -%define CONFIG_BIGRAW 0x08 ; MUST be 8! - - org 0h - -%define SECTORSIZE_LG2 9 ; log2(sector size) -%define SECTORSIZE (1 << SECTORSIZE_LG2) - - ; Parameter registers definition; this is the definition - ; of the stack frame. -%define P_DS word [bp+34] -%define P_ES word [bp+32] -%define P_EAX dword [bp+28] -%define P_HAX word [bp+30] -%define P_AX word [bp+28] -%define P_AL byte [bp+28] -%define P_AH byte [bp+29] -%define P_ECX dword [bp+24] -%define P_HCX word [bp+26] -%define P_CX word [bp+24] -%define P_CL byte [bp+24] -%define P_CH byte [bp+25] -%define P_EDX dword [bp+20] -%define P_HDX word [bp+22] -%define P_DX word [bp+20] -%define P_DL byte [bp+20] -%define P_DH byte [bp+21] -%define P_EBX dword [bp+16] -%define P_HBX word [bp+18] -%define P_HBXL byte [bp+18] -%define P_BX word [bp+16] -%define P_BL byte [bp+16] -%define P_BH byte [bp+17] -%define P_EBP dword [bp+8] -%define P_BP word [bp+8] -%define P_ESI dword [bp+4] -%define P_SI word [bp+4] -%define P_EDI dword [bp] -%define P_DI word [bp] - - section .text - ; These pointers are used by the installer and - ; must be first in the binary -Pointers: dw Int13Start - dw Int15Start - dw PatchArea - dw TotalSize - dw IretPtr - -IretPtr equ Int13Start.iret -Int13Start: - ; Swap stack - mov [cs:Stack],esp - mov [cs:SavedAX],ax - mov ax,ss - mov [cs:Stack+4],ax - mov ax,cs - mov ss,ax - mov sp,[cs:MyStack] - - ; See if DL points to our class of device (FD, HD) - push dx - push dx - xor dl,[cs:DriveNo] - pop dx - js .nomatch ; If SF=3D0, we have a class match here - jz .our_drive ; If ZF=3D1, we have an exact match - cmp dl,[cs:DriveNo] - jb .nomatch ; Drive < Our drive - dec dl ; Drive > Our drive, adjust drive # -.nomatch: - mov ax,[cs:SavedAX] - pushf - call far [cs:OldInt13] - pushf - push bp - mov bp,sp - cmp byte [cs:SavedAX+1],08h - je .norestoredl - cmp byte [cs:SavedAX+1],15h - jne .restoredl - test byte [bp+4],80h ; Hard disk? - jnz .norestoredl -.restoredl: - mov dl,[bp+4] -.norestoredl: - push ax - push ebx - push ds - mov ax,[bp+2] ; Flags - lds ebx,[cs:Stack] - mov [bx+4],al ; Arithmetric flags - pop ds - pop ebx - pop ax - pop bp - lss esp,[cs:Stack] -.iret: iret - -.our_drive: - ; Set up standard entry frame - push ds - push es - mov ds,ax - mov es,ax - mov ax,[SavedAX] - pushad - mov bp,sp ; Point BP to the entry stack frame - TRACER ''F'' - ; Note: AH =3D=3D P_AH here - cmp ah,[Int13MaxFunc] - ja Invalid_jump - xor al,al ; AL =3D 0 is standard entry condition - mov di,ax - shr di,7 ; Convert AH to an offset in DI - call [Int13Funcs+di] - -Done: ; Standard routine for return - mov P_AX,ax -DoneWeird: - TRACER ''D'' - xor bx,bx - mov es,bx - mov bx,[StatusPtr] - mov [es:bx],ah ; Save status - and ah,ah - - lds ebx,[Stack] - ; This sets the low byte (the arithmetric flags) of the - ; FLAGS on stack to either 00h (no flags) or 01h (CF) - ; depending on if AH was zero or not. - setnz [bx+4] ; Set CF iff error - popad - pop es - pop ds - lss esp,[cs:Stack] - iret - -Reset: - ; Reset affects multiple drives, so we need to pass it on - TRACER ''R'' - xor ax,ax ; Bottom of memory - mov es,ax - test dl,dl ; Always pass it on if we are resetting HD - js .hard_disk ; Bit 7 set - ; Some BIOSes get very unhappy if we pass a reset floppy - ; command to them and don''t actually have any floppies. - ; This is a bug, but we have to deal with it nontheless. - ; Therefore, if we are the *ONLY* floppy drive, and the - ; user didn''t request HD reset, then just drop the command. - ; BIOS equipment byte, top two bits + 1 =3D=3D total # of floppies - test byte [es:0x410],0C0h - jz success - jmp .pass_on ; ... otherwise pass it to the BIOS -.hard_disk: - ; ... same thing for hard disks, sigh ... - cmp byte [es:0x475],1 ; BIOS variable for number of hard disks - jbe success - -.pass_on: - pop ax ; Drop return address - popad ; Restore all registers - pop es - pop ds - lss esp,[cs:Stack] ; Restore the stack - and dl,80h ; Clear all but the type bit - jmp far [cs:OldInt13] - - -Invalid: - pop dx ; Drop return address -Invalid_jump: - TRACER ''I'' - mov ah,01h ; Unsupported function - jmp short Done - -GetDriveType: - test byte [DriveNo],80h - mov bl,02h ; Type 02h =3D floppy with changeline - jz .floppy - ; Hard disks only... - inc bx ; Type =3D 03h - mov dx,[DiskSize] ; Return the disk size in sectors - mov P_DX,dx - mov cx,[DiskSize+2] - mov P_CX,cx -.floppy: - mov P_AH,bl ; 02h floppy, 03h hard disk - pop ax ; Drop return address - xor ax,ax ; Success... - jmp DoneWeird ; But don''t stick it into P_AX - -GetStatus: - xor ax,ax - mov es,ax - mov bx,[StatusPtr] - mov ah,[bx] ; Copy last status - ret - -ReadMult: - TRACER ''m'' -Read: - TRACER ''R'' - call setup_regs -do_copy: - TRACER ''<'' - call bcopy - TRACER ''>'' - movzx ax,P_AL ; AH =3D 0, AL =3D transfer count - ret - -WriteMult: - TRACER ''M'' -Write: - TRACER ''W'' - test byte [ConfigFlags],CONFIG_READONLY - jnz .readonly - call setup_regs - xchg esi,edi ; Opposite direction of a Read! - jmp short do_copy -.readonly: mov ah,03h ; Write protected medium - ret - - ; Verify integrity; just bounds-check -Seek: -Verify: - call setup_regs ; Returns error if appropriate - ; And fall through to success - -CheckIfReady: ; These are always-successful noop functions -Recalibrate: -InitWithParms: -DetectChange: -EDDDetectChange: -EDDLock: -SetMode: -success: - xor ax,ax ; Always successful - ret - -GetParms: - TRACER ''G'' - mov dl,[DriveCnt] ; Cached data - mov P_DL,dl - test byte [DriveNo],80h - jnz .hd - mov P_DI,DPT - mov P_ES,cs - mov bl,[DriveType] - mov P_BL,bl -.hd: - mov ax,[Cylinders] - dec ax ; We report the highest #, not the count - xchg al,ah - shl al,6 - or al,[Sectors] - mov P_CX,ax - mov ax,[Heads] - dec ax - mov P_DH,al - - ; - ; Is this MEMDISK installation check? - ; - cmp P_HAX,''ME'' - jne .notic - cmp P_HCX,''MD'' - jne .notic - cmp P_HDX,''IS'' - jne .notic - cmp P_HBX,''K?'' - jne .notic - - ; MEMDISK installation check... - mov P_HAX,''!M'' - mov P_HCX,''EM'' - mov P_HDX,''DI'' - mov P_HBX,''SK'' - mov P_ES,cs - mov P_DI,MemDisk_Info - -.notic: - xor ax,ax - ret -; -; EDD functions -- only if enabled -; -%if EDD -EDDPresence: - TRACER ''E'' - TRACER ''c'' - - cmp P_BX,55AAh - jne Invalid - mov P_BX,0AA55h ; EDD signature - mov P_AX,03000h ; EDD 3.0 - mov P_CX,0003h ; Bit 0 - Fixed disk access subset - ; Bit 1 - Locking and ejecting subset - pop ax ; Drop return address - xor ax,ax ; Success - jmp DoneWeird ; Success, but AH !=3D 0, sigh... - -EDDRead: - TRACER ''E'' - TRACER ''r'' - - call edd_setup_regs - call bcopy - xor ax,ax - ret - -EDDWrite: - TRACER ''E'' - TRACER ''w'' - - call edd_setup_regs - xchg esi,edi - call bcopy - xor ax,ax - ret - -EDDVerify: -EDDSeek: - call edd_setup_regs ; Just bounds checking - xor ax,ax - ret - -EDDGetParms: - TRACER ''E'' - TRACER ''p'' - - mov es,P_DS - mov di,P_SI - mov si,EDD_DPT - - lodsw ; Length of our DPT - mov cx,[es:di] - cmp cx,26 ; Minimum size - jb .overrun - - cmp cx,ax - jb .oksize - mov cx,ax - -.oksize: - mov ax,cx - stosw - dec cx - dec cx - rep movsb - - xor ax,ax - ret - -.overrun: - mov ax,0100h - ret -%endif ; EDD - - ; Set up registers as for a "Read", and compares against disk size. - ; WARNING: This fails immediately, even if we can transfer some - ; sectors. This isn''t really the correct behaviour. -setup_regs: - - ; Convert a CHS address in P_CX/P_DH into an LBA in eax - ; CH =3D cyl[7:0] - ; CL[0:5] =3D sector (1-based) CL[7:6] =3D cyl[9:8] - ; DH =3D head - movzx ecx,P_CX - movzx ebx,cl ; Sector number - and bl,3Fh - dec ebx ; Sector number is 1-based - cmp bx,[Sectors] - jae .overrun - movzx edi,P_DH ; Head number - movzx eax,word [Heads] - cmp di,ax - jae .overrun - shr cl,6 - xchg cl,ch ; Now (E)CX <- cylinder number - mul ecx ; eax <- Heads*cyl# (edx <- 0) - add eax,edi - mul dword [Sectors] - add eax,ebx - ; Now eax =3D LBA, edx =3D 0 - - ; - ; setup_regs continues... - ; - ; Note: edi[31:16] and ecx[31:16] =3D 0 already - mov di,P_BX ; Get linear address of target buffer - mov cx,P_ES - shl ecx,4 - add edi,ecx ; EDI =3D address to fetch to - movzx ecx,P_AL ; Sector count - mov esi,eax - add eax,ecx ; LBA of final sector + 1 - shl esi,SECTORSIZE_LG2 ; LBA -> byte offset - add esi,[DiskBuf] ; Get address in high memory - cmp eax,[DiskSize] ; Check the high mark against limit - ja .overrun - shl ecx,SECTORSIZE_LG2-2 ; Convert count to dwords - ret - -.overrun: pop ax ; Drop setup_regs return address - mov ax,0200h ; Missing address mark - ret ; Return to Done - - ; Set up registers as for an EDD Read, and compares against disk size. -%if EDD -edd_setup_regs: - push es - mov si,P_SI ; DS:SI -> DAPA - mov es,P_DS - - mov dx,[es:si] - cmp dx,16 - jb .baddapa - - cmp dword [es:si+4],-1 - je .linear_address - - movzx ebx,word [es:si+4] ; Offset - movzx edi,word [es:si+6] ; Segment - shl edi,4 - add ebx,edi - jmp .got_address - -.linear_address: - cmp dx,24 ; Must be large enough to hold - ; linear address - jb .baddapa - - cmp dword [es:si+20],0 ; > 4 GB addresses not supported - mov ax,0900h ; "Data boundary error" - bogus, but - ; no really better code available - jne .error - - mov ebx,[es:si+16] - -.got_address: - cmp dword [es:si+12],0 ; LBA too large? - jne .overrun - - movzx ecx, word [es:si+2] ; Sectors to transfer - mov esi,[es:si+8] ; Starting sector - mov eax,esi - add eax,ecx - jc .overrun - cmp eax,[DiskSize] - ja .overrun - - shl ecx,SECTORSIZE_LG2-2 ; Convert to dwords - shl esi,SECTORSIZE_LG2 ; Convert to an offset - add esi,[DiskBuf] - mov edi,ebx - pop es - ret - -.baddapa: - mov ax,0100h ; Invalid command - pop es - pop ax ; Drop setup_regs return address - ret - -.overrun: - mov ax,0200h ; "Address mark not found" =3D - ; LBA beyond end of disk -.error: - and word [es:si+2],0 ; No sectors transferred - pop es - pop ax - ret - -EDDEject: - mov ax,0B200h ; Volume Not Removable - ret - -%endif ; EDD - - -; -; INT 15h intercept routines -; -int15_e820: - cmp edx,534D4150h ; "SMAP" - jne oldint15 - cmp ecx,20 ; Need 20 bytes - jb err86 - push ds - push cs - pop ds - push edx ; "SMAP" - and ebx,ebx - jne .renew - mov ebx,E820Table -.renew: - add bx,16 ; Advance to next - mov eax,[bx-8] ; Type - and eax,eax ; Null type? - jz .renew ; If so advance to next - mov [es:di+16],eax - and cl,~3 - cmp ecx,24 - jb .no_extattr - mov eax,[bx-4] ; Extended attributes - mov [es:di+20],eax - mov ecx,24 ; Bytes loaded -.no_extattr: - mov eax,[bx-16] ; Start addr (low) - mov edx,[bx-12] ; Start addr (high) - mov [es:di],eax - mov [es:di+4],edx - mov eax,[bx] ; End addr (low) - mov edx,[bx+4] ; End addr (high) - sub eax,[bx-16] ; Derive the length - sbb edx,[bx-12] - mov [es:di+8],eax ; Length (low) - mov [es:di+12],edx ; Length (high) - cmp dword [bx+8],-1 ; Type of next =3D end? - jne .notdone - xor ebx,ebx ; Done with table -.notdone: - pop eax ; "SMAP" - mov edx,eax ; Some systems expect eax =3D edx =3D SMAP - pop ds -int15_success: - mov byte [bp+6], 02h ; Clear CF - pop bp - iret - -err86: - mov byte [bp+6], 03h ; Set CF - mov ah,86h - pop bp - iret - -Int15Start: - push bp - mov bp,sp - cmp ax,0E820h - je near int15_e820 - cmp ax,0E801h - je int15_e801 - cmp ax,0E881h - je int15_e881 - cmp ah,88h - je int15_88 -oldint15: pop bp - jmp far [cs:OldInt15] - -int15_e801: - mov ax,[cs:Mem1MB] - mov cx,ax - mov bx,[cs:Mem16MB] - mov dx,bx - jmp short int15_success - -int15_e881: - mov eax,[cs:Mem1MB] - mov ecx,eax - mov ebx,[cs:Mem16MB] - mov edx,ebx - jmp short int15_success - -int15_88: - mov ax,[cs:MemInt1588] - jmp short int15_success - -; -; Routine to copy in/out of high memory -; esi =3D linear source address -; edi =3D linear target address -; ecx =3D 32-bit word count -; -; Assumes cs =3D ds =3D es -; -bcopy: - push eax - push ebx - push edx - push ebp - - mov bx, real_int15_stub - - test byte [ConfigFlags], CONFIG_RAW|CONFIG_SAFEINT - jz .anymode ; Always do the real INT 15h - - smsw ax ; Unprivileged! - test al,01h - jnz .protmode ; Protmode -> do real INT 15h - -.realmode: - ; Raw or Safeint mode, and we''re in real mode... - - test byte [ConfigFlags], CONFIG_SAFEINT - jnz .fakeint15 - -.raw: - TRACER ''r'' - ; We''re in real mode, do it outselves - - pushfd ; <A> - push ds ; <B> - push es ; <C> - - cli - cld - - xor ebx,ebx - mov bx,cs - shl ebx,4 - lea edx,[Shaker+ebx] - mov [Shaker+2],edx - - ; Test to see if A20 is enabled or not - xor ax,ax - mov ds,ax - dec ax - mov es,ax - - mov ax,[0] - mov bx,ax - xor bx,[es:10h] - not ax - mov [0],ax - mov dx,ax - xor dx,[es:10h] - not ax - mov [0],ax - - or dx,bx - push dx ; <D> Save A20 status - jnz .skip_a20e - - mov ax,2401h ; Enable A20 - int 15h -.skip_a20e: - mov dl,[ConfigFlags] - and dx,CONFIG_BIGRAW - add dx,8 - ; DX =3D 16 for BIGRAW, 8 for RAW - ; 8 is selector for a 64K flat segment, - ; 16 is selector for a 4GB flat segment. - - lgdt [cs:Shaker] - mov eax,cr0 - or al,01h - mov cr0,eax - - mov bx,16 ; Large flat segment - mov ds,bx - mov es,bx - - a32 rep movsd - - ; DX has the appropriate value to put in - ; the registers on return - mov ds,dx - mov es,dx - - and al,~01h - mov cr0,eax - - pop dx ; <D> A20 status - pop es ; <C> - pop ds ; <B> - - and dx,dx - jnz .skip_a20d - mov ax,2400h ; Disable A20 - int 15h -.skip_a20d: - popfd ; <A> - jmp .done - -.fakeint15: - ; We''re in real mode with CONFIG_SAFEINT, invoke the - ; original INT 15h vector. We used to test for the - ; INT 15h vector being unchanged here, but that is - ; *us*; however, the test was wrong for years (always - ; negative) so instead of fixing the test do what we - ; tested and don''t bother probing. - mov bx, fake_int15_stub - -.protmode: - TRACER ''p'' -.anymode: - -.copy_loop: - push esi - push edi - push ecx - cmp ecx,4000h - jna .safe_size - mov ecx,4000h -.safe_size: - push ecx ; Transfer size this cycle - mov eax, esi - mov [Mover_src1], si - shr eax, 16 - mov [Mover_src1+2], al - mov [Mover_src2], ah - mov eax, edi - mov [Mover_dst1], di - shr eax, 16 - mov [Mover_dst1+2], al - mov [Mover_dst2], ah - mov si,Mover - mov ah, 87h - shl cx,1 ; Convert to 16-bit words - call bx ; INT 15h stub - pop eax ; Transfer size this cycle - pop ecx - pop edi - pop esi - jc .error - lea esi,[esi+4*eax] - lea edi,[edi+4*eax] - sub ecx, eax - jnz .copy_loop - ; CF =3D 0 -.error: -.done: - pop ebp - pop edx - pop ebx - pop eax - ret - -real_int15_stub: - int 15h - cli ; Some BIOSes enable interrupts on INT 15h - ret - -fake_int15_stub: - pushf - call far [OldInt15] - cli - ret - -%ifdef DEBUG_TRACERS -debug_tracer: pushad - pushfd - mov bp,sp - mov bx,[bp+9*4] - mov al,[cs:bx] - inc word [bp+9*4] - mov ah,0Eh - mov bx,7 - int 10h - popfd - popad - ret -%endif - - section .data - alignb 2 -Int13Funcs dw Reset ; 00h - RESET - dw GetStatus ; 01h - GET STATUS - dw Read ; 02h - READ - dw Write ; 03h - WRITE - dw Verify ; 04h - VERIFY - dw Invalid ; 05h - FORMAT TRACK - dw Invalid ; 06h - FORMAT TRACK AND SET BAD FLAGS - dw Invalid ; 07h - FORMAT DRIVE AT TRACK - dw GetParms ; 08h - GET PARAMETERS - dw InitWithParms ; 09h - INITIALIZE CONTROLLER WITH DRIVE PARAMETERS - dw Invalid ; 0Ah - dw Invalid ; 0Bh - dw Seek ; 0Ch - SEEK TO CYLINDER - dw Reset ; 0Dh - RESET HARD DISKS - dw Invalid ; 0Eh - dw Invalid ; 0Fh - dw CheckIfReady ; 10h - CHECK IF READY - dw Recalibrate ; 11h - RECALIBRATE - dw Invalid ; 12h - dw Invalid ; 13h - dw Invalid ; 14h - dw GetDriveType ; 15h - GET DRIVE TYPE - dw DetectChange ; 16h - DETECT DRIVE CHANGE -%if EDD - dw Invalid ; 17h - dw Invalid ; 18h - dw Invalid ; 19h - dw Invalid ; 1Ah - dw Invalid ; 1Bh - dw Invalid ; 1Ch - dw Invalid ; 1Dh - dw Invalid ; 1Eh - dw Invalid ; 1Fh - dw Invalid ; 20h - dw ReadMult ; 21h - READ MULTIPLE - dw WriteMult ; 22h - WRITE MULTIPLE - dw SetMode ; 23h - SET CONTROLLER FEATURES - dw SetMode ; 24h - SET MULTIPLE MODE - dw Invalid ; 25h - IDENTIFY DRIVE - dw Invalid ; 26h - dw Invalid ; 27h - dw Invalid ; 28h - dw Invalid ; 29h - dw Invalid ; 2Ah - dw Invalid ; 2Bh - dw Invalid ; 2Ch - dw Invalid ; 2Dh - dw Invalid ; 2Eh - dw Invalid ; 2Fh - dw Invalid ; 30h - dw Invalid ; 31h - dw Invalid ; 32h - dw Invalid ; 33h - dw Invalid ; 34h - dw Invalid ; 35h - dw Invalid ; 36h - dw Invalid ; 37h - dw Invalid ; 38h - dw Invalid ; 39h - dw Invalid ; 3Ah - dw Invalid ; 3Bh - dw Invalid ; 3Ch - dw Invalid ; 3Dh - dw Invalid ; 3Eh - dw Invalid ; 3Fh - dw Invalid ; 40h - dw EDDPresence ; 41h - EDD PRESENCE DETECT - dw EDDRead ; 42h - EDD READ - dw EDDWrite ; 43h - EDD WRITE - dw EDDVerify ; 44h - EDD VERIFY - dw EDDLock ; 45h - EDD LOCK/UNLOCK MEDIA - dw EDDEject ; 46h - EDD EJECT - dw EDDSeek ; 47h - EDD SEEK - dw EDDGetParms ; 48h - EDD GET PARAMETERS - dw EDDDetectChange ; 49h - EDD MEDIA CHANGE STATUS -%endif - -Int13FuncsEnd equ $ -Int13FuncsCnt equ (Int13FuncsEnd-Int13Funcs) >> 1 - - - alignb 8, db 0 -Shaker dw ShakerEnd-$ - dd 0 ; Pointer to self - dw 0 - -Shaker_RMDS: dd 0x0000ffff ; 64K data segment - dd 0x00009300 - -Shaker_DS: dd 0x0000ffff ; 4GB data segment - dd 0x008f9300 - -ShakerEnd equ $ - - alignb 8, db 0 - -Mover dd 0, 0, 0, 0 ; Must be zero - dw 0ffffh ; 64 K segment size -Mover_src1: db 0, 0, 0 ; Low 24 bits of source addy - db 93h ; Access rights - db 00h ; Extended access rights -Mover_src2: db 0 ; High 8 bits of source addy - dw 0ffffh ; 64 K segment size -Mover_dst1: db 0, 0, 0 ; Low 24 bits of target addy - db 93h ; Access rights - db 00h ; Extended access rights -Mover_dst2: db 0 ; High 8 bits of source addy -Mover_dummy2: dd 0, 0, 0, 0 ; More space for the BIOS - - alignb 4, db 0 -MemDisk_Info equ $ ; Pointed to by installation check -MDI_Bytes dw MDI_Len ; Total bytes in MDI structure -MDI_Version db VERSION_MINOR, VERSION_MAJOR ; MEMDISK version - -PatchArea equ $ ; This gets filled in by the installer - -DiskBuf dd 0 ; Linear address of high memory disk -DiskSize dd 0 ; Size of disk in blocks -CommandLine dw 0, 0 ; Far pointer to saved command line - -OldInt13 dd 0 ; INT 13h in chain -OldInt15 dd 0 ; INT 15h in chain - -OldDosMem dw 0 ; Old position of DOS mem end -BootLoaderID db 0 ; Boot loader ID from header - db 0 ; pad - -DPT_ptr dw 0 ; If nonzero, pointer to DPT - ; Original DPT pointer follows - -MDI_Len equ $-MemDisk_Info - -; ---- MDI structure ends here --- -Int13MaxFunc db Int13FuncsCnt-1 ; Max INT 13h function (to disable EDD) - db 0 ; pad - - dw 0 ; pad -MemInt1588 dw 0 ; 1MB-65MB memory amount (1K) - -Cylinders dw 0 ; Cylinder count -Heads dw 0 ; Head count -Sectors dd 0 ; Sector count (zero-extended) - -Mem1MB dd 0 ; 1MB-16MB memory amount (1K) -Mem16MB dd 0 ; 16MB-4G memory amount (64K) - -DriveNo db 0 ; Our drive number -DriveType db 0 ; Our drive type (floppies) -DriveCnt db 0 ; Drive count (from the BIOS) - -ConfigFlags db 0 ; Bit 0 - readonly - -MyStack dw 0 ; Offset of stack -StatusPtr dw 0 ; Where to save status (zeroseg ptr) - -DPT times 16 db 0 ; BIOS parameter table pointer (floppies) -OldInt1E dd 0 ; Previous INT 1E pointer (DPT) - -%if EDD -EDD_DPT: -.length dw 30 -.info dw 0029h - ; Bit 0 - DMA boundaries handled transparently - ; Bit 3 - Device supports write verify - ; Bit 5 - Media is lockable -.cylinders dd 0 ; Filled in by installer -.heads dd 0 ; Filled in by installer -.sectors dd 0 ; Filled in by installer -.totalsize dd 0, 0 ; Filled in by installer -.bytespersec dw SECTORSIZE -.eddtable dw -1, -1 ; Invalid DPTE pointer - -%endif - - ; End patch area -Stack dd 0 ; Saved SS:ESP on invocation - dw 0 -SavedAX dw 0 ; AX saved on invocation - - alignb 4, db 0 ; We *MUST* end on a dword boundary - -E820Table equ $ ; The installer loads the E820 table here -TotalSize equ $ ; End pointer +%include "memdisk.inc" diff --git a/memdisk/memdisk.inc b/memdisk/memdisk.inc new file mode 100644 index 0000000..2b5b4e0 --- /dev/null +++ b/memdisk/memdisk.inc @@ -0,0 +1,987 @@ +; -*- fundamental -*- (asm-mode sucks) +; **************************************************************************** +; +; memdisk.inc +; +; A program to emulate an INT 13h disk BIOS from a "disk" in extended +; memory. +; +; Copyright 2001-2008 H. Peter Anvin - All Rights Reserved +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, Inc., 53 Temple Place Ste 330, +; Boston MA 02111-1307, USA; either version 2 of the License, or +; (at your option) any later version; incorporated herein by reference. +; +; **************************************************************************** + +%ifndef DEPEND +%include "../version.gen" +%endif + +; %define DEBUG_TRACERS ; Uncomment to get debugging tracers + +%ifdef WITH_EDD +%define EDD 1 +%else +%define EDD 0 +%endif + +%ifdef DEBUG_TRACERS + +%macro TRACER 1 + call debug_tracer + db %1 +%endmacro + +%else ; DEBUG_TRACERS + +%macro TRACER 1 +%endmacro + +%endif ; DEBUG_TRACERS + +%define CONFIG_READONLY 0x01 +%define CONFIG_RAW 0x02 +%define CONFIG_SAFEINT 0x04 +%define CONFIG_BIGRAW 0x08 ; MUST be 8! + + org 0h + +%define SECTORSIZE_LG2 9 ; log2(sector size) +%define SECTORSIZE (1 << SECTORSIZE_LG2) + + ; Parameter registers definition; this is the definition + ; of the stack frame. +%define P_DS word [bp+34] +%define P_ES word [bp+32] +%define P_EAX dword [bp+28] +%define P_HAX word [bp+30] +%define P_AX word [bp+28] +%define P_AL byte [bp+28] +%define P_AH byte [bp+29] +%define P_ECX dword [bp+24] +%define P_HCX word [bp+26] +%define P_CX word [bp+24] +%define P_CL byte [bp+24] +%define P_CH byte [bp+25] +%define P_EDX dword [bp+20] +%define P_HDX word [bp+22] +%define P_DX word [bp+20] +%define P_DL byte [bp+20] +%define P_DH byte [bp+21] +%define P_EBX dword [bp+16] +%define P_HBX word [bp+18] +%define P_HBXL byte [bp+18] +%define P_BX word [bp+16] +%define P_BL byte [bp+16] +%define P_BH byte [bp+17] +%define P_EBP dword [bp+8] +%define P_BP word [bp+8] +%define P_ESI dword [bp+4] +%define P_SI word [bp+4] +%define P_EDI dword [bp] +%define P_DI word [bp] + + section .text + ; These pointers are used by the installer and + ; must be first in the binary +Pointers: dw Int13Start + dw Int15Start + dw PatchArea + dw TotalSize + dw IretPtr + +IretPtr equ Int13Start.iret +Int13Start: + ; Swap stack + mov [cs:Stack],esp + mov [cs:SavedAX],ax + mov ax,ss + mov [cs:Stack+4],ax + mov ax,cs + mov ss,ax + mov sp,[cs:MyStack] + + ; See if DL points to our class of device (FD, HD) + push dx + push dx + xor dl,[cs:DriveNo] + pop dx + js .nomatch ; If SF=3D0, we have a class match here + jz .our_drive ; If ZF=3D1, we have an exact match + cmp dl,[cs:DriveNo] + jb .nomatch ; Drive < Our drive + dec dl ; Drive > Our drive, adjust drive # +.nomatch: + mov ax,[cs:SavedAX] + pushf + call far [cs:OldInt13] + pushf + push bp + mov bp,sp + cmp byte [cs:SavedAX+1],08h + je .norestoredl + cmp byte [cs:SavedAX+1],15h + jne .restoredl + test byte [bp+4],80h ; Hard disk? + jnz .norestoredl +.restoredl: + mov dl,[bp+4] +.norestoredl: + push ax + push ebx + push ds + mov ax,[bp+2] ; Flags + lds ebx,[cs:Stack] + mov [bx+4],al ; Arithmetric flags + pop ds + pop ebx + pop ax + pop bp + lss esp,[cs:Stack] +.iret: iret + +.our_drive: + ; Set up standard entry frame + push ds + push es + mov ds,ax + mov es,ax + mov ax,[SavedAX] + pushad + mov bp,sp ; Point BP to the entry stack frame + TRACER ''F'' + ; Note: AH =3D=3D P_AH here + cmp ah,[Int13MaxFunc] + ja Invalid_jump + xor al,al ; AL =3D 0 is standard entry condition + mov di,ax + shr di,7 ; Convert AH to an offset in DI + call [Int13Funcs+di] + +Done: ; Standard routine for return + mov P_AX,ax +DoneWeird: + TRACER ''D'' + xor bx,bx + mov es,bx + mov bx,[StatusPtr] + mov [es:bx],ah ; Save status + and ah,ah + + lds ebx,[Stack] + ; This sets the low byte (the arithmetric flags) of the + ; FLAGS on stack to either 00h (no flags) or 01h (CF) + ; depending on if AH was zero or not. + setnz [bx+4] ; Set CF iff error + popad + pop es + pop ds + lss esp,[cs:Stack] + iret + +Reset: + ; Reset affects multiple drives, so we need to pass it on + TRACER ''R'' + xor ax,ax ; Bottom of memory + mov es,ax + test dl,dl ; Always pass it on if we are resetting HD + js .hard_disk ; Bit 7 set + ; Some BIOSes get very unhappy if we pass a reset floppy + ; command to them and don''t actually have any floppies. + ; This is a bug, but we have to deal with it nontheless. + ; Therefore, if we are the *ONLY* floppy drive, and the + ; user didn''t request HD reset, then just drop the command. + ; BIOS equipment byte, top two bits + 1 =3D=3D total # of floppies + test byte [es:0x410],0C0h + jz success + jmp .pass_on ; ... otherwise pass it to the BIOS +.hard_disk: + ; ... same thing for hard disks, sigh ... + cmp byte [es:0x475],1 ; BIOS variable for number of hard disks + jbe success + +.pass_on: + pop ax ; Drop return address + popad ; Restore all registers + pop es + pop ds + lss esp,[cs:Stack] ; Restore the stack + and dl,80h ; Clear all but the type bit + jmp far [cs:OldInt13] + + +Invalid: + pop dx ; Drop return address +Invalid_jump: + TRACER ''I'' + mov ah,01h ; Unsupported function + jmp short Done + +GetDriveType: + test byte [DriveNo],80h + mov bl,02h ; Type 02h =3D floppy with changeline + jz .floppy + ; Hard disks only... + inc bx ; Type =3D 03h + mov dx,[DiskSize] ; Return the disk size in sectors + mov P_DX,dx + mov cx,[DiskSize+2] + mov P_CX,cx +.floppy: + mov P_AH,bl ; 02h floppy, 03h hard disk + pop ax ; Drop return address + xor ax,ax ; Success... + jmp DoneWeird ; But don''t stick it into P_AX + +GetStatus: + xor ax,ax + mov es,ax + mov bx,[StatusPtr] + mov ah,[bx] ; Copy last status + ret + +ReadMult: + TRACER ''m'' +Read: + TRACER ''R'' + call setup_regs +do_copy: + TRACER ''<'' + call bcopy + TRACER ''>'' + movzx ax,P_AL ; AH =3D 0, AL =3D transfer count + ret + +WriteMult: + TRACER ''M'' +Write: + TRACER ''W'' + test byte [ConfigFlags],CONFIG_READONLY + jnz .readonly + call setup_regs + xchg esi,edi ; Opposite direction of a Read! + jmp short do_copy +.readonly: mov ah,03h ; Write protected medium + ret + + ; Verify integrity; just bounds-check +Seek: +Verify: + call setup_regs ; Returns error if appropriate + ; And fall through to success + +CheckIfReady: ; These are always-successful noop functions +Recalibrate: +InitWithParms: +DetectChange: +EDDDetectChange: +EDDLock: +SetMode: +success: + xor ax,ax ; Always successful + ret + +GetParms: + TRACER ''G'' + mov dl,[DriveCnt] ; Cached data + mov P_DL,dl + test byte [DriveNo],80h + jnz .hd + mov P_DI,DPT + mov P_ES,cs + mov bl,[DriveType] + mov P_BL,bl +.hd: + mov ax,[Cylinders] + dec ax ; We report the highest #, not the count + xchg al,ah + shl al,6 + or al,[Sectors] + mov P_CX,ax + mov ax,[Heads] + dec ax + mov P_DH,al + + ; + ; Is this MEMDISK installation check? + ; + cmp P_HAX,''ME'' + jne .notic + cmp P_HCX,''MD'' + jne .notic + cmp P_HDX,''IS'' + jne .notic + cmp P_HBX,''K?'' + jne .notic + + ; MEMDISK installation check... + mov P_HAX,''!M'' + mov P_HCX,''EM'' + mov P_HDX,''DI'' + mov P_HBX,''SK'' + mov P_ES,cs + mov P_DI,MemDisk_Info + +.notic: + xor ax,ax + ret +; +; EDD functions -- only if enabled +; +%if EDD +EDDPresence: + TRACER ''E'' + TRACER ''c'' + + cmp P_BX,55AAh + jne Invalid + mov P_BX,0AA55h ; EDD signature + mov P_AX,03000h ; EDD 3.0 + mov P_CX,0003h ; Bit 0 - Fixed disk access subset + ; Bit 1 - Locking and ejecting subset + pop ax ; Drop return address + xor ax,ax ; Success + jmp DoneWeird ; Success, but AH !=3D 0, sigh... + +EDDRead: + TRACER ''E'' + TRACER ''r'' + + call edd_setup_regs + call bcopy + xor ax,ax + ret + +EDDWrite: + TRACER ''E'' + TRACER ''w'' + + call edd_setup_regs + xchg esi,edi + call bcopy + xor ax,ax + ret + +EDDVerify: +EDDSeek: + call edd_setup_regs ; Just bounds checking + xor ax,ax + ret + +EDDGetParms: + TRACER ''E'' + TRACER ''p'' + + mov es,P_DS + mov di,P_SI + mov si,EDD_DPT + + lodsw ; Length of our DPT + mov cx,[es:di] + cmp cx,26 ; Minimum size + jb .overrun + + cmp cx,ax + jb .oksize + mov cx,ax + +.oksize: + mov ax,cx + stosw + dec cx + dec cx + rep movsb + + xor ax,ax + ret + +.overrun: + mov ax,0100h + ret +%endif ; EDD + + ; Set up registers as for a "Read", and compares against disk size. + ; WARNING: This fails immediately, even if we can transfer some + ; sectors. This isn''t really the correct behaviour. +setup_regs: + + ; Convert a CHS address in P_CX/P_DH into an LBA in eax + ; CH =3D cyl[7:0] + ; CL[0:5] =3D sector (1-based) CL[7:6] =3D cyl[9:8] + ; DH =3D head + movzx ecx,P_CX + movzx ebx,cl ; Sector number + and bl,3Fh + dec ebx ; Sector number is 1-based + cmp bx,[Sectors] + jae .overrun + movzx edi,P_DH ; Head number + movzx eax,word [Heads] + cmp di,ax + jae .overrun + shr cl,6 + xchg cl,ch ; Now (E)CX <- cylinder number + mul ecx ; eax <- Heads*cyl# (edx <- 0) + add eax,edi + mul dword [Sectors] + add eax,ebx + ; Now eax =3D LBA, edx =3D 0 + + ; + ; setup_regs continues... + ; + ; Note: edi[31:16] and ecx[31:16] =3D 0 already + mov di,P_BX ; Get linear address of target buffer + mov cx,P_ES + shl ecx,4 + add edi,ecx ; EDI =3D address to fetch to + movzx ecx,P_AL ; Sector count + mov esi,eax + add eax,ecx ; LBA of final sector + 1 + shl esi,SECTORSIZE_LG2 ; LBA -> byte offset + add esi,[DiskBuf] ; Get address in high memory + cmp eax,[DiskSize] ; Check the high mark against limit + ja .overrun + shl ecx,SECTORSIZE_LG2-2 ; Convert count to dwords + ret + +.overrun: pop ax ; Drop setup_regs return address + mov ax,0200h ; Missing address mark + ret ; Return to Done + + ; Set up registers as for an EDD Read, and compares against disk size. +%if EDD +edd_setup_regs: + push es + mov si,P_SI ; DS:SI -> DAPA + mov es,P_DS + + mov dx,[es:si] + cmp dx,16 + jb .baddapa + + cmp dword [es:si+4],-1 + je .linear_address + + movzx ebx,word [es:si+4] ; Offset + movzx edi,word [es:si+6] ; Segment + shl edi,4 + add ebx,edi + jmp .got_address + +.linear_address: + cmp dx,24 ; Must be large enough to hold + ; linear address + jb .baddapa + + cmp dword [es:si+20],0 ; > 4 GB addresses not supported + mov ax,0900h ; "Data boundary error" - bogus, but + ; no really better code available + jne .error + + mov ebx,[es:si+16] + +.got_address: + cmp dword [es:si+12],0 ; LBA too large? + jne .overrun + + movzx ecx, word [es:si+2] ; Sectors to transfer + mov esi,[es:si+8] ; Starting sector + mov eax,esi + add eax,ecx + jc .overrun + cmp eax,[DiskSize] + ja .overrun + + shl ecx,SECTORSIZE_LG2-2 ; Convert to dwords + shl esi,SECTORSIZE_LG2 ; Convert to an offset + add esi,[DiskBuf] + mov edi,ebx + pop es + ret + +.baddapa: + mov ax,0100h ; Invalid command + pop es + pop ax ; Drop setup_regs return address + ret + +.overrun: + mov ax,0200h ; "Address mark not found" =3D + ; LBA beyond end of disk +.error: + and word [es:si+2],0 ; No sectors transferred + pop es + pop ax + ret + +EDDEject: + mov ax,0B200h ; Volume Not Removable + ret + +%endif ; EDD + + +; +; INT 15h intercept routines +; +int15_e820: + cmp edx,534D4150h ; "SMAP" + jne oldint15 + cmp ecx,20 ; Need 20 bytes + jb err86 + push ds + push cs + pop ds + push edx ; "SMAP" + and ebx,ebx + jne .renew + mov ebx,E820Table +.renew: + add bx,16 ; Advance to next + mov eax,[bx-8] ; Type + and eax,eax ; Null type? + jz .renew ; If so advance to next + mov [es:di+16],eax + and cl,~3 + cmp ecx,24 + jb .no_extattr + mov eax,[bx-4] ; Extended attributes + mov [es:di+20],eax + mov ecx,24 ; Bytes loaded +.no_extattr: + mov eax,[bx-16] ; Start addr (low) + mov edx,[bx-12] ; Start addr (high) + mov [es:di],eax + mov [es:di+4],edx + mov eax,[bx] ; End addr (low) + mov edx,[bx+4] ; End addr (high) + sub eax,[bx-16] ; Derive the length + sbb edx,[bx-12] + mov [es:di+8],eax ; Length (low) + mov [es:di+12],edx ; Length (high) + cmp dword [bx+8],-1 ; Type of next =3D end? + jne .notdone + xor ebx,ebx ; Done with table +.notdone: + pop eax ; "SMAP" + mov edx,eax ; Some systems expect eax =3D edx =3D SMAP + pop ds +int15_success: + mov byte [bp+6], 02h ; Clear CF + pop bp + iret + +err86: + mov byte [bp+6], 03h ; Set CF + mov ah,86h + pop bp + iret + +Int15Start: + push bp + mov bp,sp + cmp ax,0E820h + je near int15_e820 + cmp ax,0E801h + je int15_e801 + cmp ax,0E881h + je int15_e881 + cmp ah,88h + je int15_88 +oldint15: pop bp + jmp far [cs:OldInt15] + +int15_e801: + mov ax,[cs:Mem1MB] + mov cx,ax + mov bx,[cs:Mem16MB] + mov dx,bx + jmp short int15_success + +int15_e881: + mov eax,[cs:Mem1MB] + mov ecx,eax + mov ebx,[cs:Mem16MB] + mov edx,ebx + jmp short int15_success + +int15_88: + mov ax,[cs:MemInt1588] + jmp short int15_success + +; +; Routine to copy in/out of high memory +; esi =3D linear source address +; edi =3D linear target address +; ecx =3D 32-bit word count +; +; Assumes cs =3D ds =3D es +; +bcopy: + push eax + push ebx + push edx + push ebp + + mov bx, real_int15_stub + + test byte [ConfigFlags], CONFIG_RAW|CONFIG_SAFEINT + jz .anymode ; Always do the real INT 15h + + smsw ax ; Unprivileged! + test al,01h + jnz .protmode ; Protmode -> do real INT 15h + +.realmode: + ; Raw or Safeint mode, and we''re in real mode... + + test byte [ConfigFlags], CONFIG_SAFEINT + jnz .fakeint15 + +.raw: + TRACER ''r'' + ; We''re in real mode, do it outselves + + pushfd ; <A> + push ds ; <B> + push es ; <C> + + cli + cld + + xor ebx,ebx + mov bx,cs + shl ebx,4 + lea edx,[Shaker+ebx] + mov [Shaker+2],edx + + ; Test to see if A20 is enabled or not + xor ax,ax + mov ds,ax + dec ax + mov es,ax + + mov ax,[0] + mov bx,ax + xor bx,[es:10h] + not ax + mov [0],ax + mov dx,ax + xor dx,[es:10h] + not ax + mov [0],ax + + or dx,bx + push dx ; <D> Save A20 status + jnz .skip_a20e + + mov ax,2401h ; Enable A20 + int 15h +.skip_a20e: + mov dl,[ConfigFlags] + and dx,CONFIG_BIGRAW + add dx,8 + ; DX =3D 16 for BIGRAW, 8 for RAW + ; 8 is selector for a 64K flat segment, + ; 16 is selector for a 4GB flat segment. + + lgdt [cs:Shaker] + mov eax,cr0 + or al,01h + mov cr0,eax + + mov bx,16 ; Large flat segment + mov ds,bx + mov es,bx + + a32 rep movsd + + ; DX has the appropriate value to put in + ; the registers on return + mov ds,dx + mov es,dx + + and al,~01h + mov cr0,eax + + pop dx ; <D> A20 status + pop es ; <C> + pop ds ; <B> + + and dx,dx + jnz .skip_a20d + mov ax,2400h ; Disable A20 + int 15h +.skip_a20d: + popfd ; <A> + jmp .done + +.fakeint15: + ; We''re in real mode with CONFIG_SAFEINT, invoke the + ; original INT 15h vector. We used to test for the + ; INT 15h vector being unchanged here, but that is + ; *us*; however, the test was wrong for years (always + ; negative) so instead of fixing the test do what we + ; tested and don''t bother probing. + mov bx, fake_int15_stub + +.protmode: + TRACER ''p'' +.anymode: + +.copy_loop: + push esi + push edi + push ecx + cmp ecx,4000h + jna .safe_size + mov ecx,4000h +.safe_size: + push ecx ; Transfer size this cycle + mov eax, esi + mov [Mover_src1], si + shr eax, 16 + mov [Mover_src1+2], al + mov [Mover_src2], ah + mov eax, edi + mov [Mover_dst1], di + shr eax, 16 + mov [Mover_dst1+2], al + mov [Mover_dst2], ah + mov si,Mover + mov ah, 87h + shl cx,1 ; Convert to 16-bit words + call bx ; INT 15h stub + pop eax ; Transfer size this cycle + pop ecx + pop edi + pop esi + jc .error + lea esi,[esi+4*eax] + lea edi,[edi+4*eax] + sub ecx, eax + jnz .copy_loop + ; CF =3D 0 +.error: +.done: + pop ebp + pop edx + pop ebx + pop eax + ret + +real_int15_stub: + int 15h + cli ; Some BIOSes enable interrupts on INT 15h + ret + +fake_int15_stub: + pushf + call far [OldInt15] + cli + ret + +%ifdef DEBUG_TRACERS +debug_tracer: pushad + pushfd + mov bp,sp + mov bx,[bp+9*4] + mov al,[cs:bx] + inc word [bp+9*4] + mov ah,0Eh + mov bx,7 + int 10h + popfd + popad + ret +%endif + + section .data + alignb 2 +Int13Funcs dw Reset ; 00h - RESET + dw GetStatus ; 01h - GET STATUS + dw Read ; 02h - READ + dw Write ; 03h - WRITE + dw Verify ; 04h - VERIFY + dw Invalid ; 05h - FORMAT TRACK + dw Invalid ; 06h - FORMAT TRACK AND SET BAD FLAGS + dw Invalid ; 07h - FORMAT DRIVE AT TRACK + dw GetParms ; 08h - GET PARAMETERS + dw InitWithParms ; 09h - INITIALIZE CONTROLLER WITH DRIVE PARAMETERS + dw Invalid ; 0Ah + dw Invalid ; 0Bh + dw Seek ; 0Ch - SEEK TO CYLINDER + dw Reset ; 0Dh - RESET HARD DISKS + dw Invalid ; 0Eh + dw Invalid ; 0Fh + dw CheckIfReady ; 10h - CHECK IF READY + dw Recalibrate ; 11h - RECALIBRATE + dw Invalid ; 12h + dw Invalid ; 13h + dw Invalid ; 14h + dw GetDriveType ; 15h - GET DRIVE TYPE + dw DetectChange ; 16h - DETECT DRIVE CHANGE +%if EDD + dw Invalid ; 17h + dw Invalid ; 18h + dw Invalid ; 19h + dw Invalid ; 1Ah + dw Invalid ; 1Bh + dw Invalid ; 1Ch + dw Invalid ; 1Dh + dw Invalid ; 1Eh + dw Invalid ; 1Fh + dw Invalid ; 20h + dw ReadMult ; 21h - READ MULTIPLE + dw WriteMult ; 22h - WRITE MULTIPLE + dw SetMode ; 23h - SET CONTROLLER FEATURES + dw SetMode ; 24h - SET MULTIPLE MODE + dw Invalid ; 25h - IDENTIFY DRIVE + dw Invalid ; 26h + dw Invalid ; 27h + dw Invalid ; 28h + dw Invalid ; 29h + dw Invalid ; 2Ah + dw Invalid ; 2Bh + dw Invalid ; 2Ch + dw Invalid ; 2Dh + dw Invalid ; 2Eh + dw Invalid ; 2Fh + dw Invalid ; 30h + dw Invalid ; 31h + dw Invalid ; 32h + dw Invalid ; 33h + dw Invalid ; 34h + dw Invalid ; 35h + dw Invalid ; 36h + dw Invalid ; 37h + dw Invalid ; 38h + dw Invalid ; 39h + dw Invalid ; 3Ah + dw Invalid ; 3Bh + dw Invalid ; 3Ch + dw Invalid ; 3Dh + dw Invalid ; 3Eh + dw Invalid ; 3Fh + dw Invalid ; 40h + dw EDDPresence ; 41h - EDD PRESENCE DETECT + dw EDDRead ; 42h - EDD READ + dw EDDWrite ; 43h - EDD WRITE + dw EDDVerify ; 44h - EDD VERIFY + dw EDDLock ; 45h - EDD LOCK/UNLOCK MEDIA + dw EDDEject ; 46h - EDD EJECT + dw EDDSeek ; 47h - EDD SEEK + dw EDDGetParms ; 48h - EDD GET PARAMETERS + dw EDDDetectChange ; 49h - EDD MEDIA CHANGE STATUS +%endif + +Int13FuncsEnd equ $ +Int13FuncsCnt equ (Int13FuncsEnd-Int13Funcs) >> 1 + + + alignb 8, db 0 +Shaker dw ShakerEnd-$ + dd 0 ; Pointer to self + dw 0 + +Shaker_RMDS: dd 0x0000ffff ; 64K data segment + dd 0x00009300 + +Shaker_DS: dd 0x0000ffff ; 4GB data segment + dd 0x008f9300 + +ShakerEnd equ $ + + alignb 8, db 0 + +Mover dd 0, 0, 0, 0 ; Must be zero + dw 0ffffh ; 64 K segment size +Mover_src1: db 0, 0, 0 ; Low 24 bits of source addy + db 93h ; Access rights + db 00h ; Extended access rights +Mover_src2: db 0 ; High 8 bits of source addy + dw 0ffffh ; 64 K segment size +Mover_dst1: db 0, 0, 0 ; Low 24 bits of target addy + db 93h ; Access rights + db 00h ; Extended access rights +Mover_dst2: db 0 ; High 8 bits of source addy +Mover_dummy2: dd 0, 0, 0, 0 ; More space for the BIOS + + alignb 4, db 0 +MemDisk_Info equ $ ; Pointed to by installation check +MDI_Bytes dw MDI_Len ; Total bytes in MDI structure +MDI_Version db VERSION_MINOR, VERSION_MAJOR ; MEMDISK version + +PatchArea equ $ ; This gets filled in by the installer + +DiskBuf dd 0 ; Linear address of high memory disk +DiskSize dd 0 ; Size of disk in blocks +CommandLine dw 0, 0 ; Far pointer to saved command line + +OldInt13 dd 0 ; INT 13h in chain +OldInt15 dd 0 ; INT 15h in chain + +OldDosMem dw 0 ; Old position of DOS mem end +BootLoaderID db 0 ; Boot loader ID from header + db 0 ; pad + +DPT_ptr dw 0 ; If nonzero, pointer to DPT + ; Original DPT pointer follows + +MDI_Len equ $-MemDisk_Info + +; ---- MDI structure ends here --- +Int13MaxFunc db Int13FuncsCnt-1 ; Max INT 13h function (to disable EDD) + db 0 ; pad + + dw 0 ; pad +MemInt1588 dw 0 ; 1MB-65MB memory amount (1K) + +Cylinders dw 0 ; Cylinder count +Heads dw 0 ; Head count +Sectors dd 0 ; Sector count (zero-extended) + +Mem1MB dd 0 ; 1MB-16MB memory amount (1K) +Mem16MB dd 0 ; 16MB-4G memory amount (64K) + +DriveNo db 0 ; Our drive number +DriveType db 0 ; Our drive type (floppies) +DriveCnt db 0 ; Drive count (from the BIOS) + +ConfigFlags db 0 ; Bit 0 - readonly + +MyStack dw 0 ; Offset of stack +StatusPtr dw 0 ; Where to save status (zeroseg ptr) + +DPT times 16 db 0 ; BIOS parameter table pointer (floppies) +OldInt1E dd 0 ; Previous INT 1E pointer (DPT) + +%if EDD +EDD_DPT: +.length dw 30 +.info dw 0029h + ; Bit 0 - DMA boundaries handled transparently + ; Bit 3 - Device supports write verify + ; Bit 5 - Media is lockable +.cylinders dd 0 ; Filled in by installer +.heads dd 0 ; Filled in by installer +.sectors dd 0 ; Filled in by installer +.totalsize dd 0, 0 ; Filled in by installer +.bytespersec dw SECTORSIZE +.eddtable dw -1, -1 ; Invalid DPTE pointer + +%endif + + ; End patch area +Stack dd 0 ; Saved SS:ESP on invocation + dw 0 +SavedAX dw 0 ; AX saved on invocation + + alignb 4, db 0 ; We *MUST* end on a dword boundary + +E820Table equ $ ; The installer loads the E820 table here +TotalSize equ $ ; End pointer diff --git a/memdisk/memdisk_edd.asm b/memdisk/memdisk_edd.asm new file mode 100644 index 0000000..97d3fe9 --- /dev/null +++ b/memdisk/memdisk_edd.asm @@ -0,0 +1,2 @@ +%define WITH_EDD +%include "memdisk.inc" diff --git a/memdisk/setup.c b/memdisk/setup.c index 7b1f456..ed08d57 100644 --- a/memdisk/setup.c +++ b/memdisk/setup.c @@ -24,6 +24,9 @@ const char copyright[] =3D =20 extern const char _binary_memdisk_bin_start[], _binary_memdisk_bin_end[]; extern const char _binary_memdisk_bin_size[]; /* Weird, I know */ +extern const char _binary_memdisk_edd_bin_start[], + _binary_memdisk_edd_end[]; +extern const char _binary_memdisk_edd_bin_size[]; =20 struct memdisk_header { uint16_t int13_offs; @@ -93,7 +96,6 @@ struct patch_area { uint16_t dpt_ptr; /* End of the official MemDisk_Info */ uint8_t maxint13func; -#define MAXINT13_NOEDD 0x16 uint8_t _pad2; =20 uint16_t _pad3; @@ -598,7 +600,8 @@ void *sys_bounce; =20 __cdecl void setup(__cdecl syscall_t cs_syscall, void *cs_bounce) { - unsigned int bin_size =3D (int) &_binary_memdisk_bin_size; + unsigned int bin_size; + char *memdisk_hook; struct memdisk_header *hptr; struct patch_area *pptr; uint16_t driverseg; @@ -610,7 +613,7 @@ __cdecl void setup(__cdecl syscall_t cs_syscall, void *cs_bounce) com32sys_t regs; uint32_t ramdisk_image, ramdisk_size; int bios_drives; - int do_edd =3D -1; /* -1 =3D default, 0 =3D no, 1 =3D yes */ + int do_edd =3D 1; /* 0 =3D no, 1 =3D yes, default is yes */ int no_bpt; /* No valid BPT presented */ =20 /* Set up global variables */ @@ -649,13 +652,22 @@ __cdecl void setup(__cdecl syscall_t cs_syscall, void *cs_bounce) else do_edd =3D (geometry->driveno & 0x80) ? 1 : 0; =20 + /* Choose the appropriate installable memdisk hook */ + if (do_edd) { + bin_size =3D (int) &_binary_memdisk_edd_bin_size; + memdisk_hook =3D (char *) &_binary_memdisk_edd_bin_start; + } else { + bin_size =3D (int) &_binary_memdisk_bin_size; + memdisk_hook =3D (char *) &_binary_memdisk_bin_start; + } + /* Reserve the ramdisk memory */ insertrange(ramdisk_image, ramdisk_size, 2, 1); parse_mem(); /* Recompute variables */ =20 /* Figure out where it needs to go */ - hptr =3D (struct memdisk_header *) &_binary_memdisk_bin_start; - pptr =3D (struct patch_area *)(_binary_memdisk_bin_start + hptr->patch_offs); + hptr =3D (struct memdisk_header *) memdisk_hook; + pptr =3D (struct patch_area *)(memdisk_hook + hptr->patch_offs); =20 dosmem_k =3D rdz_16(BIOS_BASEMEM); pptr->olddosmem =3D dosmem_k; @@ -726,10 +738,6 @@ __cdecl void setup(__cdecl syscall_t cs_syscall, void *cs_bounce) } puts(" access to high memory\n"); =20 - /* pptr->maxint13func defaults to EDD enabled, if compiled in */ - if (!do_edd) - pptr->maxint13func =3D MAXINT13_NOEDD; - /* Set up a drive parameter table */ if ( geometry->driveno & 0x80 ) { /* Hard disk */ @@ -898,7 +906,7 @@ __cdecl void setup(__cdecl syscall_t cs_syscall, void *cs_bounce) hptr =3D (struct memdisk_header *)dpp; =20 /* Actually copy to low memory */ - dpp =3D mempcpy(dpp, &_binary_memdisk_bin_start, bin_size); + dpp =3D mempcpy(dpp, memdisk_hook, bin_size); dpp =3D mempcpy(dpp, ranges, (nranges+1)*sizeof(ranges[0])); dpp =3D mempcpy(dpp, shdr->cmdline, cmdlinelen+1); } --=20 1.5.3.4 ------_=_NextPart_001_01C9A06C.565F4677 Content-Type: application/octet-stream; name="0001-memdisk-varieties-Allow-for-multiple-memdisk-instal.patch" Content-Transfer-Encoding: base64 Content-Description: 0001-memdisk-varieties-Allow-for-multiple-memdisk-instal.patch Content-Disposition: attachment; filename="0001-memdisk-varieties-Allow-for-multiple-memdisk-instal.patch" RnJvbSBjOGQ3ZjE0YTkzOWMyYWJiNzE2NWVhZmE1NzUyMWFlMjlmYWJlMzI3IE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBTaGFvIE1pbGxlciA8c2hhby5taWxsZXJAeXJkc2IuZWR1Lm9u LmNhPgpEYXRlOiBTdW4sIDggTWFyIDIwMDkgMjM6NTQ6NDMgLTA0MDAKU3ViamVjdDogW1BBVENI XSBtZW1kaXNrIHZhcmlldGllczogQWxsb3cgZm9yIG11bHRpcGxlIG1lbWRpc2sgaW5zdGFsbGFi bGUgaG9va3MKClRoaXMgcGF0Y2ggInNldHMgdGhlIHN0YWdlIiBmb3IgdGhlIG1lbWRpc2sga2Vy bmVsIHRvIGluY2x1ZGUgZGlmZmVyZW50CiJpbnN0YWxsYWJsZXMiOiB2ZXJzaW9ucyBvZiB0aGUg bWVtZGlzayBob29rcy4KClRoaXMgcGF0Y2ggc3BsaXRzIHRoZSBjYXNlIG9mIHRoZSBFREQtY29t cGlsZWQgaG9vayBmcm9tIHRoZSBub24tRURELWNvbXBpbGVkCmhvb2suICBCb3RoIGFyZSBhdmFp bGFibGUgaW5zaWRlIHRoZSBrZXJuZWwsIGFuZCB0aGUga2VybmVsIGNob29zZXMgd2hpY2ggb25l CnRvIGluc3RhbGwgYmFzZWQgb24gdGhlIGNvbW1hbmQtbGluZS4KCkl0J3MgcG9zc2libGUgdGhh dCBvdGhlciwgc2xpZ2h0bHkgbW9kaWZpZWQgdmVyc2lvbnMgb2YgdGhlIG1lbWRpc2sgaG9vayBj b3VsZApiZSB1c2VmdWwgdG8gaGF2ZS4uLgotLS0KIG1lbWRpc2svTWFrZWZpbGUgICAgICAgIHwg ICAgOSArLQogbWVtZGlzay9tZW1kaXNrLmFzbSAgICAgfCAgOTg4ICstLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiBtZW1kaXNrL21lbWRpc2suaW5jICAgICB8 ICA5ODcgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwogbWVt ZGlzay9tZW1kaXNrX2VkZC5hc20gfCAgICAyICsKIG1lbWRpc2svc2V0dXAuYyAgICAgICAgIHwg ICAyOCArLQogNSBmaWxlcyBjaGFuZ2VkLCAxMDE0IGluc2VydGlvbnMoKyksIDEwMDAgZGVsZXRp b25zKC0pCiBjcmVhdGUgbW9kZSAxMDA2NDQgbWVtZGlzay9tZW1kaXNrLmluYwogY3JlYXRlIG1v ZGUgMTAwNjQ0IG1lbWRpc2svbWVtZGlza19lZGQuYXNtCgpkaWZmIC0tZ2l0IGEvbWVtZGlzay9N YWtlZmlsZSBiL21lbWRpc2svTWFrZWZpbGUKaW5kZXggMzc3NjczMS4uYjhjYjkxYSAxMDA2NDQK LS0tIGEvbWVtZGlzay9NYWtlZmlsZQorKysgYi9tZW1kaXNrL01ha2VmaWxlCkBAIC0yMCw3ICsy MCw3IEBAIExERkxBR1MgID0gJChHQ0NPUFQpIC1nCiBJTkNMVURFICA9IC1JJCh0b3BkaXIpL2Nv bTMyL2luY2x1ZGUKIE5BU00gICAgID0gbmFzbQogTkFTTU9QVCAgPSAtTzk5OTkKLU5GTEFHUyAg ID0gLWREQVRFPSciJChEQVRFKSInIC1kV0lUSF9FREQKK05GTEFHUyAgID0gLWREQVRFPSciJChE QVRFKSInCiBOSU5DTFVERSA9CiAKIFNSQ1MJID0gJCh3aWxkY2FyZCAqLmFzbSAqLmMgKi5oKQpA QCAtMzgsMTEgKzM4LDExIEBAIGVuZGlmCiAjIEltcG9ydGFudDogaW5pdC5vMTYgbXVzdCBiZSBm aXJzdCEhCiBPQkpTMTYgICA9IGluaXQubzE2IGluaXQzMi5vCiBPQkpTMzIgICA9IHN0YXJ0MzIu byBzZXR1cC5vIG1zZXR1cC5vIGU4MjBmdW5jLm8gY29uaW8ubyBtZW1jcHkubyBtZW1zZXQubyBc Ci0gICAgICAgICAgIHVuemlwLm8gbWVtZGlzay5vCisgICAgICAgICAgIHVuemlwLm8gbWVtZGlz ay5vIG1lbWRpc2tfZWRkLm8KIAogQ1NSQyAgICAgPSBzZXR1cC5jIG1zZXR1cC5jIGU4MjBmdW5j LmMgY29uaW8uYyB1bnppcC5jCiBTU1JDICAgICA9IHN0YXJ0MzIuUyBtZW1jcHkuUyBtZW1zZXQu UwotTkFTTVNSQyAgPSBtZW1kaXNrLmFzbSBtZW1kaXNrMTYuYXNtCitOQVNNU1JDICA9IG1lbWRp c2suYXNtIG1lbWRpc2tfZWRkLmFzbSBtZW1kaXNrMTYuYXNtCiAKIGFsbDogbWVtZGlzayAjIGU4 MjB0ZXN0CiAKQEAgLTExMCw2ICsxMTAsOSBAQCBlODIwdGVzdDogZTgyMHRlc3QuYyBlODIwZnVu Yy5jIG1zZXR1cC5jCiBtZW1kaXNrLm86IG1lbWRpc2suYmluCiAJJChMRCkgLXIgLWIgYmluYXJ5 IC1vICRAICQ8CiAKK21lbWRpc2tfZWRkLm86IG1lbWRpc2tfZWRkLmJpbgorCSQoTEQpIC1yIC1i IGJpbmFyeSAtbyAkQCAkPAorCiAuZGVwZW5kOgogCXJtIC1mIC5kZXBlbmQKIAlmb3IgY3NyYyBp biAqLmMgOyBkbyAkKENDKSAkKElOQ0xVREUpICQoQ0ZMQUdTKSAtTU0gJCRjc3JjID4+IC5kZXBl bmQgOyBkb25lCmRpZmYgLS1naXQgYS9tZW1kaXNrL21lbWRpc2suYXNtIGIvbWVtZGlzay9tZW1k aXNrLmFzbQppbmRleCAwZDQ4OTYxLi5kYWE1YzBhIDEwMDY0NAotLS0gYS9tZW1kaXNrL21lbWRp c2suYXNtCisrKyBiL21lbWRpc2svbWVtZGlzay5hc20KQEAgLTEsOTg3ICsxIEBACi07IC0qLSBm dW5kYW1lbnRhbCAtKi0gKGFzbS1tb2RlIHN1Y2tzKQotOyAqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi07 Ci07ICBtZW1kaXNrLmFzbQotOwotOyAgQSBwcm9ncmFtIHRvIGVtdWxhdGUgYW4gSU5UIDEzaCBk aXNrIEJJT1MgZnJvbSBhICJkaXNrIiBpbiBleHRlbmRlZAotOyAgbWVtb3J5LgotOwotOyAgIENv cHlyaWdodCAyMDAxLTIwMDggSC4gUGV0ZXIgQW52aW4gLSBBbGwgUmlnaHRzIFJlc2VydmVkCi07 Ci07ICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUg aXQgYW5kL29yIG1vZGlmeQotOyAgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJh bCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKLTsgIHRoZSBGcmVlIFNvZnR3YXJlIEZv dW5kYXRpb24sIEluYy4sIDUzIFRlbXBsZSBQbGFjZSBTdGUgMzMwLAotOyAgQm9zdG9uIE1BIDAy MTExLTEzMDcsIFVTQTsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKLTsgIChh dCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb247IGluY29ycG9yYXRlZCBoZXJlaW4gYnkg cmVmZXJlbmNlLgotOwotOyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0KLSVpZm5kZWYgREVQRU5ECi0l aW5jbHVkZQkiLi4vdmVyc2lvbi5nZW4iCi0lZW5kaWYKLQotOyAlZGVmaW5lIERFQlVHX1RSQUNF UlMJCQk7IFVuY29tbWVudCB0byBnZXQgZGVidWdnaW5nIHRyYWNlcnMKLQotJWlmZGVmIFdJVEhf RURECi0lZGVmaW5lIEVERCAxCi0lZWxzZQotJWRlZmluZSBFREQgMAotJWVuZGlmCi0KLSVpZmRl ZiBERUJVR19UUkFDRVJTCi0KLSVtYWNybyBUUkFDRVIJMQotCWNhbGwgZGVidWdfdHJhY2VyCi0J ZGIgJTEKLSVlbmRtYWNybwotCi0lZWxzZQk7IERFQlVHX1RSQUNFUlMKLQotJW1hY3JvCVRSQUNF UgkxCi0lZW5kbWFjcm8KLQotJWVuZGlmCTsgREVCVUdfVFJBQ0VSUwotCi0lZGVmaW5lIENPTkZJ R19SRUFET05MWQkweDAxCi0lZGVmaW5lIENPTkZJR19SQVcJMHgwMgotJWRlZmluZSBDT05GSUdf U0FGRUlOVAkweDA0Ci0lZGVmaW5lIENPTkZJR19CSUdSQVcJMHgwOAkJOyBNVVNUIGJlIDghCi0K LQkJb3JnIDBoCi0KLSVkZWZpbmUgU0VDVE9SU0laRV9MRzIJOQkJOyBsb2cyKHNlY3RvciBzaXpl KQotJWRlZmluZQlTRUNUT1JTSVpFCSgxIDw8IFNFQ1RPUlNJWkVfTEcyKQotCi0JCTsgUGFyYW1l dGVyIHJlZ2lzdGVycyBkZWZpbml0aW9uOyB0aGlzIGlzIHRoZSBkZWZpbml0aW9uCi0JCTsgb2Yg dGhlIHN0YWNrIGZyYW1lLgotJWRlZmluZQkJUF9EUwkJd29yZCBbYnArMzRdCi0lZGVmaW5lCQlQ X0VTCQl3b3JkIFticCszMl0KLSVkZWZpbmUJCVBfRUFYCQlkd29yZCBbYnArMjhdCi0lZGVmaW5l CQlQX0hBWAkJd29yZCBbYnArMzBdCi0lZGVmaW5lCQlQX0FYCQl3b3JkIFticCsyOF0KLSVkZWZp bmUJCVBfQUwJCWJ5dGUgW2JwKzI4XQotJWRlZmluZQkJUF9BSAkJYnl0ZSBbYnArMjldCi0lZGVm aW5lCQlQX0VDWAkJZHdvcmQgW2JwKzI0XQotJWRlZmluZQkJUF9IQ1gJCXdvcmQgW2JwKzI2XQot JWRlZmluZQkJUF9DWAkJd29yZCBbYnArMjRdCi0lZGVmaW5lCQlQX0NMCQlieXRlIFticCsyNF0K LSVkZWZpbmUJCVBfQ0gJCWJ5dGUgW2JwKzI1XQotJWRlZmluZQkJUF9FRFgJCWR3b3JkIFticCsy MF0KLSVkZWZpbmUJCVBfSERYCQl3b3JkIFticCsyMl0KLSVkZWZpbmUJCVBfRFgJCXdvcmQgW2Jw KzIwXQotJWRlZmluZQkJUF9ETAkJYnl0ZSBbYnArMjBdCi0lZGVmaW5lCQlQX0RICQlieXRlIFti cCsyMV0KLSVkZWZpbmUJCVBfRUJYCQlkd29yZCBbYnArMTZdCi0lZGVmaW5lCQlQX0hCWAkJd29y ZCBbYnArMThdCi0lZGVmaW5lCQlQX0hCWEwJCWJ5dGUgW2JwKzE4XQotJWRlZmluZQkJUF9CWAkJ d29yZCBbYnArMTZdCi0lZGVmaW5lCQlQX0JMCQlieXRlIFticCsxNl0KLSVkZWZpbmUJCVBfQkgJ CWJ5dGUgW2JwKzE3XQotJWRlZmluZQkJUF9FQlAJCWR3b3JkIFticCs4XQotJWRlZmluZQkJUF9C UAkJd29yZCBbYnArOF0KLSVkZWZpbmUJCVBfRVNJCQlkd29yZCBbYnArNF0KLSVkZWZpbmUJCVBf U0kJCXdvcmQgW2JwKzRdCi0lZGVmaW5lCQlQX0VESQkJZHdvcmQgW2JwXQotJWRlZmluZQkJUF9E SQkJd29yZCBbYnBdCi0KLQkJc2VjdGlvbiAudGV4dAotCQk7IFRoZXNlIHBvaW50ZXJzIGFyZSB1 c2VkIGJ5IHRoZSBpbnN0YWxsZXIgYW5kCi0JCTsgbXVzdCBiZSBmaXJzdCBpbiB0aGUgYmluYXJ5 Ci1Qb2ludGVyczoJZHcgSW50MTNTdGFydAotCQlkdyBJbnQxNVN0YXJ0Ci0JCWR3IFBhdGNoQXJl YQotCQlkdyBUb3RhbFNpemUKLQkJZHcgSXJldFB0cgotCi1JcmV0UHRyCQllcXUgSW50MTNTdGFy dC5pcmV0Ci1JbnQxM1N0YXJ0OgotCQk7IFN3YXAgc3RhY2sKLQkJbW92IFtjczpTdGFja10sZXNw Ci0JCW1vdiBbY3M6U2F2ZWRBWF0sYXgKLQkJbW92IGF4LHNzCi0JCW1vdiBbY3M6U3RhY2srNF0s YXgKLQkJbW92IGF4LGNzCi0JCW1vdiBzcyxheAotCQltb3Ygc3AsW2NzOk15U3RhY2tdCi0KLQkJ OyBTZWUgaWYgREwgcG9pbnRzIHRvIG91ciBjbGFzcyBvZiBkZXZpY2UgKEZELCBIRCkKLQkJcHVz aCBkeAotCQlwdXNoIGR4Ci0JCXhvciBkbCxbY3M6RHJpdmVOb10KLQkJcG9wIGR4Ci0JCWpzIC5u b21hdGNoCQk7IElmIFNGPTAsIHdlIGhhdmUgYSBjbGFzcyBtYXRjaCBoZXJlCi0JCWp6IC5vdXJf ZHJpdmUJCTsgSWYgWkY9MSwgd2UgaGF2ZSBhbiBleGFjdCBtYXRjaAotCQljbXAgZGwsW2NzOkRy aXZlTm9dCi0JCWpiIC5ub21hdGNoCQk7IERyaXZlIDwgT3VyIGRyaXZlCi0JCWRlYyBkbAkJCTsg RHJpdmUgPiBPdXIgZHJpdmUsIGFkanVzdCBkcml2ZSAjCi0ubm9tYXRjaDoKLQkJbW92IGF4LFtj czpTYXZlZEFYXQotCQlwdXNoZgotCQljYWxsIGZhciBbY3M6T2xkSW50MTNdCi0JCXB1c2hmCi0J CXB1c2ggYnAKLQkJbW92IGJwLHNwCi0JCWNtcCBieXRlIFtjczpTYXZlZEFYKzFdLDA4aAotCQlq ZSAubm9yZXN0b3JlZGwKLQkJY21wIGJ5dGUgW2NzOlNhdmVkQVgrMV0sMTVoCi0JCWpuZSAucmVz dG9yZWRsCi0JCXRlc3QgYnl0ZSBbYnArNF0sODBoCTsgSGFyZCBkaXNrPwotCQlqbnogLm5vcmVz dG9yZWRsCi0ucmVzdG9yZWRsOgotCQltb3YgZGwsW2JwKzRdCi0ubm9yZXN0b3JlZGw6Ci0JCXB1 c2ggYXgKLQkJcHVzaCBlYngKLQkJcHVzaCBkcwotCQltb3YgYXgsW2JwKzJdCQk7IEZsYWdzCi0J CWxkcyBlYngsW2NzOlN0YWNrXQotCQltb3YgW2J4KzRdLGFsCQk7IEFyaXRobWV0cmljIGZsYWdz Ci0JCXBvcCBkcwotCQlwb3AgZWJ4Ci0JCXBvcCBheAotCQlwb3AgYnAKLQkJbHNzIGVzcCxbY3M6 U3RhY2tdCi0uaXJldDoJCWlyZXQKLQotLm91cl9kcml2ZToKLQkJOyBTZXQgdXAgc3RhbmRhcmQg ZW50cnkgZnJhbWUKLQkJcHVzaCBkcwotCQlwdXNoIGVzCi0JCW1vdiBkcyxheAotCQltb3YgZXMs YXgKLQkJbW92IGF4LFtTYXZlZEFYXQotCQlwdXNoYWQKLQkJbW92IGJwLHNwCQk7IFBvaW50IEJQ IHRvIHRoZSBlbnRyeSBzdGFjayBmcmFtZQotCQlUUkFDRVIgJ0YnCi0JCTsgTm90ZTogQUggPT0g UF9BSCBoZXJlCi0JCWNtcCBhaCxbSW50MTNNYXhGdW5jXQotCQlqYSBJbnZhbGlkX2p1bXAKLQkJ eG9yIGFsLGFsCQk7IEFMID0gMCBpcyBzdGFuZGFyZCBlbnRyeSBjb25kaXRpb24KLQkJbW92IGRp LGF4Ci0JCXNociBkaSw3CQk7IENvbnZlcnQgQUggdG8gYW4gb2Zmc2V0IGluIERJCi0JCWNhbGwg W0ludDEzRnVuY3MrZGldCi0KLURvbmU6CQk7IFN0YW5kYXJkIHJvdXRpbmUgZm9yIHJldHVybgot CQltb3YgUF9BWCxheAotRG9uZVdlaXJkOgotCQlUUkFDRVIgJ0QnCi0JCXhvciBieCxieAotCQlt b3YgZXMsYngKLQkJbW92IGJ4LFtTdGF0dXNQdHJdCi0JCW1vdiBbZXM6YnhdLGFoCQk7IFNhdmUg c3RhdHVzCi0JCWFuZCBhaCxhaAotCi0JCWxkcyBlYngsW1N0YWNrXQotCQk7IFRoaXMgc2V0cyB0 aGUgbG93IGJ5dGUgKHRoZSBhcml0aG1ldHJpYyBmbGFncykgb2YgdGhlCi0JCTsgRkxBR1Mgb24g c3RhY2sgdG8gZWl0aGVyIDAwaCAobm8gZmxhZ3MpIG9yIDAxaCAoQ0YpCi0JCTsgZGVwZW5kaW5n IG9uIGlmIEFIIHdhcyB6ZXJvIG9yIG5vdC4KLQkJc2V0bnogW2J4KzRdCQk7IFNldCBDRiBpZmYg ZXJyb3IKLQkJcG9wYWQKLQkJcG9wIGVzCi0JCXBvcCBkcwotCQlsc3MgZXNwLFtjczpTdGFja10K LQkJaXJldAotCi1SZXNldDoKLQkJOyBSZXNldCBhZmZlY3RzIG11bHRpcGxlIGRyaXZlcywgc28g d2UgbmVlZCB0byBwYXNzIGl0IG9uCi0JCVRSQUNFUiAnUicKLQkJeG9yIGF4LGF4CQk7IEJvdHRv bSBvZiBtZW1vcnkKLQkJbW92IGVzLGF4Ci0JCXRlc3QgZGwsZGwJCTsgQWx3YXlzIHBhc3MgaXQg b24gaWYgd2UgYXJlIHJlc2V0dGluZyBIRAotCQlqcyAuaGFyZF9kaXNrCQk7IEJpdCA3IHNldAot CQk7IFNvbWUgQklPU2VzIGdldCB2ZXJ5IHVuaGFwcHkgaWYgd2UgcGFzcyBhIHJlc2V0IGZsb3Bw eQotCQk7IGNvbW1hbmQgdG8gdGhlbSBhbmQgZG9uJ3QgYWN0dWFsbHkgaGF2ZSBhbnkgZmxvcHBp ZXMuCi0JCTsgVGhpcyBpcyBhIGJ1ZywgYnV0IHdlIGhhdmUgdG8gZGVhbCB3aXRoIGl0IG5vbnRo ZWxlc3MuCi0JCTsgVGhlcmVmb3JlLCBpZiB3ZSBhcmUgdGhlICpPTkxZKiBmbG9wcHkgZHJpdmUs IGFuZCB0aGUKLQkJOyB1c2VyIGRpZG4ndCByZXF1ZXN0IEhEIHJlc2V0LCB0aGVuIGp1c3QgZHJv cCB0aGUgY29tbWFuZC4KLQkJOyBCSU9TIGVxdWlwbWVudCBieXRlLCB0b3AgdHdvIGJpdHMgKyAx ID09IHRvdGFsICMgb2YgZmxvcHBpZXMKLQkJdGVzdCBieXRlIFtlczoweDQxMF0sMEMwaAotCQlq eiBzdWNjZXNzCi0JCWptcCAucGFzc19vbgkJOyAuLi4gb3RoZXJ3aXNlIHBhc3MgaXQgdG8gdGhl IEJJT1MKLS5oYXJkX2Rpc2s6Ci0JCTsgLi4uIHNhbWUgdGhpbmcgZm9yIGhhcmQgZGlza3MsIHNp Z2ggLi4uCi0JCWNtcCBieXRlIFtlczoweDQ3NV0sMQk7IEJJT1MgdmFyaWFibGUgZm9yIG51bWJl ciBvZiBoYXJkIGRpc2tzCi0JCWpiZSBzdWNjZXNzCi0KLS5wYXNzX29uOgotCQlwb3AgYXgJCQk7 IERyb3AgcmV0dXJuIGFkZHJlc3MKLQkJcG9wYWQJCQk7IFJlc3RvcmUgYWxsIHJlZ2lzdGVycwot CQlwb3AgZXMKLQkJcG9wIGRzCi0JCWxzcyBlc3AsW2NzOlN0YWNrXQk7IFJlc3RvcmUgdGhlIHN0 YWNrCi0JCWFuZCBkbCw4MGgJCTsgQ2xlYXIgYWxsIGJ1dCB0aGUgdHlwZSBiaXQKLQkJam1wIGZh ciBbY3M6T2xkSW50MTNdCi0KLQotSW52YWxpZDoKLQkJcG9wIGR4CQkJOyBEcm9wIHJldHVybiBh ZGRyZXNzCi1JbnZhbGlkX2p1bXA6Ci0JCVRSQUNFUiAnSScKLQkJbW92IGFoLDAxaAkJOyBVbnN1 cHBvcnRlZCBmdW5jdGlvbgotCQlqbXAgc2hvcnQgRG9uZQotCi1HZXREcml2ZVR5cGU6Ci0JCXRl c3QgYnl0ZSBbRHJpdmVOb10sODBoCi0JCW1vdiBibCwwMmgJCTsgVHlwZSAwMmggPSBmbG9wcHkg d2l0aCBjaGFuZ2VsaW5lCi0JCWp6IC5mbG9wcHkKLQkJOyBIYXJkIGRpc2tzIG9ubHkuLi4KLQkJ aW5jIGJ4CQkJOyBUeXBlID0gMDNoCi0JCW1vdiBkeCxbRGlza1NpemVdCTsgUmV0dXJuIHRoZSBk aXNrIHNpemUgaW4gc2VjdG9ycwotCQltb3YgUF9EWCxkeAotCQltb3YgY3gsW0Rpc2tTaXplKzJd Ci0JCW1vdiBQX0NYLGN4Ci0uZmxvcHB5OgotCQltb3YgUF9BSCxibAkJOyAwMmggZmxvcHB5LCAw M2ggaGFyZCBkaXNrCi0JCXBvcCBheAkJCTsgRHJvcCByZXR1cm4gYWRkcmVzcwotCQl4b3IgYXgs YXgJCTsgU3VjY2Vzcy4uLgotCQlqbXAgRG9uZVdlaXJkCQk7IEJ1dCBkb24ndCBzdGljayBpdCBp bnRvIFBfQVgKLQotR2V0U3RhdHVzOgotCQl4b3IgYXgsYXgKLQkJbW92IGVzLGF4Ci0JCW1vdiBi eCxbU3RhdHVzUHRyXQotCQltb3YgYWgsW2J4XQkJOyBDb3B5IGxhc3Qgc3RhdHVzCi0JCXJldAot Ci1SZWFkTXVsdDoKLQkJVFJBQ0VSICdtJwotUmVhZDoKLQkJVFJBQ0VSICdSJwotCQljYWxsIHNl dHVwX3JlZ3MKLWRvX2NvcHk6Ci0JCVRSQUNFUiAnPCcKLQkJY2FsbCBiY29weQotCQlUUkFDRVIg Jz4nCi0JCW1vdnp4IGF4LFBfQUwJCTsgQUggPSAwLCBBTCA9IHRyYW5zZmVyIGNvdW50Ci0JCXJl dAotCi1Xcml0ZU11bHQ6Ci0JCVRSQUNFUiAnTScKLVdyaXRlOgotCQlUUkFDRVIgJ1cnCi0JCXRl c3QgYnl0ZSBbQ29uZmlnRmxhZ3NdLENPTkZJR19SRUFET05MWQotCQlqbnogLnJlYWRvbmx5Ci0J CWNhbGwgc2V0dXBfcmVncwotCQl4Y2hnIGVzaSxlZGkJCTsgT3Bwb3NpdGUgZGlyZWN0aW9uIG9m IGEgUmVhZCEKLQkJam1wIHNob3J0IGRvX2NvcHkKLS5yZWFkb25seToJbW92IGFoLDAzaAkJOyBX cml0ZSBwcm90ZWN0ZWQgbWVkaXVtCi0JCXJldAotCi0JCTsgVmVyaWZ5IGludGVncml0eTsganVz dCBib3VuZHMtY2hlY2sKLVNlZWs6Ci1WZXJpZnk6Ci0JCWNhbGwgc2V0dXBfcmVncwkJOyBSZXR1 cm5zIGVycm9yIGlmIGFwcHJvcHJpYXRlCi0JCTsgQW5kIGZhbGwgdGhyb3VnaCB0byBzdWNjZXNz Ci0KLUNoZWNrSWZSZWFkeToJCQkJOyBUaGVzZSBhcmUgYWx3YXlzLXN1Y2Nlc3NmdWwgbm9vcCBm dW5jdGlvbnMKLVJlY2FsaWJyYXRlOgotSW5pdFdpdGhQYXJtczoKLURldGVjdENoYW5nZToKLUVE RERldGVjdENoYW5nZToKLUVERExvY2s6Ci1TZXRNb2RlOgotc3VjY2VzczoKLQkJeG9yIGF4LGF4 CQk7IEFsd2F5cyBzdWNjZXNzZnVsCi0JCXJldAotCi1HZXRQYXJtczoKLQkJVFJBQ0VSICdHJwot CQltb3YgZGwsW0RyaXZlQ250XQk7IENhY2hlZCBkYXRhCi0JCW1vdiBQX0RMLGRsCi0JCXRlc3Qg Ynl0ZSBbRHJpdmVOb10sODBoCi0JCWpueiAuaGQKLQkJbW92IFBfREksRFBUCi0JCW1vdiBQX0VT LGNzCi0JCW1vdiBibCxbRHJpdmVUeXBlXQotCQltb3YgUF9CTCxibAotLmhkOgotCQltb3YgYXgs W0N5bGluZGVyc10KLQkJZGVjIGF4CQkJOyBXZSByZXBvcnQgdGhlIGhpZ2hlc3QgIywgbm90IHRo ZSBjb3VudAotCQl4Y2hnIGFsLGFoCi0JCXNobCBhbCw2Ci0JCW9yIGFsLFtTZWN0b3JzXQotCQlt b3YgUF9DWCxheAotCQltb3YgYXgsW0hlYWRzXQotCQlkZWMgYXgKLQkJbW92IFBfREgsYWwKLQot CQk7Ci0JCTsgSXMgdGhpcyBNRU1ESVNLIGluc3RhbGxhdGlvbiBjaGVjaz8KLQkJOwotCQljbXAg UF9IQVgsJ01FJwotCQlqbmUgLm5vdGljCi0JCWNtcCBQX0hDWCwnTUQnCi0JCWpuZSAubm90aWMK LQkJY21wIFBfSERYLCdJUycKLQkJam5lIC5ub3RpYwotCQljbXAgUF9IQlgsJ0s/JwotCQlqbmUg Lm5vdGljCi0KLQkJOyBNRU1ESVNLIGluc3RhbGxhdGlvbiBjaGVjay4uLgotCQltb3YgUF9IQVgs JyFNJwotCQltb3YgUF9IQ1gsJ0VNJwotCQltb3YgUF9IRFgsJ0RJJwotCQltb3YgUF9IQlgsJ1NL JwotCQltb3YgUF9FUyxjcwotCQltb3YgUF9ESSxNZW1EaXNrX0luZm8KLQotLm5vdGljOgotCQl4 b3IgYXgsYXgKLQkJcmV0Ci07Ci07IEVERCBmdW5jdGlvbnMgLS0gb25seSBpZiBlbmFibGVkCi07 Ci0laWYgRURECi1FRERQcmVzZW5jZToKLQkJVFJBQ0VSICdFJwotCQlUUkFDRVIgJ2MnCi0KLQkJ Y21wIFBfQlgsNTVBQWgKLQkJam5lIEludmFsaWQKLQkJbW92IFBfQlgsMEFBNTVoCQk7IEVERCBz aWduYXR1cmUKLQkJbW92IFBfQVgsMDMwMDBoCQk7IEVERCAzLjAKLQkJbW92IFBfQ1gsMDAwM2gJ CTsgQml0IDAgLSBGaXhlZCBkaXNrIGFjY2VzcyBzdWJzZXQKLQkJCQkJOyBCaXQgMSAtIExvY2tp bmcgYW5kIGVqZWN0aW5nIHN1YnNldAotCQlwb3AgYXgJCQk7IERyb3AgcmV0dXJuIGFkZHJlc3MK LQkJeG9yIGF4LGF4CQk7IFN1Y2Nlc3MKLQkJam1wIERvbmVXZWlyZAkJOyBTdWNjZXNzLCBidXQg QUggIT0gMCwgc2lnaC4uLgotCi1FRERSZWFkOgotCQlUUkFDRVIgJ0UnCi0JCVRSQUNFUiAncicK LQotCQljYWxsIGVkZF9zZXR1cF9yZWdzCi0JCWNhbGwgYmNvcHkKLQkJeG9yIGF4LGF4Ci0JCXJl dAotCi1FRERXcml0ZToKLQkJVFJBQ0VSICdFJwotCQlUUkFDRVIgJ3cnCi0KLQkJY2FsbCBlZGRf c2V0dXBfcmVncwotCQl4Y2hnIGVzaSxlZGkKLQkJY2FsbCBiY29weQotCQl4b3IgYXgsYXgKLQkJ cmV0Ci0KLUVERFZlcmlmeToKLUVERFNlZWs6Ci0JCWNhbGwgZWRkX3NldHVwX3JlZ3MJOyBKdXN0 IGJvdW5kcyBjaGVja2luZwotCQl4b3IgYXgsYXgKLQkJcmV0Ci0KLUVEREdldFBhcm1zOgotCQlU UkFDRVIgJ0UnCi0JCVRSQUNFUiAncCcKLQotCQltb3YgZXMsUF9EUwotCQltb3YgZGksUF9TSQot CQltb3Ygc2ksRUREX0RQVAotCi0JCWxvZHN3CQkJOyBMZW5ndGggb2Ygb3VyIERQVAotCQltb3Yg Y3gsW2VzOmRpXQotCQljbXAgY3gsMjYJCTsgTWluaW11bSBzaXplCi0JCWpiIC5vdmVycnVuCi0K LQkJY21wIGN4LGF4Ci0JCWpiIC5va3NpemUKLQkJbW92IGN4LGF4Ci0KLS5va3NpemU6Ci0JCW1v diBheCxjeAotCQlzdG9zdwotCQlkZWMgY3gKLQkJZGVjIGN4Ci0JCXJlcCBtb3ZzYgotCi0JCXhv ciBheCxheAotCQlyZXQKLQotLm92ZXJydW46Ci0JCW1vdiBheCwwMTAwaAotCQlyZXQKLSVlbmRp ZiA7IEVERAotCi0JCTsgU2V0IHVwIHJlZ2lzdGVycyBhcyBmb3IgYSAiUmVhZCIsIGFuZCBjb21w YXJlcyBhZ2FpbnN0IGRpc2sgc2l6ZS4KLQkJOyBXQVJOSU5HOiBUaGlzIGZhaWxzIGltbWVkaWF0 ZWx5LCBldmVuIGlmIHdlIGNhbiB0cmFuc2ZlciBzb21lCi0JCTsgc2VjdG9ycy4gIFRoaXMgaXNu J3QgcmVhbGx5IHRoZSBjb3JyZWN0IGJlaGF2aW91ci4KLXNldHVwX3JlZ3M6Ci0KLQkJOyBDb252 ZXJ0IGEgQ0hTIGFkZHJlc3MgaW4gUF9DWC9QX0RIIGludG8gYW4gTEJBIGluIGVheAotCQk7IENI ID0gY3lsWzc6MF0KLQkJOyBDTFswOjVdID0gc2VjdG9yICgxLWJhc2VkKSAgQ0xbNzo2XSA9IGN5 bFs5OjhdCi0JCTsgREggPSBoZWFkCi0JCW1vdnp4IGVjeCxQX0NYCi0JCW1vdnp4IGVieCxjbAkJ OyBTZWN0b3IgbnVtYmVyCi0JCWFuZCBibCwzRmgKLQkJZGVjIGVieAkJCTsgU2VjdG9yIG51bWJl ciBpcyAxLWJhc2VkCi0JCWNtcCBieCxbU2VjdG9yc10KLQkJamFlIC5vdmVycnVuCi0JCW1vdnp4 IGVkaSxQX0RICQk7IEhlYWQgbnVtYmVyCi0JCW1vdnp4IGVheCx3b3JkIFtIZWFkc10KLQkJY21w IGRpLGF4Ci0JCWphZSAub3ZlcnJ1bgotCQlzaHIgY2wsNgotCQl4Y2hnIGNsLGNoCQk7IE5vdyAo RSlDWCA8LSBjeWxpbmRlciBudW1iZXIKLQkJbXVsIGVjeAkJCTsgZWF4IDwtIEhlYWRzKmN5bCMg KGVkeCA8LSAwKQotCQlhZGQgZWF4LGVkaQotCQltdWwgZHdvcmQgW1NlY3RvcnNdCi0JCWFkZCBl YXgsZWJ4Ci0JCTsgTm93IGVheCA9IExCQSwgZWR4ID0gMAotCi0JCTsKLQkJOyBzZXR1cF9yZWdz IGNvbnRpbnVlcy4uLgotCQk7Ci0JCTsgTm90ZTogZWRpWzMxOjE2XSBhbmQgZWN4WzMxOjE2XSA9 IDAgYWxyZWFkeQotCQltb3YgZGksUF9CWAkJOyBHZXQgbGluZWFyIGFkZHJlc3Mgb2YgdGFyZ2V0 IGJ1ZmZlcgotCQltb3YgY3gsUF9FUwotCQlzaGwgZWN4LDQKLQkJYWRkIGVkaSxlY3gJCTsgRURJ ID0gYWRkcmVzcyB0byBmZXRjaCB0bwotCQltb3Z6eCBlY3gsUF9BTAkJOyBTZWN0b3IgY291bnQK LQkJbW92IGVzaSxlYXgKLQkJYWRkIGVheCxlY3gJCTsgTEJBIG9mIGZpbmFsIHNlY3RvciArIDEK LQkJc2hsIGVzaSxTRUNUT1JTSVpFX0xHMgk7IExCQSAtPiBieXRlIG9mZnNldAotCQlhZGQgZXNp LFtEaXNrQnVmXQk7IEdldCBhZGRyZXNzIGluIGhpZ2ggbWVtb3J5Ci0JCWNtcCBlYXgsW0Rpc2tT aXplXQk7IENoZWNrIHRoZSBoaWdoIG1hcmsgYWdhaW5zdCBsaW1pdAotCQlqYSAub3ZlcnJ1bgot CQlzaGwgZWN4LFNFQ1RPUlNJWkVfTEcyLTIgOyBDb252ZXJ0IGNvdW50IHRvIGR3b3JkcwotCQly ZXQKLQotLm92ZXJydW46CXBvcCBheAkJCTsgRHJvcCBzZXR1cF9yZWdzIHJldHVybiBhZGRyZXNz Ci0JCW1vdiBheCwwMjAwaAkJOyBNaXNzaW5nIGFkZHJlc3MgbWFyawotCQlyZXQJCQk7IFJldHVy biB0byBEb25lCi0KLQkJOyBTZXQgdXAgcmVnaXN0ZXJzIGFzIGZvciBhbiBFREQgUmVhZCwgYW5k IGNvbXBhcmVzIGFnYWluc3QgZGlzayBzaXplLgotJWlmIEVERAotZWRkX3NldHVwX3JlZ3M6Ci0J CXB1c2ggZXMKLQkJbW92IHNpLFBfU0kJCTsgRFM6U0kgLT4gREFQQQotCQltb3YgZXMsUF9EUwot Ci0JCW1vdiBkeCxbZXM6c2ldCi0JCWNtcCBkeCwxNgotCQlqYiAuYmFkZGFwYQotCi0JCWNtcCBk d29yZCBbZXM6c2krNF0sLTEKLQkJamUgLmxpbmVhcl9hZGRyZXNzCi0KLQkJbW92enggZWJ4LHdv cmQgW2VzOnNpKzRdCTsgT2Zmc2V0Ci0JCW1vdnp4IGVkaSx3b3JkIFtlczpzaSs2XQk7IFNlZ21l bnQKLQkJc2hsIGVkaSw0Ci0JCWFkZCBlYngsZWRpCi0JCWptcCAuZ290X2FkZHJlc3MKLQotLmxp bmVhcl9hZGRyZXNzOgotCQljbXAgZHgsMjQJCTsgTXVzdCBiZSBsYXJnZSBlbm91Z2ggdG8gaG9s ZAotCQkJCQk7IGxpbmVhciBhZGRyZXNzCi0JCWpiIC5iYWRkYXBhCi0KLQkJY21wIGR3b3JkIFtl czpzaSsyMF0sMAk7ID4gNCBHQiBhZGRyZXNzZXMgbm90IHN1cHBvcnRlZAotCQltb3YgYXgsMDkw MGgJCTsgIkRhdGEgYm91bmRhcnkgZXJyb3IiIC0gYm9ndXMsIGJ1dAotCQkJCQk7IG5vIHJlYWxs eSBiZXR0ZXIgY29kZSBhdmFpbGFibGUKLQkJam5lIC5lcnJvcgotCi0JCW1vdiBlYngsW2VzOnNp KzE2XQotCi0uZ290X2FkZHJlc3M6Ci0JCWNtcCBkd29yZCBbZXM6c2krMTJdLDAJCTsgTEJBIHRv byBsYXJnZT8KLQkJam5lIC5vdmVycnVuCi0KLQkJbW92enggZWN4LCB3b3JkIFtlczpzaSsyXQk7 IFNlY3RvcnMgdG8gdHJhbnNmZXIKLQkJbW92IGVzaSxbZXM6c2krOF0JCTsgU3RhcnRpbmcgc2Vj dG9yCi0JCW1vdiBlYXgsZXNpCi0JCWFkZCBlYXgsZWN4Ci0JCWpjIC5vdmVycnVuCi0JCWNtcCBl YXgsW0Rpc2tTaXplXQotCQlqYSAub3ZlcnJ1bgotCi0JCXNobCBlY3gsU0VDVE9SU0laRV9MRzIt Mgk7IENvbnZlcnQgdG8gZHdvcmRzCi0JCXNobCBlc2ksU0VDVE9SU0laRV9MRzIJCTsgQ29udmVy dCB0byBhbiBvZmZzZXQKLQkJYWRkIGVzaSxbRGlza0J1Zl0KLQkJbW92IGVkaSxlYngKLQkJcG9w IGVzCi0JCXJldAotCi0uYmFkZGFwYToKLQkJbW92IGF4LDAxMDBoCQk7IEludmFsaWQgY29tbWFu ZAotCQlwb3AgZXMKLQkJcG9wIGF4CQkJOyBEcm9wIHNldHVwX3JlZ3MgcmV0dXJuIGFkZHJlc3MK LQkJcmV0Ci0KLS5vdmVycnVuOgotCQltb3YgYXgsMDIwMGgJCTsgIkFkZHJlc3MgbWFyayBub3Qg Zm91bmQiID0KLQkJCQkJOyBMQkEgYmV5b25kIGVuZCBvZiBkaXNrCi0uZXJyb3I6Ci0JCWFuZCB3 b3JkIFtlczpzaSsyXSwwCTsgTm8gc2VjdG9ycyB0cmFuc2ZlcnJlZAotCQlwb3AgZXMKLQkJcG9w IGF4Ci0JCXJldAotCi1FRERFamVjdDoKLQkJbW92IGF4LDBCMjAwaAkJOyBWb2x1bWUgTm90IFJl bW92YWJsZQotCQlyZXQKLQotJWVuZGlmIDsgRURECi0KLQotOwotOyBJTlQgMTVoIGludGVyY2Vw dCByb3V0aW5lcwotOwotaW50MTVfZTgyMDoKLQkJY21wIGVkeCw1MzRENDE1MGgJOyAiU01BUCIK LQkJam5lIG9sZGludDE1Ci0JCWNtcCBlY3gsMjAJCTsgTmVlZCAyMCBieXRlcwotCQlqYiBlcnI4 NgotCQlwdXNoIGRzCi0JCXB1c2ggY3MKLQkJcG9wIGRzCi0JCXB1c2ggZWR4CQk7ICJTTUFQIgot CQlhbmQgZWJ4LGVieAotCQlqbmUgLnJlbmV3Ci0JCW1vdiBlYngsRTgyMFRhYmxlCi0ucmVuZXc6 Ci0JCWFkZCBieCwxNgkJOyBBZHZhbmNlIHRvIG5leHQKLQkJbW92IGVheCxbYngtOF0JCTsgVHlw ZQotCQlhbmQgZWF4LGVheAkJOyBOdWxsIHR5cGU/Ci0JCWp6IC5yZW5ldwkJOyBJZiBzbyBhZHZh bmNlIHRvIG5leHQKLQkJbW92IFtlczpkaSsxNl0sZWF4Ci0JCWFuZCBjbCx+MwotCQljbXAgZWN4 LDI0Ci0JCWpiIC5ub19leHRhdHRyCi0JCW1vdiBlYXgsW2J4LTRdCQk7IEV4dGVuZGVkIGF0dHJp YnV0ZXMKLQkJbW92IFtlczpkaSsyMF0sZWF4Ci0JCW1vdiBlY3gsMjQJCTsgQnl0ZXMgbG9hZGVk Ci0ubm9fZXh0YXR0cjoKLQkJbW92IGVheCxbYngtMTZdCQk7IFN0YXJ0IGFkZHIgKGxvdykKLQkJ bW92IGVkeCxbYngtMTJdCQk7IFN0YXJ0IGFkZHIgKGhpZ2gpCi0JCW1vdiBbZXM6ZGldLGVheAot CQltb3YgW2VzOmRpKzRdLGVkeAotCQltb3YgZWF4LFtieF0JCTsgRW5kIGFkZHIgKGxvdykKLQkJ bW92IGVkeCxbYngrNF0JCTsgRW5kIGFkZHIgKGhpZ2gpCi0JCXN1YiBlYXgsW2J4LTE2XQkJOyBE ZXJpdmUgdGhlIGxlbmd0aAotCQlzYmIgZWR4LFtieC0xMl0KLQkJbW92IFtlczpkaSs4XSxlYXgJ OyBMZW5ndGggKGxvdykKLQkJbW92IFtlczpkaSsxMl0sZWR4CTsgTGVuZ3RoIChoaWdoKQotCQlj bXAgZHdvcmQgW2J4KzhdLC0xCTsgVHlwZSBvZiBuZXh0ID0gZW5kPwotCQlqbmUgLm5vdGRvbmUK LQkJeG9yIGVieCxlYngJCTsgRG9uZSB3aXRoIHRhYmxlCi0ubm90ZG9uZToKLQkJcG9wIGVheAkJ CTsgIlNNQVAiCi0JCW1vdiBlZHgsZWF4CQk7IFNvbWUgc3lzdGVtcyBleHBlY3QgZWF4ID0gZWR4 ID0gU01BUAotCQlwb3AgZHMKLWludDE1X3N1Y2Nlc3M6Ci0JCW1vdiBieXRlIFticCs2XSwgMDJo CTsgQ2xlYXIgQ0YKLQkJcG9wIGJwCi0JCWlyZXQKLQotZXJyODY6Ci0JCW1vdiBieXRlIFticCs2 XSwgMDNoCTsgU2V0IENGCi0JCW1vdiBhaCw4NmgKLQkJcG9wIGJwCi0JCWlyZXQKLQotSW50MTVT dGFydDoKLQkJcHVzaCBicAotCQltb3YgYnAsc3AKLQkJY21wIGF4LDBFODIwaAotCQlqZSBuZWFy IGludDE1X2U4MjAKLQkJY21wIGF4LDBFODAxaAotCQlqZSBpbnQxNV9lODAxCi0JCWNtcCBheCww RTg4MWgKLQkJamUgaW50MTVfZTg4MQotCQljbXAgYWgsODhoCi0JCWplIGludDE1Xzg4Ci1vbGRp bnQxNToJcG9wIGJwCi0JCWptcCBmYXIgW2NzOk9sZEludDE1XQotCi1pbnQxNV9lODAxOgotCQlt b3YgYXgsW2NzOk1lbTFNQl0KLQkJbW92IGN4LGF4Ci0JCW1vdiBieCxbY3M6TWVtMTZNQl0KLQkJ bW92IGR4LGJ4Ci0JCWptcCBzaG9ydCBpbnQxNV9zdWNjZXNzCi0KLWludDE1X2U4ODE6Ci0JCW1v diBlYXgsW2NzOk1lbTFNQl0KLQkJbW92IGVjeCxlYXgKLQkJbW92IGVieCxbY3M6TWVtMTZNQl0K LQkJbW92IGVkeCxlYngKLQkJam1wIHNob3J0IGludDE1X3N1Y2Nlc3MKLQotaW50MTVfODg6Ci0J CW1vdiBheCxbY3M6TWVtSW50MTU4OF0KLQkJam1wIHNob3J0IGludDE1X3N1Y2Nlc3MKLQotOwot OyBSb3V0aW5lIHRvIGNvcHkgaW4vb3V0IG9mIGhpZ2ggbWVtb3J5Ci07IGVzaSA9IGxpbmVhciBz b3VyY2UgYWRkcmVzcwotOyBlZGkgPSBsaW5lYXIgdGFyZ2V0IGFkZHJlc3MKLTsgZWN4ID0gMzIt Yml0IHdvcmQgY291bnQKLTsKLTsgQXNzdW1lcyBjcyA9IGRzID0gZXMKLTsKLWJjb3B5OgotCQlw dXNoIGVheAotCQlwdXNoIGVieAotCQlwdXNoIGVkeAotCQlwdXNoIGVicAotCi0JCW1vdiBieCwg cmVhbF9pbnQxNV9zdHViCi0KLQkJdGVzdCBieXRlIFtDb25maWdGbGFnc10sIENPTkZJR19SQVd8 Q09ORklHX1NBRkVJTlQKLQkJanogLmFueW1vZGUJCTsgQWx3YXlzIGRvIHRoZSByZWFsIElOVCAx NWgKLQotCQlzbXN3IGF4CQkJOyBVbnByaXZpbGVnZWQhCi0JCXRlc3QgYWwsMDFoCi0JCWpueiAu cHJvdG1vZGUJCTsgUHJvdG1vZGUgLT4gZG8gcmVhbCBJTlQgMTVoCi0KLS5yZWFsbW9kZToKLQkJ OyBSYXcgb3IgU2FmZWludCBtb2RlLCBhbmQgd2UncmUgaW4gcmVhbCBtb2RlLi4uCi0KLQkJdGVz dCBieXRlIFtDb25maWdGbGFnc10sIENPTkZJR19TQUZFSU5UCi0JCWpueiAuZmFrZWludDE1Ci0K LS5yYXc6Ci0JCVRSQUNFUiAncicKLQkJOyBXZSdyZSBpbiByZWFsIG1vZGUsIGRvIGl0IG91dHNl bHZlcwotCi0JCXB1c2hmZAkJCTsgPEE+Ci0JCXB1c2ggZHMJCQk7IDxCPgotCQlwdXNoIGVzCQkJ OyA8Qz4KLQotCQljbGkKLQkJY2xkCi0KLQkJeG9yIGVieCxlYngKLQkJbW92IGJ4LGNzCi0JCXNo bCBlYngsNAotCQlsZWEgZWR4LFtTaGFrZXIrZWJ4XQotCQltb3YgW1NoYWtlcisyXSxlZHgKLQot CQk7IFRlc3QgdG8gc2VlIGlmIEEyMCBpcyBlbmFibGVkIG9yIG5vdAotCQl4b3IgYXgsYXgKLQkJ bW92IGRzLGF4Ci0JCWRlYyBheAotCQltb3YgZXMsYXgKLQotCQltb3YgYXgsWzBdCi0JCW1vdiBi eCxheAotCQl4b3IgYngsW2VzOjEwaF0KLQkJbm90IGF4Ci0JCW1vdiBbMF0sYXgKLQkJbW92IGR4 LGF4Ci0JCXhvciBkeCxbZXM6MTBoXQotCQlub3QgYXgKLQkJbW92IFswXSxheAotCi0JCW9yIGR4 LGJ4Ci0JCXB1c2ggZHgJCQk7IDxEPiBTYXZlIEEyMCBzdGF0dXMKLQkJam56IC5za2lwX2EyMGUK LQotCQltb3YgYXgsMjQwMWgJCTsgRW5hYmxlIEEyMAotCQlpbnQgMTVoCi0uc2tpcF9hMjBlOgot CQltb3YgZGwsW0NvbmZpZ0ZsYWdzXQotCQlhbmQgZHgsQ09ORklHX0JJR1JBVwotCQlhZGQgZHgs OAotCQk7IERYID0gMTYgZm9yIEJJR1JBVywgOCBmb3IgUkFXCi0JCTsgIDggaXMgc2VsZWN0b3Ig Zm9yIGEgNjRLIGZsYXQgc2VnbWVudCwKLQkJOyAxNiBpcyBzZWxlY3RvciBmb3IgYSA0R0IgZmxh dCBzZWdtZW50LgotCi0JCWxnZHQgW2NzOlNoYWtlcl0KLQkJbW92IGVheCxjcjAKLQkJb3IgYWws MDFoCi0JCW1vdiBjcjAsZWF4Ci0KLQkJbW92IGJ4LDE2CQk7IExhcmdlIGZsYXQgc2VnbWVudAot CQltb3YgZHMsYngKLQkJbW92IGVzLGJ4Ci0KLQkJYTMyIHJlcCBtb3ZzZAotCi0JCTsgRFggaGFz IHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSB0byBwdXQgaW4KLQkJOyB0aGUgcmVnaXN0ZXJzIG9uIHJl dHVybgotCQltb3YgZHMsZHgKLQkJbW92IGVzLGR4Ci0KLQkJYW5kIGFsLH4wMWgKLQkJbW92IGNy MCxlYXgKLQotCQlwb3AgZHgJCQk7IDxEPiBBMjAgc3RhdHVzCi0JCXBvcCBlcwkJCTsgPEM+Ci0J CXBvcCBkcwkJCTsgPEI+Ci0KLQkJYW5kIGR4LGR4Ci0JCWpueiAuc2tpcF9hMjBkCi0JCW1vdiBh eCwyNDAwaAkJOyBEaXNhYmxlIEEyMAotCQlpbnQgMTVoCi0uc2tpcF9hMjBkOgotCQlwb3BmZAkJ CTsgPEE+Ci0JCWptcCAuZG9uZQotCi0uZmFrZWludDE1OgotCQk7IFdlJ3JlIGluIHJlYWwgbW9k ZSB3aXRoIENPTkZJR19TQUZFSU5ULCBpbnZva2UgdGhlCi0JCTsgb3JpZ2luYWwgSU5UIDE1aCB2 ZWN0b3IuICBXZSB1c2VkIHRvIHRlc3QgZm9yIHRoZQotCQk7IElOVCAxNWggdmVjdG9yIGJlaW5n IHVuY2hhbmdlZCBoZXJlLCBidXQgdGhhdCBpcwotCQk7ICp1cyo7IGhvd2V2ZXIsIHRoZSB0ZXN0 IHdhcyB3cm9uZyBmb3IgeWVhcnMgKGFsd2F5cwotCQk7IG5lZ2F0aXZlKSBzbyBpbnN0ZWFkIG9m IGZpeGluZyB0aGUgdGVzdCBkbyB3aGF0IHdlCi0JCTsgdGVzdGVkIGFuZCBkb24ndCBib3RoZXIg cHJvYmluZy4KLQkJbW92IGJ4LCBmYWtlX2ludDE1X3N0dWIKLQotLnByb3Rtb2RlOgotCQlUUkFD RVIgJ3AnCi0uYW55bW9kZToKLQotLmNvcHlfbG9vcDoKLQkJcHVzaCBlc2kKLQkJcHVzaCBlZGkK LQkJcHVzaCBlY3gKLQkJY21wIGVjeCw0MDAwaAotCQlqbmEgLnNhZmVfc2l6ZQotCQltb3YgZWN4 LDQwMDBoCi0uc2FmZV9zaXplOgotCQlwdXNoIGVjeAk7IFRyYW5zZmVyIHNpemUgdGhpcyBjeWNs ZQotCQltb3YgZWF4LCBlc2kKLQkJbW92IFtNb3Zlcl9zcmMxXSwgc2kKLQkJc2hyIGVheCwgMTYK LQkJbW92IFtNb3Zlcl9zcmMxKzJdLCBhbAotCQltb3YgW01vdmVyX3NyYzJdLCBhaAotCQltb3Yg ZWF4LCBlZGkKLQkJbW92IFtNb3Zlcl9kc3QxXSwgZGkKLQkJc2hyIGVheCwgMTYKLQkJbW92IFtN b3Zlcl9kc3QxKzJdLCBhbAotCQltb3YgW01vdmVyX2RzdDJdLCBhaAotCQltb3Ygc2ksTW92ZXIK LQkJbW92IGFoLCA4N2gKLQkJc2hsIGN4LDEJOyBDb252ZXJ0IHRvIDE2LWJpdCB3b3JkcwotCQlj YWxsIGJ4CQk7IElOVCAxNWggc3R1YgotCQlwb3AgZWF4CQk7IFRyYW5zZmVyIHNpemUgdGhpcyBj eWNsZQotCQlwb3AgZWN4Ci0JCXBvcCBlZGkKLQkJcG9wIGVzaQotCQlqYyAuZXJyb3IKLQkJbGVh IGVzaSxbZXNpKzQqZWF4XQotCQlsZWEgZWRpLFtlZGkrNCplYXhdCi0JCXN1YiBlY3gsIGVheAot CQlqbnogLmNvcHlfbG9vcAotCQk7IENGID0gMAotLmVycm9yOgotLmRvbmU6Ci0JCXBvcCBlYnAK LQkJcG9wIGVkeAotCQlwb3AgZWJ4Ci0JCXBvcCBlYXgKLQkJcmV0Ci0KLXJlYWxfaW50MTVfc3R1 YjoKLQkJaW50IDE1aAotCQljbGkJCTsgU29tZSBCSU9TZXMgZW5hYmxlIGludGVycnVwdHMgb24g SU5UIDE1aAotCQlyZXQKLQotZmFrZV9pbnQxNV9zdHViOgotCQlwdXNoZgotCQljYWxsIGZhciBb T2xkSW50MTVdCi0JCWNsaQotCQlyZXQKLQotJWlmZGVmIERFQlVHX1RSQUNFUlMKLWRlYnVnX3Ry YWNlcjoJcHVzaGFkCi0JCXB1c2hmZAotCQltb3YgYnAsc3AKLQkJbW92IGJ4LFticCs5KjRdCi0J CW1vdiBhbCxbY3M6YnhdCi0JCWluYyB3b3JkIFticCs5KjRdCi0JCW1vdiBhaCwwRWgKLQkJbW92 IGJ4LDcKLQkJaW50IDEwaAotCQlwb3BmZAotCQlwb3BhZAotCQlyZXQKLSVlbmRpZgotCi0JCXNl Y3Rpb24gLmRhdGEKLQkJYWxpZ25iIDIKLUludDEzRnVuY3MJZHcgUmVzZXQJCTsgMDBoIC0gUkVT RVQKLQkJZHcgR2V0U3RhdHVzCQk7IDAxaCAtIEdFVCBTVEFUVVMKLQkJZHcgUmVhZAkJCTsgMDJo IC0gUkVBRAotCQlkdyBXcml0ZQkJOyAwM2ggLSBXUklURQotCQlkdyBWZXJpZnkJCTsgMDRoIC0g VkVSSUZZCi0JCWR3IEludmFsaWQJCTsgMDVoIC0gRk9STUFUIFRSQUNLCi0JCWR3IEludmFsaWQJ CTsgMDZoIC0gRk9STUFUIFRSQUNLIEFORCBTRVQgQkFEIEZMQUdTCi0JCWR3IEludmFsaWQJCTsg MDdoIC0gRk9STUFUIERSSVZFIEFUIFRSQUNLCi0JCWR3IEdldFBhcm1zCQk7IDA4aCAtIEdFVCBQ QVJBTUVURVJTCi0JCWR3IEluaXRXaXRoUGFybXMJOyAwOWggLSBJTklUSUFMSVpFIENPTlRST0xM RVIgV0lUSCBEUklWRSBQQVJBTUVURVJTCi0JCWR3IEludmFsaWQJCTsgMEFoCi0JCWR3IEludmFs aWQJCTsgMEJoCi0JCWR3IFNlZWsJCQk7IDBDaCAtIFNFRUsgVE8gQ1lMSU5ERVIKLQkJZHcgUmVz ZXQJCTsgMERoIC0gUkVTRVQgSEFSRCBESVNLUwotCQlkdyBJbnZhbGlkCQk7IDBFaAotCQlkdyBJ bnZhbGlkCQk7IDBGaAotCQlkdyBDaGVja0lmUmVhZHkJCTsgMTBoIC0gQ0hFQ0sgSUYgUkVBRFkK LQkJZHcgUmVjYWxpYnJhdGUJCTsgMTFoIC0gUkVDQUxJQlJBVEUKLQkJZHcgSW52YWxpZAkJOyAx MmgKLQkJZHcgSW52YWxpZAkJOyAxM2gKLQkJZHcgSW52YWxpZAkJOyAxNGgKLQkJZHcgR2V0RHJp dmVUeXBlCQk7IDE1aCAtIEdFVCBEUklWRSBUWVBFCi0JCWR3IERldGVjdENoYW5nZQkJOyAxNmgg LSBERVRFQ1QgRFJJVkUgQ0hBTkdFCi0laWYgRURECi0JCWR3IEludmFsaWQJCTsgMTdoCi0JCWR3 IEludmFsaWQJCTsgMThoCi0JCWR3IEludmFsaWQJCTsgMTloCi0JCWR3IEludmFsaWQJCTsgMUFo Ci0JCWR3IEludmFsaWQJCTsgMUJoCi0JCWR3IEludmFsaWQJCTsgMUNoCi0JCWR3IEludmFsaWQJ CTsgMURoCi0JCWR3IEludmFsaWQJCTsgMUVoCi0JCWR3IEludmFsaWQJCTsgMUZoCi0JCWR3IElu dmFsaWQJCTsgMjBoCi0JCWR3IFJlYWRNdWx0CQk7IDIxaCAtIFJFQUQgTVVMVElQTEUKLQkJZHcg V3JpdGVNdWx0CQk7IDIyaCAtIFdSSVRFIE1VTFRJUExFCi0JCWR3IFNldE1vZGUJCTsgMjNoIC0g U0VUIENPTlRST0xMRVIgRkVBVFVSRVMKLQkJZHcgU2V0TW9kZQkJOyAyNGggLSBTRVQgTVVMVElQ TEUgTU9ERQotCQlkdyBJbnZhbGlkCQk7IDI1aCAtIElERU5USUZZIERSSVZFCi0JCWR3IEludmFs aWQJCTsgMjZoCi0JCWR3IEludmFsaWQJCTsgMjdoCi0JCWR3IEludmFsaWQJCTsgMjhoCi0JCWR3 IEludmFsaWQJCTsgMjloCi0JCWR3IEludmFsaWQJCTsgMkFoCi0JCWR3IEludmFsaWQJCTsgMkJo Ci0JCWR3IEludmFsaWQJCTsgMkNoCi0JCWR3IEludmFsaWQJCTsgMkRoCi0JCWR3IEludmFsaWQJ CTsgMkVoCi0JCWR3IEludmFsaWQJCTsgMkZoCi0JCWR3IEludmFsaWQJCTsgMzBoCi0JCWR3IElu dmFsaWQJCTsgMzFoCi0JCWR3IEludmFsaWQJCTsgMzJoCi0JCWR3IEludmFsaWQJCTsgMzNoCi0J CWR3IEludmFsaWQJCTsgMzRoCi0JCWR3IEludmFsaWQJCTsgMzVoCi0JCWR3IEludmFsaWQJCTsg MzZoCi0JCWR3IEludmFsaWQJCTsgMzdoCi0JCWR3IEludmFsaWQJCTsgMzhoCi0JCWR3IEludmFs aWQJCTsgMzloCi0JCWR3IEludmFsaWQJCTsgM0FoCi0JCWR3IEludmFsaWQJCTsgM0JoCi0JCWR3 IEludmFsaWQJCTsgM0NoCi0JCWR3IEludmFsaWQJCTsgM0RoCi0JCWR3IEludmFsaWQJCTsgM0Vo Ci0JCWR3IEludmFsaWQJCTsgM0ZoCi0JCWR3IEludmFsaWQJCTsgNDBoCi0JCWR3IEVERFByZXNl bmNlCQk7IDQxaCAtIEVERCBQUkVTRU5DRSBERVRFQ1QKLQkJZHcgRUREUmVhZAkJOyA0MmggLSBF REQgUkVBRAotCQlkdyBFRERXcml0ZQkJOyA0M2ggLSBFREQgV1JJVEUKLQkJZHcgRUREVmVyaWZ5 CQk7IDQ0aCAtIEVERCBWRVJJRlkKLQkJZHcgRURETG9jawkJOyA0NWggLSBFREQgTE9DSy9VTkxP Q0sgTUVESUEKLQkJZHcgRURERWplY3QJCTsgNDZoIC0gRUREIEVKRUNUCi0JCWR3IEVERFNlZWsJ CTsgNDdoIC0gRUREIFNFRUsKLQkJZHcgRURER2V0UGFybXMJCTsgNDhoIC0gRUREIEdFVCBQQVJB TUVURVJTCi0JCWR3IEVERERldGVjdENoYW5nZQk7IDQ5aCAtIEVERCBNRURJQSBDSEFOR0UgU1RB VFVTCi0lZW5kaWYKLQotSW50MTNGdW5jc0VuZAllcXUgJAotSW50MTNGdW5jc0NudAllcXUgKElu dDEzRnVuY3NFbmQtSW50MTNGdW5jcykgPj4gMQotCi0KLQkJYWxpZ25iIDgsIGRiIDAKLVNoYWtl cgkJZHcgU2hha2VyRW5kLSQKLQkJZGQgMAkJCTsgUG9pbnRlciB0byBzZWxmCi0JCWR3IDAKLQot U2hha2VyX1JNRFM6CWRkIDB4MDAwMGZmZmYJCTsgNjRLIGRhdGEgc2VnbWVudAotCQlkZCAweDAw MDA5MzAwCi0KLVNoYWtlcl9EUzoJZGQgMHgwMDAwZmZmZgkJOyA0R0IgZGF0YSBzZWdtZW50Ci0J CWRkIDB4MDA4ZjkzMDAKLQotU2hha2VyRW5kCWVxdSAkCi0KLQkJYWxpZ25iIDgsIGRiIDAKLQot TW92ZXIJCWRkIDAsIDAsIDAsIDAJCTsgTXVzdCBiZSB6ZXJvCi0JCWR3IDBmZmZmaAkJOyA2NCBL IHNlZ21lbnQgc2l6ZQotTW92ZXJfc3JjMToJZGIgMCwgMCwgMAkJOyBMb3cgMjQgYml0cyBvZiBz b3VyY2UgYWRkeQotCQlkYiA5M2gJCQk7IEFjY2VzcyByaWdodHMKLQkJZGIgMDBoCQkJOyBFeHRl bmRlZCBhY2Nlc3MgcmlnaHRzCi1Nb3Zlcl9zcmMyOglkYiAwCQkJOyBIaWdoIDggYml0cyBvZiBz b3VyY2UgYWRkeQotCQlkdyAwZmZmZmgJCTsgNjQgSyBzZWdtZW50IHNpemUKLU1vdmVyX2RzdDE6 CWRiIDAsIDAsIDAJCTsgTG93IDI0IGJpdHMgb2YgdGFyZ2V0IGFkZHkKLQkJZGIgOTNoCQkJOyBB Y2Nlc3MgcmlnaHRzCi0JCWRiIDAwaAkJCTsgRXh0ZW5kZWQgYWNjZXNzIHJpZ2h0cwotTW92ZXJf ZHN0MjoJZGIgMAkJCTsgSGlnaCA4IGJpdHMgb2Ygc291cmNlIGFkZHkKLU1vdmVyX2R1bW15MjoJ ZGQgMCwgMCwgMCwgMAkJOyBNb3JlIHNwYWNlIGZvciB0aGUgQklPUwotCi0JCWFsaWduYiA0LCBk YiAwCi1NZW1EaXNrX0luZm8JZXF1ICQJCQk7IFBvaW50ZWQgdG8gYnkgaW5zdGFsbGF0aW9uIGNo ZWNrCi1NRElfQnl0ZXMJZHcgTURJX0xlbgkJOyBUb3RhbCBieXRlcyBpbiBNREkgc3RydWN0dXJl Ci1NRElfVmVyc2lvbglkYiBWRVJTSU9OX01JTk9SLCBWRVJTSU9OX01BSk9SCTsgTUVNRElTSyB2 ZXJzaW9uCi0KLVBhdGNoQXJlYQllcXUgJAkJCTsgVGhpcyBnZXRzIGZpbGxlZCBpbiBieSB0aGUg aW5zdGFsbGVyCi0KLURpc2tCdWYJCWRkIDAJCQk7IExpbmVhciBhZGRyZXNzIG9mIGhpZ2ggbWVt b3J5IGRpc2sKLURpc2tTaXplCWRkIDAJCQk7IFNpemUgb2YgZGlzayBpbiBibG9ja3MKLUNvbW1h bmRMaW5lCWR3IDAsIDAJCQk7IEZhciBwb2ludGVyIHRvIHNhdmVkIGNvbW1hbmQgbGluZQotCi1P bGRJbnQxMwlkZCAwCQkJOyBJTlQgMTNoIGluIGNoYWluCi1PbGRJbnQxNQlkZCAwCQkJOyBJTlQg MTVoIGluIGNoYWluCi0KLU9sZERvc01lbQlkdyAwCQkJOyBPbGQgcG9zaXRpb24gb2YgRE9TIG1l bSBlbmQKLUJvb3RMb2FkZXJJRAlkYiAwCQkJOyBCb290IGxvYWRlciBJRCBmcm9tIGhlYWRlcgot CQlkYiAwCQkJOyBwYWQKLQotRFBUX3B0cgkJZHcgMAkJCTsgSWYgbm9uemVybywgcG9pbnRlciB0 byBEUFQKLQkJCQkJOyBPcmlnaW5hbCBEUFQgcG9pbnRlciBmb2xsb3dzCi0KLU1ESV9MZW4JCWVx dSAkLU1lbURpc2tfSW5mbwotCi07IC0tLS0gTURJIHN0cnVjdHVyZSBlbmRzIGhlcmUgLS0tCi1J bnQxM01heEZ1bmMJZGIgSW50MTNGdW5jc0NudC0xCTsgTWF4IElOVCAxM2ggZnVuY3Rpb24gKHRv IGRpc2FibGUgRUREKQotCQlkYiAwCQkJOyBwYWQKLQotCQlkdyAwCQkJOyBwYWQKLU1lbUludDE1 ODgJZHcgMAkJCTsgMU1CLTY1TUIgbWVtb3J5IGFtb3VudCAoMUspCi0KLUN5bGluZGVycwlkdyAw CQkJOyBDeWxpbmRlciBjb3VudAotSGVhZHMJCWR3IDAJCQk7IEhlYWQgY291bnQKLVNlY3RvcnMJ CWRkIDAJCQk7IFNlY3RvciBjb3VudCAoemVyby1leHRlbmRlZCkKLQotTWVtMU1CCQlkZCAwCQkJ OyAxTUItMTZNQiBtZW1vcnkgYW1vdW50ICgxSykKLU1lbTE2TUIJCWRkIDAJCQk7IDE2TUItNEcg bWVtb3J5IGFtb3VudCAoNjRLKQotCi1Ecml2ZU5vCQlkYiAwCQkJOyBPdXIgZHJpdmUgbnVtYmVy Ci1Ecml2ZVR5cGUJZGIgMAkJCTsgT3VyIGRyaXZlIHR5cGUgKGZsb3BwaWVzKQotRHJpdmVDbnQJ ZGIgMAkJCTsgRHJpdmUgY291bnQgKGZyb20gdGhlIEJJT1MpCi0KLUNvbmZpZ0ZsYWdzCWRiIDAJ CQk7IEJpdCAwIC0gcmVhZG9ubHkKLQotTXlTdGFjawkJZHcgMAkJCTsgT2Zmc2V0IG9mIHN0YWNr Ci1TdGF0dXNQdHIJZHcgMAkJCTsgV2hlcmUgdG8gc2F2ZSBzdGF0dXMgKHplcm9zZWcgcHRyKQot Ci1EUFQJCXRpbWVzIDE2IGRiIDAJCTsgQklPUyBwYXJhbWV0ZXIgdGFibGUgcG9pbnRlciAoZmxv cHBpZXMpCi1PbGRJbnQxRQlkZCAwCQkJOyBQcmV2aW91cyBJTlQgMUUgcG9pbnRlciAoRFBUKQot Ci0laWYgRURECi1FRERfRFBUOgotLmxlbmd0aAkJZHcgMzAKLS5pbmZvCQlkdyAwMDI5aAotCQk7 IEJpdCAwIC0gRE1BIGJvdW5kYXJpZXMgaGFuZGxlZCB0cmFuc3BhcmVudGx5Ci0JCTsgQml0IDMg LSBEZXZpY2Ugc3VwcG9ydHMgd3JpdGUgdmVyaWZ5Ci0JCTsgQml0IDUgLSBNZWRpYSBpcyBsb2Nr YWJsZQotLmN5bGluZGVycwlkZCAwCQkJOyBGaWxsZWQgaW4gYnkgaW5zdGFsbGVyCi0uaGVhZHMJ CWRkIDAJCQk7IEZpbGxlZCBpbiBieSBpbnN0YWxsZXIKLS5zZWN0b3JzCWRkIDAJCQk7IEZpbGxl ZCBpbiBieSBpbnN0YWxsZXIKLS50b3RhbHNpemUJZGQgMCwgMAkJCTsgRmlsbGVkIGluIGJ5IGlu c3RhbGxlcgotLmJ5dGVzcGVyc2VjCWR3IFNFQ1RPUlNJWkUKLS5lZGR0YWJsZQlkdyAtMSwgLTEJ CTsgSW52YWxpZCBEUFRFIHBvaW50ZXIKLQotJWVuZGlmCi0KLQkJOyBFbmQgcGF0Y2ggYXJlYQot U3RhY2sJCWRkIDAJCQk7IFNhdmVkIFNTOkVTUCBvbiBpbnZvY2F0aW9uCi0JCWR3IDAKLVNhdmVk QVgJCWR3IDAJCQk7IEFYIHNhdmVkIG9uIGludm9jYXRpb24KLQotCQlhbGlnbmIgNCwgZGIgMAkJ OyBXZSAqTVVTVCogZW5kIG9uIGEgZHdvcmQgYm91bmRhcnkKLQotRTgyMFRhYmxlCWVxdSAkCQkJ OyBUaGUgaW5zdGFsbGVyIGxvYWRzIHRoZSBFODIwIHRhYmxlIGhlcmUKLVRvdGFsU2l6ZQllcXUg JAkJCTsgRW5kIHBvaW50ZXIKKyVpbmNsdWRlICJtZW1kaXNrLmluYyIKZGlmZiAtLWdpdCBhL21l bWRpc2svbWVtZGlzay5pbmMgYi9tZW1kaXNrL21lbWRpc2suaW5jCm5ldyBmaWxlIG1vZGUgMTAw NjQ0CmluZGV4IDAwMDAwMDAuLjJiNWI0ZTAKLS0tIC9kZXYvbnVsbAorKysgYi9tZW1kaXNrL21l bWRpc2suaW5jCkBAIC0wLDAgKzEsOTg3IEBACis7IC0qLSBmdW5kYW1lbnRhbCAtKi0gKGFzbS1t b2RlIHN1Y2tzKQorOyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCis7Cis7ICBtZW1kaXNrLmluYworOwor OyAgQSBwcm9ncmFtIHRvIGVtdWxhdGUgYW4gSU5UIDEzaCBkaXNrIEJJT1MgZnJvbSBhICJkaXNr IiBpbiBleHRlbmRlZAorOyAgbWVtb3J5LgorOworOyAgIENvcHlyaWdodCAyMDAxLTIwMDggSC4g UGV0ZXIgQW52aW4gLSBBbGwgUmlnaHRzIFJlc2VydmVkCis7Cis7ICBUaGlzIHByb2dyYW0gaXMg ZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQorOyAg aXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBw dWJsaXNoZWQgYnkKKzsgIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sIDUzIFRl bXBsZSBQbGFjZSBTdGUgMzMwLAorOyAgQm9zdG9uIE1BIDAyMTExLTEzMDcsIFVTQTsgZWl0aGVy IHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKKzsgIChhdCB5b3VyIG9wdGlvbikgYW55IGxh dGVyIHZlcnNpb247IGluY29ycG9yYXRlZCBoZXJlaW4gYnkgcmVmZXJlbmNlLgorOworOyAqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqCisKKyVpZm5kZWYgREVQRU5ECislaW5jbHVkZQkiLi4vdmVyc2lvbi5n ZW4iCislZW5kaWYKKworOyAlZGVmaW5lIERFQlVHX1RSQUNFUlMJCQk7IFVuY29tbWVudCB0byBn ZXQgZGVidWdnaW5nIHRyYWNlcnMKKworJWlmZGVmIFdJVEhfRURECislZGVmaW5lIEVERCAxCisl ZWxzZQorJWRlZmluZSBFREQgMAorJWVuZGlmCisKKyVpZmRlZiBERUJVR19UUkFDRVJTCisKKyVt YWNybyBUUkFDRVIJMQorCWNhbGwgZGVidWdfdHJhY2VyCisJZGIgJTEKKyVlbmRtYWNybworCisl ZWxzZQk7IERFQlVHX1RSQUNFUlMKKworJW1hY3JvCVRSQUNFUgkxCislZW5kbWFjcm8KKworJWVu ZGlmCTsgREVCVUdfVFJBQ0VSUworCislZGVmaW5lIENPTkZJR19SRUFET05MWQkweDAxCislZGVm aW5lIENPTkZJR19SQVcJMHgwMgorJWRlZmluZSBDT05GSUdfU0FGRUlOVAkweDA0CislZGVmaW5l IENPTkZJR19CSUdSQVcJMHgwOAkJOyBNVVNUIGJlIDghCisKKwkJb3JnIDBoCisKKyVkZWZpbmUg U0VDVE9SU0laRV9MRzIJOQkJOyBsb2cyKHNlY3RvciBzaXplKQorJWRlZmluZQlTRUNUT1JTSVpF CSgxIDw8IFNFQ1RPUlNJWkVfTEcyKQorCisJCTsgUGFyYW1ldGVyIHJlZ2lzdGVycyBkZWZpbml0 aW9uOyB0aGlzIGlzIHRoZSBkZWZpbml0aW9uCisJCTsgb2YgdGhlIHN0YWNrIGZyYW1lLgorJWRl ZmluZQkJUF9EUwkJd29yZCBbYnArMzRdCislZGVmaW5lCQlQX0VTCQl3b3JkIFticCszMl0KKyVk ZWZpbmUJCVBfRUFYCQlkd29yZCBbYnArMjhdCislZGVmaW5lCQlQX0hBWAkJd29yZCBbYnArMzBd CislZGVmaW5lCQlQX0FYCQl3b3JkIFticCsyOF0KKyVkZWZpbmUJCVBfQUwJCWJ5dGUgW2JwKzI4 XQorJWRlZmluZQkJUF9BSAkJYnl0ZSBbYnArMjldCislZGVmaW5lCQlQX0VDWAkJZHdvcmQgW2Jw KzI0XQorJWRlZmluZQkJUF9IQ1gJCXdvcmQgW2JwKzI2XQorJWRlZmluZQkJUF9DWAkJd29yZCBb YnArMjRdCislZGVmaW5lCQlQX0NMCQlieXRlIFticCsyNF0KKyVkZWZpbmUJCVBfQ0gJCWJ5dGUg W2JwKzI1XQorJWRlZmluZQkJUF9FRFgJCWR3b3JkIFticCsyMF0KKyVkZWZpbmUJCVBfSERYCQl3 b3JkIFticCsyMl0KKyVkZWZpbmUJCVBfRFgJCXdvcmQgW2JwKzIwXQorJWRlZmluZQkJUF9ETAkJ Ynl0ZSBbYnArMjBdCislZGVmaW5lCQlQX0RICQlieXRlIFticCsyMV0KKyVkZWZpbmUJCVBfRUJY CQlkd29yZCBbYnArMTZdCislZGVmaW5lCQlQX0hCWAkJd29yZCBbYnArMThdCislZGVmaW5lCQlQ X0hCWEwJCWJ5dGUgW2JwKzE4XQorJWRlZmluZQkJUF9CWAkJd29yZCBbYnArMTZdCislZGVmaW5l CQlQX0JMCQlieXRlIFticCsxNl0KKyVkZWZpbmUJCVBfQkgJCWJ5dGUgW2JwKzE3XQorJWRlZmlu ZQkJUF9FQlAJCWR3b3JkIFticCs4XQorJWRlZmluZQkJUF9CUAkJd29yZCBbYnArOF0KKyVkZWZp bmUJCVBfRVNJCQlkd29yZCBbYnArNF0KKyVkZWZpbmUJCVBfU0kJCXdvcmQgW2JwKzRdCislZGVm aW5lCQlQX0VESQkJZHdvcmQgW2JwXQorJWRlZmluZQkJUF9ESQkJd29yZCBbYnBdCisKKwkJc2Vj dGlvbiAudGV4dAorCQk7IFRoZXNlIHBvaW50ZXJzIGFyZSB1c2VkIGJ5IHRoZSBpbnN0YWxsZXIg YW5kCisJCTsgbXVzdCBiZSBmaXJzdCBpbiB0aGUgYmluYXJ5CitQb2ludGVyczoJZHcgSW50MTNT dGFydAorCQlkdyBJbnQxNVN0YXJ0CisJCWR3IFBhdGNoQXJlYQorCQlkdyBUb3RhbFNpemUKKwkJ ZHcgSXJldFB0cgorCitJcmV0UHRyCQllcXUgSW50MTNTdGFydC5pcmV0CitJbnQxM1N0YXJ0Ogor CQk7IFN3YXAgc3RhY2sKKwkJbW92IFtjczpTdGFja10sZXNwCisJCW1vdiBbY3M6U2F2ZWRBWF0s YXgKKwkJbW92IGF4LHNzCisJCW1vdiBbY3M6U3RhY2srNF0sYXgKKwkJbW92IGF4LGNzCisJCW1v diBzcyxheAorCQltb3Ygc3AsW2NzOk15U3RhY2tdCisKKwkJOyBTZWUgaWYgREwgcG9pbnRzIHRv IG91ciBjbGFzcyBvZiBkZXZpY2UgKEZELCBIRCkKKwkJcHVzaCBkeAorCQlwdXNoIGR4CisJCXhv ciBkbCxbY3M6RHJpdmVOb10KKwkJcG9wIGR4CisJCWpzIC5ub21hdGNoCQk7IElmIFNGPTAsIHdl IGhhdmUgYSBjbGFzcyBtYXRjaCBoZXJlCisJCWp6IC5vdXJfZHJpdmUJCTsgSWYgWkY9MSwgd2Ug aGF2ZSBhbiBleGFjdCBtYXRjaAorCQljbXAgZGwsW2NzOkRyaXZlTm9dCisJCWpiIC5ub21hdGNo CQk7IERyaXZlIDwgT3VyIGRyaXZlCisJCWRlYyBkbAkJCTsgRHJpdmUgPiBPdXIgZHJpdmUsIGFk anVzdCBkcml2ZSAjCisubm9tYXRjaDoKKwkJbW92IGF4LFtjczpTYXZlZEFYXQorCQlwdXNoZgor CQljYWxsIGZhciBbY3M6T2xkSW50MTNdCisJCXB1c2hmCisJCXB1c2ggYnAKKwkJbW92IGJwLHNw CisJCWNtcCBieXRlIFtjczpTYXZlZEFYKzFdLDA4aAorCQlqZSAubm9yZXN0b3JlZGwKKwkJY21w IGJ5dGUgW2NzOlNhdmVkQVgrMV0sMTVoCisJCWpuZSAucmVzdG9yZWRsCisJCXRlc3QgYnl0ZSBb YnArNF0sODBoCTsgSGFyZCBkaXNrPworCQlqbnogLm5vcmVzdG9yZWRsCisucmVzdG9yZWRsOgor CQltb3YgZGwsW2JwKzRdCisubm9yZXN0b3JlZGw6CisJCXB1c2ggYXgKKwkJcHVzaCBlYngKKwkJ cHVzaCBkcworCQltb3YgYXgsW2JwKzJdCQk7IEZsYWdzCisJCWxkcyBlYngsW2NzOlN0YWNrXQor CQltb3YgW2J4KzRdLGFsCQk7IEFyaXRobWV0cmljIGZsYWdzCisJCXBvcCBkcworCQlwb3AgZWJ4 CisJCXBvcCBheAorCQlwb3AgYnAKKwkJbHNzIGVzcCxbY3M6U3RhY2tdCisuaXJldDoJCWlyZXQK KworLm91cl9kcml2ZToKKwkJOyBTZXQgdXAgc3RhbmRhcmQgZW50cnkgZnJhbWUKKwkJcHVzaCBk cworCQlwdXNoIGVzCisJCW1vdiBkcyxheAorCQltb3YgZXMsYXgKKwkJbW92IGF4LFtTYXZlZEFY XQorCQlwdXNoYWQKKwkJbW92IGJwLHNwCQk7IFBvaW50IEJQIHRvIHRoZSBlbnRyeSBzdGFjayBm cmFtZQorCQlUUkFDRVIgJ0YnCisJCTsgTm90ZTogQUggPT0gUF9BSCBoZXJlCisJCWNtcCBhaCxb SW50MTNNYXhGdW5jXQorCQlqYSBJbnZhbGlkX2p1bXAKKwkJeG9yIGFsLGFsCQk7IEFMID0gMCBp cyBzdGFuZGFyZCBlbnRyeSBjb25kaXRpb24KKwkJbW92IGRpLGF4CisJCXNociBkaSw3CQk7IENv bnZlcnQgQUggdG8gYW4gb2Zmc2V0IGluIERJCisJCWNhbGwgW0ludDEzRnVuY3MrZGldCisKK0Rv bmU6CQk7IFN0YW5kYXJkIHJvdXRpbmUgZm9yIHJldHVybgorCQltb3YgUF9BWCxheAorRG9uZVdl aXJkOgorCQlUUkFDRVIgJ0QnCisJCXhvciBieCxieAorCQltb3YgZXMsYngKKwkJbW92IGJ4LFtT dGF0dXNQdHJdCisJCW1vdiBbZXM6YnhdLGFoCQk7IFNhdmUgc3RhdHVzCisJCWFuZCBhaCxhaAor CisJCWxkcyBlYngsW1N0YWNrXQorCQk7IFRoaXMgc2V0cyB0aGUgbG93IGJ5dGUgKHRoZSBhcml0 aG1ldHJpYyBmbGFncykgb2YgdGhlCisJCTsgRkxBR1Mgb24gc3RhY2sgdG8gZWl0aGVyIDAwaCAo bm8gZmxhZ3MpIG9yIDAxaCAoQ0YpCisJCTsgZGVwZW5kaW5nIG9uIGlmIEFIIHdhcyB6ZXJvIG9y IG5vdC4KKwkJc2V0bnogW2J4KzRdCQk7IFNldCBDRiBpZmYgZXJyb3IKKwkJcG9wYWQKKwkJcG9w IGVzCisJCXBvcCBkcworCQlsc3MgZXNwLFtjczpTdGFja10KKwkJaXJldAorCitSZXNldDoKKwkJ OyBSZXNldCBhZmZlY3RzIG11bHRpcGxlIGRyaXZlcywgc28gd2UgbmVlZCB0byBwYXNzIGl0IG9u CisJCVRSQUNFUiAnUicKKwkJeG9yIGF4LGF4CQk7IEJvdHRvbSBvZiBtZW1vcnkKKwkJbW92IGVz LGF4CisJCXRlc3QgZGwsZGwJCTsgQWx3YXlzIHBhc3MgaXQgb24gaWYgd2UgYXJlIHJlc2V0dGlu ZyBIRAorCQlqcyAuaGFyZF9kaXNrCQk7IEJpdCA3IHNldAorCQk7IFNvbWUgQklPU2VzIGdldCB2 ZXJ5IHVuaGFwcHkgaWYgd2UgcGFzcyBhIHJlc2V0IGZsb3BweQorCQk7IGNvbW1hbmQgdG8gdGhl bSBhbmQgZG9uJ3QgYWN0dWFsbHkgaGF2ZSBhbnkgZmxvcHBpZXMuCisJCTsgVGhpcyBpcyBhIGJ1 ZywgYnV0IHdlIGhhdmUgdG8gZGVhbCB3aXRoIGl0IG5vbnRoZWxlc3MuCisJCTsgVGhlcmVmb3Jl LCBpZiB3ZSBhcmUgdGhlICpPTkxZKiBmbG9wcHkgZHJpdmUsIGFuZCB0aGUKKwkJOyB1c2VyIGRp ZG4ndCByZXF1ZXN0IEhEIHJlc2V0LCB0aGVuIGp1c3QgZHJvcCB0aGUgY29tbWFuZC4KKwkJOyBC SU9TIGVxdWlwbWVudCBieXRlLCB0b3AgdHdvIGJpdHMgKyAxID09IHRvdGFsICMgb2YgZmxvcHBp ZXMKKwkJdGVzdCBieXRlIFtlczoweDQxMF0sMEMwaAorCQlqeiBzdWNjZXNzCisJCWptcCAucGFz c19vbgkJOyAuLi4gb3RoZXJ3aXNlIHBhc3MgaXQgdG8gdGhlIEJJT1MKKy5oYXJkX2Rpc2s6CisJ CTsgLi4uIHNhbWUgdGhpbmcgZm9yIGhhcmQgZGlza3MsIHNpZ2ggLi4uCisJCWNtcCBieXRlIFtl czoweDQ3NV0sMQk7IEJJT1MgdmFyaWFibGUgZm9yIG51bWJlciBvZiBoYXJkIGRpc2tzCisJCWpi ZSBzdWNjZXNzCisKKy5wYXNzX29uOgorCQlwb3AgYXgJCQk7IERyb3AgcmV0dXJuIGFkZHJlc3MK KwkJcG9wYWQJCQk7IFJlc3RvcmUgYWxsIHJlZ2lzdGVycworCQlwb3AgZXMKKwkJcG9wIGRzCisJ CWxzcyBlc3AsW2NzOlN0YWNrXQk7IFJlc3RvcmUgdGhlIHN0YWNrCisJCWFuZCBkbCw4MGgJCTsg Q2xlYXIgYWxsIGJ1dCB0aGUgdHlwZSBiaXQKKwkJam1wIGZhciBbY3M6T2xkSW50MTNdCisKKwor SW52YWxpZDoKKwkJcG9wIGR4CQkJOyBEcm9wIHJldHVybiBhZGRyZXNzCitJbnZhbGlkX2p1bXA6 CisJCVRSQUNFUiAnSScKKwkJbW92IGFoLDAxaAkJOyBVbnN1cHBvcnRlZCBmdW5jdGlvbgorCQlq bXAgc2hvcnQgRG9uZQorCitHZXREcml2ZVR5cGU6CisJCXRlc3QgYnl0ZSBbRHJpdmVOb10sODBo CisJCW1vdiBibCwwMmgJCTsgVHlwZSAwMmggPSBmbG9wcHkgd2l0aCBjaGFuZ2VsaW5lCisJCWp6 IC5mbG9wcHkKKwkJOyBIYXJkIGRpc2tzIG9ubHkuLi4KKwkJaW5jIGJ4CQkJOyBUeXBlID0gMDNo CisJCW1vdiBkeCxbRGlza1NpemVdCTsgUmV0dXJuIHRoZSBkaXNrIHNpemUgaW4gc2VjdG9ycwor CQltb3YgUF9EWCxkeAorCQltb3YgY3gsW0Rpc2tTaXplKzJdCisJCW1vdiBQX0NYLGN4CisuZmxv cHB5OgorCQltb3YgUF9BSCxibAkJOyAwMmggZmxvcHB5LCAwM2ggaGFyZCBkaXNrCisJCXBvcCBh eAkJCTsgRHJvcCByZXR1cm4gYWRkcmVzcworCQl4b3IgYXgsYXgJCTsgU3VjY2Vzcy4uLgorCQlq bXAgRG9uZVdlaXJkCQk7IEJ1dCBkb24ndCBzdGljayBpdCBpbnRvIFBfQVgKKworR2V0U3RhdHVz OgorCQl4b3IgYXgsYXgKKwkJbW92IGVzLGF4CisJCW1vdiBieCxbU3RhdHVzUHRyXQorCQltb3Yg YWgsW2J4XQkJOyBDb3B5IGxhc3Qgc3RhdHVzCisJCXJldAorCitSZWFkTXVsdDoKKwkJVFJBQ0VS ICdtJworUmVhZDoKKwkJVFJBQ0VSICdSJworCQljYWxsIHNldHVwX3JlZ3MKK2RvX2NvcHk6CisJ CVRSQUNFUiAnPCcKKwkJY2FsbCBiY29weQorCQlUUkFDRVIgJz4nCisJCW1vdnp4IGF4LFBfQUwJ CTsgQUggPSAwLCBBTCA9IHRyYW5zZmVyIGNvdW50CisJCXJldAorCitXcml0ZU11bHQ6CisJCVRS QUNFUiAnTScKK1dyaXRlOgorCQlUUkFDRVIgJ1cnCisJCXRlc3QgYnl0ZSBbQ29uZmlnRmxhZ3Nd LENPTkZJR19SRUFET05MWQorCQlqbnogLnJlYWRvbmx5CisJCWNhbGwgc2V0dXBfcmVncworCQl4 Y2hnIGVzaSxlZGkJCTsgT3Bwb3NpdGUgZGlyZWN0aW9uIG9mIGEgUmVhZCEKKwkJam1wIHNob3J0 IGRvX2NvcHkKKy5yZWFkb25seToJbW92IGFoLDAzaAkJOyBXcml0ZSBwcm90ZWN0ZWQgbWVkaXVt CisJCXJldAorCisJCTsgVmVyaWZ5IGludGVncml0eTsganVzdCBib3VuZHMtY2hlY2sKK1NlZWs6 CitWZXJpZnk6CisJCWNhbGwgc2V0dXBfcmVncwkJOyBSZXR1cm5zIGVycm9yIGlmIGFwcHJvcHJp YXRlCisJCTsgQW5kIGZhbGwgdGhyb3VnaCB0byBzdWNjZXNzCisKK0NoZWNrSWZSZWFkeToJCQkJ OyBUaGVzZSBhcmUgYWx3YXlzLXN1Y2Nlc3NmdWwgbm9vcCBmdW5jdGlvbnMKK1JlY2FsaWJyYXRl OgorSW5pdFdpdGhQYXJtczoKK0RldGVjdENoYW5nZToKK0VERERldGVjdENoYW5nZToKK0VERExv Y2s6CitTZXRNb2RlOgorc3VjY2VzczoKKwkJeG9yIGF4LGF4CQk7IEFsd2F5cyBzdWNjZXNzZnVs CisJCXJldAorCitHZXRQYXJtczoKKwkJVFJBQ0VSICdHJworCQltb3YgZGwsW0RyaXZlQ250XQk7 IENhY2hlZCBkYXRhCisJCW1vdiBQX0RMLGRsCisJCXRlc3QgYnl0ZSBbRHJpdmVOb10sODBoCisJ CWpueiAuaGQKKwkJbW92IFBfREksRFBUCisJCW1vdiBQX0VTLGNzCisJCW1vdiBibCxbRHJpdmVU eXBlXQorCQltb3YgUF9CTCxibAorLmhkOgorCQltb3YgYXgsW0N5bGluZGVyc10KKwkJZGVjIGF4 CQkJOyBXZSByZXBvcnQgdGhlIGhpZ2hlc3QgIywgbm90IHRoZSBjb3VudAorCQl4Y2hnIGFsLGFo CisJCXNobCBhbCw2CisJCW9yIGFsLFtTZWN0b3JzXQorCQltb3YgUF9DWCxheAorCQltb3YgYXgs W0hlYWRzXQorCQlkZWMgYXgKKwkJbW92IFBfREgsYWwKKworCQk7CisJCTsgSXMgdGhpcyBNRU1E SVNLIGluc3RhbGxhdGlvbiBjaGVjaz8KKwkJOworCQljbXAgUF9IQVgsJ01FJworCQlqbmUgLm5v dGljCisJCWNtcCBQX0hDWCwnTUQnCisJCWpuZSAubm90aWMKKwkJY21wIFBfSERYLCdJUycKKwkJ am5lIC5ub3RpYworCQljbXAgUF9IQlgsJ0s/JworCQlqbmUgLm5vdGljCisKKwkJOyBNRU1ESVNL IGluc3RhbGxhdGlvbiBjaGVjay4uLgorCQltb3YgUF9IQVgsJyFNJworCQltb3YgUF9IQ1gsJ0VN JworCQltb3YgUF9IRFgsJ0RJJworCQltb3YgUF9IQlgsJ1NLJworCQltb3YgUF9FUyxjcworCQlt b3YgUF9ESSxNZW1EaXNrX0luZm8KKworLm5vdGljOgorCQl4b3IgYXgsYXgKKwkJcmV0Cis7Cis7 IEVERCBmdW5jdGlvbnMgLS0gb25seSBpZiBlbmFibGVkCis7CislaWYgRURECitFRERQcmVzZW5j ZToKKwkJVFJBQ0VSICdFJworCQlUUkFDRVIgJ2MnCisKKwkJY21wIFBfQlgsNTVBQWgKKwkJam5l IEludmFsaWQKKwkJbW92IFBfQlgsMEFBNTVoCQk7IEVERCBzaWduYXR1cmUKKwkJbW92IFBfQVgs MDMwMDBoCQk7IEVERCAzLjAKKwkJbW92IFBfQ1gsMDAwM2gJCTsgQml0IDAgLSBGaXhlZCBkaXNr IGFjY2VzcyBzdWJzZXQKKwkJCQkJOyBCaXQgMSAtIExvY2tpbmcgYW5kIGVqZWN0aW5nIHN1YnNl dAorCQlwb3AgYXgJCQk7IERyb3AgcmV0dXJuIGFkZHJlc3MKKwkJeG9yIGF4LGF4CQk7IFN1Y2Nl c3MKKwkJam1wIERvbmVXZWlyZAkJOyBTdWNjZXNzLCBidXQgQUggIT0gMCwgc2lnaC4uLgorCitF RERSZWFkOgorCQlUUkFDRVIgJ0UnCisJCVRSQUNFUiAncicKKworCQljYWxsIGVkZF9zZXR1cF9y ZWdzCisJCWNhbGwgYmNvcHkKKwkJeG9yIGF4LGF4CisJCXJldAorCitFRERXcml0ZToKKwkJVFJB Q0VSICdFJworCQlUUkFDRVIgJ3cnCisKKwkJY2FsbCBlZGRfc2V0dXBfcmVncworCQl4Y2hnIGVz aSxlZGkKKwkJY2FsbCBiY29weQorCQl4b3IgYXgsYXgKKwkJcmV0CisKK0VERFZlcmlmeToKK0VE RFNlZWs6CisJCWNhbGwgZWRkX3NldHVwX3JlZ3MJOyBKdXN0IGJvdW5kcyBjaGVja2luZworCQl4 b3IgYXgsYXgKKwkJcmV0CisKK0VEREdldFBhcm1zOgorCQlUUkFDRVIgJ0UnCisJCVRSQUNFUiAn cCcKKworCQltb3YgZXMsUF9EUworCQltb3YgZGksUF9TSQorCQltb3Ygc2ksRUREX0RQVAorCisJ CWxvZHN3CQkJOyBMZW5ndGggb2Ygb3VyIERQVAorCQltb3YgY3gsW2VzOmRpXQorCQljbXAgY3gs MjYJCTsgTWluaW11bSBzaXplCisJCWpiIC5vdmVycnVuCisKKwkJY21wIGN4LGF4CisJCWpiIC5v a3NpemUKKwkJbW92IGN4LGF4CisKKy5va3NpemU6CisJCW1vdiBheCxjeAorCQlzdG9zdworCQlk ZWMgY3gKKwkJZGVjIGN4CisJCXJlcCBtb3ZzYgorCisJCXhvciBheCxheAorCQlyZXQKKworLm92 ZXJydW46CisJCW1vdiBheCwwMTAwaAorCQlyZXQKKyVlbmRpZiA7IEVERAorCisJCTsgU2V0IHVw IHJlZ2lzdGVycyBhcyBmb3IgYSAiUmVhZCIsIGFuZCBjb21wYXJlcyBhZ2FpbnN0IGRpc2sgc2l6 ZS4KKwkJOyBXQVJOSU5HOiBUaGlzIGZhaWxzIGltbWVkaWF0ZWx5LCBldmVuIGlmIHdlIGNhbiB0 cmFuc2ZlciBzb21lCisJCTsgc2VjdG9ycy4gIFRoaXMgaXNuJ3QgcmVhbGx5IHRoZSBjb3JyZWN0 IGJlaGF2aW91ci4KK3NldHVwX3JlZ3M6CisKKwkJOyBDb252ZXJ0IGEgQ0hTIGFkZHJlc3MgaW4g UF9DWC9QX0RIIGludG8gYW4gTEJBIGluIGVheAorCQk7IENIID0gY3lsWzc6MF0KKwkJOyBDTFsw OjVdID0gc2VjdG9yICgxLWJhc2VkKSAgQ0xbNzo2XSA9IGN5bFs5OjhdCisJCTsgREggPSBoZWFk CisJCW1vdnp4IGVjeCxQX0NYCisJCW1vdnp4IGVieCxjbAkJOyBTZWN0b3IgbnVtYmVyCisJCWFu ZCBibCwzRmgKKwkJZGVjIGVieAkJCTsgU2VjdG9yIG51bWJlciBpcyAxLWJhc2VkCisJCWNtcCBi eCxbU2VjdG9yc10KKwkJamFlIC5vdmVycnVuCisJCW1vdnp4IGVkaSxQX0RICQk7IEhlYWQgbnVt YmVyCisJCW1vdnp4IGVheCx3b3JkIFtIZWFkc10KKwkJY21wIGRpLGF4CisJCWphZSAub3ZlcnJ1 bgorCQlzaHIgY2wsNgorCQl4Y2hnIGNsLGNoCQk7IE5vdyAoRSlDWCA8LSBjeWxpbmRlciBudW1i ZXIKKwkJbXVsIGVjeAkJCTsgZWF4IDwtIEhlYWRzKmN5bCMgKGVkeCA8LSAwKQorCQlhZGQgZWF4 LGVkaQorCQltdWwgZHdvcmQgW1NlY3RvcnNdCisJCWFkZCBlYXgsZWJ4CisJCTsgTm93IGVheCA9 IExCQSwgZWR4ID0gMAorCisJCTsKKwkJOyBzZXR1cF9yZWdzIGNvbnRpbnVlcy4uLgorCQk7CisJ CTsgTm90ZTogZWRpWzMxOjE2XSBhbmQgZWN4WzMxOjE2XSA9IDAgYWxyZWFkeQorCQltb3YgZGks UF9CWAkJOyBHZXQgbGluZWFyIGFkZHJlc3Mgb2YgdGFyZ2V0IGJ1ZmZlcgorCQltb3YgY3gsUF9F UworCQlzaGwgZWN4LDQKKwkJYWRkIGVkaSxlY3gJCTsgRURJID0gYWRkcmVzcyB0byBmZXRjaCB0 bworCQltb3Z6eCBlY3gsUF9BTAkJOyBTZWN0b3IgY291bnQKKwkJbW92IGVzaSxlYXgKKwkJYWRk IGVheCxlY3gJCTsgTEJBIG9mIGZpbmFsIHNlY3RvciArIDEKKwkJc2hsIGVzaSxTRUNUT1JTSVpF X0xHMgk7IExCQSAtPiBieXRlIG9mZnNldAorCQlhZGQgZXNpLFtEaXNrQnVmXQk7IEdldCBhZGRy ZXNzIGluIGhpZ2ggbWVtb3J5CisJCWNtcCBlYXgsW0Rpc2tTaXplXQk7IENoZWNrIHRoZSBoaWdo IG1hcmsgYWdhaW5zdCBsaW1pdAorCQlqYSAub3ZlcnJ1bgorCQlzaGwgZWN4LFNFQ1RPUlNJWkVf TEcyLTIgOyBDb252ZXJ0IGNvdW50IHRvIGR3b3JkcworCQlyZXQKKworLm92ZXJydW46CXBvcCBh eAkJCTsgRHJvcCBzZXR1cF9yZWdzIHJldHVybiBhZGRyZXNzCisJCW1vdiBheCwwMjAwaAkJOyBN aXNzaW5nIGFkZHJlc3MgbWFyaworCQlyZXQJCQk7IFJldHVybiB0byBEb25lCisKKwkJOyBTZXQg dXAgcmVnaXN0ZXJzIGFzIGZvciBhbiBFREQgUmVhZCwgYW5kIGNvbXBhcmVzIGFnYWluc3QgZGlz ayBzaXplLgorJWlmIEVERAorZWRkX3NldHVwX3JlZ3M6CisJCXB1c2ggZXMKKwkJbW92IHNpLFBf U0kJCTsgRFM6U0kgLT4gREFQQQorCQltb3YgZXMsUF9EUworCisJCW1vdiBkeCxbZXM6c2ldCisJ CWNtcCBkeCwxNgorCQlqYiAuYmFkZGFwYQorCisJCWNtcCBkd29yZCBbZXM6c2krNF0sLTEKKwkJ amUgLmxpbmVhcl9hZGRyZXNzCisKKwkJbW92enggZWJ4LHdvcmQgW2VzOnNpKzRdCTsgT2Zmc2V0 CisJCW1vdnp4IGVkaSx3b3JkIFtlczpzaSs2XQk7IFNlZ21lbnQKKwkJc2hsIGVkaSw0CisJCWFk ZCBlYngsZWRpCisJCWptcCAuZ290X2FkZHJlc3MKKworLmxpbmVhcl9hZGRyZXNzOgorCQljbXAg ZHgsMjQJCTsgTXVzdCBiZSBsYXJnZSBlbm91Z2ggdG8gaG9sZAorCQkJCQk7IGxpbmVhciBhZGRy ZXNzCisJCWpiIC5iYWRkYXBhCisKKwkJY21wIGR3b3JkIFtlczpzaSsyMF0sMAk7ID4gNCBHQiBh ZGRyZXNzZXMgbm90IHN1cHBvcnRlZAorCQltb3YgYXgsMDkwMGgJCTsgIkRhdGEgYm91bmRhcnkg ZXJyb3IiIC0gYm9ndXMsIGJ1dAorCQkJCQk7IG5vIHJlYWxseSBiZXR0ZXIgY29kZSBhdmFpbGFi bGUKKwkJam5lIC5lcnJvcgorCisJCW1vdiBlYngsW2VzOnNpKzE2XQorCisuZ290X2FkZHJlc3M6 CisJCWNtcCBkd29yZCBbZXM6c2krMTJdLDAJCTsgTEJBIHRvbyBsYXJnZT8KKwkJam5lIC5vdmVy cnVuCisKKwkJbW92enggZWN4LCB3b3JkIFtlczpzaSsyXQk7IFNlY3RvcnMgdG8gdHJhbnNmZXIK KwkJbW92IGVzaSxbZXM6c2krOF0JCTsgU3RhcnRpbmcgc2VjdG9yCisJCW1vdiBlYXgsZXNpCisJ CWFkZCBlYXgsZWN4CisJCWpjIC5vdmVycnVuCisJCWNtcCBlYXgsW0Rpc2tTaXplXQorCQlqYSAu b3ZlcnJ1bgorCisJCXNobCBlY3gsU0VDVE9SU0laRV9MRzItMgk7IENvbnZlcnQgdG8gZHdvcmRz CisJCXNobCBlc2ksU0VDVE9SU0laRV9MRzIJCTsgQ29udmVydCB0byBhbiBvZmZzZXQKKwkJYWRk IGVzaSxbRGlza0J1Zl0KKwkJbW92IGVkaSxlYngKKwkJcG9wIGVzCisJCXJldAorCisuYmFkZGFw YToKKwkJbW92IGF4LDAxMDBoCQk7IEludmFsaWQgY29tbWFuZAorCQlwb3AgZXMKKwkJcG9wIGF4 CQkJOyBEcm9wIHNldHVwX3JlZ3MgcmV0dXJuIGFkZHJlc3MKKwkJcmV0CisKKy5vdmVycnVuOgor CQltb3YgYXgsMDIwMGgJCTsgIkFkZHJlc3MgbWFyayBub3QgZm91bmQiID0KKwkJCQkJOyBMQkEg YmV5b25kIGVuZCBvZiBkaXNrCisuZXJyb3I6CisJCWFuZCB3b3JkIFtlczpzaSsyXSwwCTsgTm8g c2VjdG9ycyB0cmFuc2ZlcnJlZAorCQlwb3AgZXMKKwkJcG9wIGF4CisJCXJldAorCitFRERFamVj dDoKKwkJbW92IGF4LDBCMjAwaAkJOyBWb2x1bWUgTm90IFJlbW92YWJsZQorCQlyZXQKKworJWVu ZGlmIDsgRURECisKKworOworOyBJTlQgMTVoIGludGVyY2VwdCByb3V0aW5lcworOworaW50MTVf ZTgyMDoKKwkJY21wIGVkeCw1MzRENDE1MGgJOyAiU01BUCIKKwkJam5lIG9sZGludDE1CisJCWNt cCBlY3gsMjAJCTsgTmVlZCAyMCBieXRlcworCQlqYiBlcnI4NgorCQlwdXNoIGRzCisJCXB1c2gg Y3MKKwkJcG9wIGRzCisJCXB1c2ggZWR4CQk7ICJTTUFQIgorCQlhbmQgZWJ4LGVieAorCQlqbmUg LnJlbmV3CisJCW1vdiBlYngsRTgyMFRhYmxlCisucmVuZXc6CisJCWFkZCBieCwxNgkJOyBBZHZh bmNlIHRvIG5leHQKKwkJbW92IGVheCxbYngtOF0JCTsgVHlwZQorCQlhbmQgZWF4LGVheAkJOyBO dWxsIHR5cGU/CisJCWp6IC5yZW5ldwkJOyBJZiBzbyBhZHZhbmNlIHRvIG5leHQKKwkJbW92IFtl czpkaSsxNl0sZWF4CisJCWFuZCBjbCx+MworCQljbXAgZWN4LDI0CisJCWpiIC5ub19leHRhdHRy CisJCW1vdiBlYXgsW2J4LTRdCQk7IEV4dGVuZGVkIGF0dHJpYnV0ZXMKKwkJbW92IFtlczpkaSsy MF0sZWF4CisJCW1vdiBlY3gsMjQJCTsgQnl0ZXMgbG9hZGVkCisubm9fZXh0YXR0cjoKKwkJbW92 IGVheCxbYngtMTZdCQk7IFN0YXJ0IGFkZHIgKGxvdykKKwkJbW92IGVkeCxbYngtMTJdCQk7IFN0 YXJ0IGFkZHIgKGhpZ2gpCisJCW1vdiBbZXM6ZGldLGVheAorCQltb3YgW2VzOmRpKzRdLGVkeAor CQltb3YgZWF4LFtieF0JCTsgRW5kIGFkZHIgKGxvdykKKwkJbW92IGVkeCxbYngrNF0JCTsgRW5k IGFkZHIgKGhpZ2gpCisJCXN1YiBlYXgsW2J4LTE2XQkJOyBEZXJpdmUgdGhlIGxlbmd0aAorCQlz YmIgZWR4LFtieC0xMl0KKwkJbW92IFtlczpkaSs4XSxlYXgJOyBMZW5ndGggKGxvdykKKwkJbW92 IFtlczpkaSsxMl0sZWR4CTsgTGVuZ3RoIChoaWdoKQorCQljbXAgZHdvcmQgW2J4KzhdLC0xCTsg VHlwZSBvZiBuZXh0ID0gZW5kPworCQlqbmUgLm5vdGRvbmUKKwkJeG9yIGVieCxlYngJCTsgRG9u ZSB3aXRoIHRhYmxlCisubm90ZG9uZToKKwkJcG9wIGVheAkJCTsgIlNNQVAiCisJCW1vdiBlZHgs ZWF4CQk7IFNvbWUgc3lzdGVtcyBleHBlY3QgZWF4ID0gZWR4ID0gU01BUAorCQlwb3AgZHMKK2lu dDE1X3N1Y2Nlc3M6CisJCW1vdiBieXRlIFticCs2XSwgMDJoCTsgQ2xlYXIgQ0YKKwkJcG9wIGJw CisJCWlyZXQKKworZXJyODY6CisJCW1vdiBieXRlIFticCs2XSwgMDNoCTsgU2V0IENGCisJCW1v diBhaCw4NmgKKwkJcG9wIGJwCisJCWlyZXQKKworSW50MTVTdGFydDoKKwkJcHVzaCBicAorCQlt b3YgYnAsc3AKKwkJY21wIGF4LDBFODIwaAorCQlqZSBuZWFyIGludDE1X2U4MjAKKwkJY21wIGF4 LDBFODAxaAorCQlqZSBpbnQxNV9lODAxCisJCWNtcCBheCwwRTg4MWgKKwkJamUgaW50MTVfZTg4 MQorCQljbXAgYWgsODhoCisJCWplIGludDE1Xzg4CitvbGRpbnQxNToJcG9wIGJwCisJCWptcCBm YXIgW2NzOk9sZEludDE1XQorCitpbnQxNV9lODAxOgorCQltb3YgYXgsW2NzOk1lbTFNQl0KKwkJ bW92IGN4LGF4CisJCW1vdiBieCxbY3M6TWVtMTZNQl0KKwkJbW92IGR4LGJ4CisJCWptcCBzaG9y dCBpbnQxNV9zdWNjZXNzCisKK2ludDE1X2U4ODE6CisJCW1vdiBlYXgsW2NzOk1lbTFNQl0KKwkJ bW92IGVjeCxlYXgKKwkJbW92IGVieCxbY3M6TWVtMTZNQl0KKwkJbW92IGVkeCxlYngKKwkJam1w IHNob3J0IGludDE1X3N1Y2Nlc3MKKworaW50MTVfODg6CisJCW1vdiBheCxbY3M6TWVtSW50MTU4 OF0KKwkJam1wIHNob3J0IGludDE1X3N1Y2Nlc3MKKworOworOyBSb3V0aW5lIHRvIGNvcHkgaW4v b3V0IG9mIGhpZ2ggbWVtb3J5Cis7IGVzaSA9IGxpbmVhciBzb3VyY2UgYWRkcmVzcworOyBlZGkg PSBsaW5lYXIgdGFyZ2V0IGFkZHJlc3MKKzsgZWN4ID0gMzItYml0IHdvcmQgY291bnQKKzsKKzsg QXNzdW1lcyBjcyA9IGRzID0gZXMKKzsKK2Jjb3B5OgorCQlwdXNoIGVheAorCQlwdXNoIGVieAor CQlwdXNoIGVkeAorCQlwdXNoIGVicAorCisJCW1vdiBieCwgcmVhbF9pbnQxNV9zdHViCisKKwkJ dGVzdCBieXRlIFtDb25maWdGbGFnc10sIENPTkZJR19SQVd8Q09ORklHX1NBRkVJTlQKKwkJanog LmFueW1vZGUJCTsgQWx3YXlzIGRvIHRoZSByZWFsIElOVCAxNWgKKworCQlzbXN3IGF4CQkJOyBV bnByaXZpbGVnZWQhCisJCXRlc3QgYWwsMDFoCisJCWpueiAucHJvdG1vZGUJCTsgUHJvdG1vZGUg LT4gZG8gcmVhbCBJTlQgMTVoCisKKy5yZWFsbW9kZToKKwkJOyBSYXcgb3IgU2FmZWludCBtb2Rl LCBhbmQgd2UncmUgaW4gcmVhbCBtb2RlLi4uCisKKwkJdGVzdCBieXRlIFtDb25maWdGbGFnc10s IENPTkZJR19TQUZFSU5UCisJCWpueiAuZmFrZWludDE1CisKKy5yYXc6CisJCVRSQUNFUiAncicK KwkJOyBXZSdyZSBpbiByZWFsIG1vZGUsIGRvIGl0IG91dHNlbHZlcworCisJCXB1c2hmZAkJCTsg PEE+CisJCXB1c2ggZHMJCQk7IDxCPgorCQlwdXNoIGVzCQkJOyA8Qz4KKworCQljbGkKKwkJY2xk CisKKwkJeG9yIGVieCxlYngKKwkJbW92IGJ4LGNzCisJCXNobCBlYngsNAorCQlsZWEgZWR4LFtT aGFrZXIrZWJ4XQorCQltb3YgW1NoYWtlcisyXSxlZHgKKworCQk7IFRlc3QgdG8gc2VlIGlmIEEy MCBpcyBlbmFibGVkIG9yIG5vdAorCQl4b3IgYXgsYXgKKwkJbW92IGRzLGF4CisJCWRlYyBheAor CQltb3YgZXMsYXgKKworCQltb3YgYXgsWzBdCisJCW1vdiBieCxheAorCQl4b3IgYngsW2VzOjEw aF0KKwkJbm90IGF4CisJCW1vdiBbMF0sYXgKKwkJbW92IGR4LGF4CisJCXhvciBkeCxbZXM6MTBo XQorCQlub3QgYXgKKwkJbW92IFswXSxheAorCisJCW9yIGR4LGJ4CisJCXB1c2ggZHgJCQk7IDxE PiBTYXZlIEEyMCBzdGF0dXMKKwkJam56IC5za2lwX2EyMGUKKworCQltb3YgYXgsMjQwMWgJCTsg RW5hYmxlIEEyMAorCQlpbnQgMTVoCisuc2tpcF9hMjBlOgorCQltb3YgZGwsW0NvbmZpZ0ZsYWdz XQorCQlhbmQgZHgsQ09ORklHX0JJR1JBVworCQlhZGQgZHgsOAorCQk7IERYID0gMTYgZm9yIEJJ R1JBVywgOCBmb3IgUkFXCisJCTsgIDggaXMgc2VsZWN0b3IgZm9yIGEgNjRLIGZsYXQgc2VnbWVu dCwKKwkJOyAxNiBpcyBzZWxlY3RvciBmb3IgYSA0R0IgZmxhdCBzZWdtZW50LgorCisJCWxnZHQg W2NzOlNoYWtlcl0KKwkJbW92IGVheCxjcjAKKwkJb3IgYWwsMDFoCisJCW1vdiBjcjAsZWF4CisK KwkJbW92IGJ4LDE2CQk7IExhcmdlIGZsYXQgc2VnbWVudAorCQltb3YgZHMsYngKKwkJbW92IGVz LGJ4CisKKwkJYTMyIHJlcCBtb3ZzZAorCisJCTsgRFggaGFzIHRoZSBhcHByb3ByaWF0ZSB2YWx1 ZSB0byBwdXQgaW4KKwkJOyB0aGUgcmVnaXN0ZXJzIG9uIHJldHVybgorCQltb3YgZHMsZHgKKwkJ bW92IGVzLGR4CisKKwkJYW5kIGFsLH4wMWgKKwkJbW92IGNyMCxlYXgKKworCQlwb3AgZHgJCQk7 IDxEPiBBMjAgc3RhdHVzCisJCXBvcCBlcwkJCTsgPEM+CisJCXBvcCBkcwkJCTsgPEI+CisKKwkJ YW5kIGR4LGR4CisJCWpueiAuc2tpcF9hMjBkCisJCW1vdiBheCwyNDAwaAkJOyBEaXNhYmxlIEEy MAorCQlpbnQgMTVoCisuc2tpcF9hMjBkOgorCQlwb3BmZAkJCTsgPEE+CisJCWptcCAuZG9uZQor CisuZmFrZWludDE1OgorCQk7IFdlJ3JlIGluIHJlYWwgbW9kZSB3aXRoIENPTkZJR19TQUZFSU5U LCBpbnZva2UgdGhlCisJCTsgb3JpZ2luYWwgSU5UIDE1aCB2ZWN0b3IuICBXZSB1c2VkIHRvIHRl c3QgZm9yIHRoZQorCQk7IElOVCAxNWggdmVjdG9yIGJlaW5nIHVuY2hhbmdlZCBoZXJlLCBidXQg dGhhdCBpcworCQk7ICp1cyo7IGhvd2V2ZXIsIHRoZSB0ZXN0IHdhcyB3cm9uZyBmb3IgeWVhcnMg KGFsd2F5cworCQk7IG5lZ2F0aXZlKSBzbyBpbnN0ZWFkIG9mIGZpeGluZyB0aGUgdGVzdCBkbyB3 aGF0IHdlCisJCTsgdGVzdGVkIGFuZCBkb24ndCBib3RoZXIgcHJvYmluZy4KKwkJbW92IGJ4LCBm YWtlX2ludDE1X3N0dWIKKworLnByb3Rtb2RlOgorCQlUUkFDRVIgJ3AnCisuYW55bW9kZToKKwor LmNvcHlfbG9vcDoKKwkJcHVzaCBlc2kKKwkJcHVzaCBlZGkKKwkJcHVzaCBlY3gKKwkJY21wIGVj eCw0MDAwaAorCQlqbmEgLnNhZmVfc2l6ZQorCQltb3YgZWN4LDQwMDBoCisuc2FmZV9zaXplOgor CQlwdXNoIGVjeAk7IFRyYW5zZmVyIHNpemUgdGhpcyBjeWNsZQorCQltb3YgZWF4LCBlc2kKKwkJ bW92IFtNb3Zlcl9zcmMxXSwgc2kKKwkJc2hyIGVheCwgMTYKKwkJbW92IFtNb3Zlcl9zcmMxKzJd LCBhbAorCQltb3YgW01vdmVyX3NyYzJdLCBhaAorCQltb3YgZWF4LCBlZGkKKwkJbW92IFtNb3Zl cl9kc3QxXSwgZGkKKwkJc2hyIGVheCwgMTYKKwkJbW92IFtNb3Zlcl9kc3QxKzJdLCBhbAorCQlt b3YgW01vdmVyX2RzdDJdLCBhaAorCQltb3Ygc2ksTW92ZXIKKwkJbW92IGFoLCA4N2gKKwkJc2hs IGN4LDEJOyBDb252ZXJ0IHRvIDE2LWJpdCB3b3JkcworCQljYWxsIGJ4CQk7IElOVCAxNWggc3R1 YgorCQlwb3AgZWF4CQk7IFRyYW5zZmVyIHNpemUgdGhpcyBjeWNsZQorCQlwb3AgZWN4CisJCXBv cCBlZGkKKwkJcG9wIGVzaQorCQlqYyAuZXJyb3IKKwkJbGVhIGVzaSxbZXNpKzQqZWF4XQorCQls ZWEgZWRpLFtlZGkrNCplYXhdCisJCXN1YiBlY3gsIGVheAorCQlqbnogLmNvcHlfbG9vcAorCQk7 IENGID0gMAorLmVycm9yOgorLmRvbmU6CisJCXBvcCBlYnAKKwkJcG9wIGVkeAorCQlwb3AgZWJ4 CisJCXBvcCBlYXgKKwkJcmV0CisKK3JlYWxfaW50MTVfc3R1YjoKKwkJaW50IDE1aAorCQljbGkJ CTsgU29tZSBCSU9TZXMgZW5hYmxlIGludGVycnVwdHMgb24gSU5UIDE1aAorCQlyZXQKKworZmFr ZV9pbnQxNV9zdHViOgorCQlwdXNoZgorCQljYWxsIGZhciBbT2xkSW50MTVdCisJCWNsaQorCQly ZXQKKworJWlmZGVmIERFQlVHX1RSQUNFUlMKK2RlYnVnX3RyYWNlcjoJcHVzaGFkCisJCXB1c2hm ZAorCQltb3YgYnAsc3AKKwkJbW92IGJ4LFticCs5KjRdCisJCW1vdiBhbCxbY3M6YnhdCisJCWlu YyB3b3JkIFticCs5KjRdCisJCW1vdiBhaCwwRWgKKwkJbW92IGJ4LDcKKwkJaW50IDEwaAorCQlw b3BmZAorCQlwb3BhZAorCQlyZXQKKyVlbmRpZgorCisJCXNlY3Rpb24gLmRhdGEKKwkJYWxpZ25i IDIKK0ludDEzRnVuY3MJZHcgUmVzZXQJCTsgMDBoIC0gUkVTRVQKKwkJZHcgR2V0U3RhdHVzCQk7 IDAxaCAtIEdFVCBTVEFUVVMKKwkJZHcgUmVhZAkJCTsgMDJoIC0gUkVBRAorCQlkdyBXcml0ZQkJ OyAwM2ggLSBXUklURQorCQlkdyBWZXJpZnkJCTsgMDRoIC0gVkVSSUZZCisJCWR3IEludmFsaWQJ CTsgMDVoIC0gRk9STUFUIFRSQUNLCisJCWR3IEludmFsaWQJCTsgMDZoIC0gRk9STUFUIFRSQUNL IEFORCBTRVQgQkFEIEZMQUdTCisJCWR3IEludmFsaWQJCTsgMDdoIC0gRk9STUFUIERSSVZFIEFU IFRSQUNLCisJCWR3IEdldFBhcm1zCQk7IDA4aCAtIEdFVCBQQVJBTUVURVJTCisJCWR3IEluaXRX aXRoUGFybXMJOyAwOWggLSBJTklUSUFMSVpFIENPTlRST0xMRVIgV0lUSCBEUklWRSBQQVJBTUVU RVJTCisJCWR3IEludmFsaWQJCTsgMEFoCisJCWR3IEludmFsaWQJCTsgMEJoCisJCWR3IFNlZWsJ CQk7IDBDaCAtIFNFRUsgVE8gQ1lMSU5ERVIKKwkJZHcgUmVzZXQJCTsgMERoIC0gUkVTRVQgSEFS RCBESVNLUworCQlkdyBJbnZhbGlkCQk7IDBFaAorCQlkdyBJbnZhbGlkCQk7IDBGaAorCQlkdyBD aGVja0lmUmVhZHkJCTsgMTBoIC0gQ0hFQ0sgSUYgUkVBRFkKKwkJZHcgUmVjYWxpYnJhdGUJCTsg MTFoIC0gUkVDQUxJQlJBVEUKKwkJZHcgSW52YWxpZAkJOyAxMmgKKwkJZHcgSW52YWxpZAkJOyAx M2gKKwkJZHcgSW52YWxpZAkJOyAxNGgKKwkJZHcgR2V0RHJpdmVUeXBlCQk7IDE1aCAtIEdFVCBE UklWRSBUWVBFCisJCWR3IERldGVjdENoYW5nZQkJOyAxNmggLSBERVRFQ1QgRFJJVkUgQ0hBTkdF CislaWYgRURECisJCWR3IEludmFsaWQJCTsgMTdoCisJCWR3IEludmFsaWQJCTsgMThoCisJCWR3 IEludmFsaWQJCTsgMTloCisJCWR3IEludmFsaWQJCTsgMUFoCisJCWR3IEludmFsaWQJCTsgMUJo CisJCWR3IEludmFsaWQJCTsgMUNoCisJCWR3IEludmFsaWQJCTsgMURoCisJCWR3IEludmFsaWQJ CTsgMUVoCisJCWR3IEludmFsaWQJCTsgMUZoCisJCWR3IEludmFsaWQJCTsgMjBoCisJCWR3IFJl YWRNdWx0CQk7IDIxaCAtIFJFQUQgTVVMVElQTEUKKwkJZHcgV3JpdGVNdWx0CQk7IDIyaCAtIFdS SVRFIE1VTFRJUExFCisJCWR3IFNldE1vZGUJCTsgMjNoIC0gU0VUIENPTlRST0xMRVIgRkVBVFVS RVMKKwkJZHcgU2V0TW9kZQkJOyAyNGggLSBTRVQgTVVMVElQTEUgTU9ERQorCQlkdyBJbnZhbGlk CQk7IDI1aCAtIElERU5USUZZIERSSVZFCisJCWR3IEludmFsaWQJCTsgMjZoCisJCWR3IEludmFs aWQJCTsgMjdoCisJCWR3IEludmFsaWQJCTsgMjhoCisJCWR3IEludmFsaWQJCTsgMjloCisJCWR3 IEludmFsaWQJCTsgMkFoCisJCWR3IEludmFsaWQJCTsgMkJoCisJCWR3IEludmFsaWQJCTsgMkNo CisJCWR3IEludmFsaWQJCTsgMkRoCisJCWR3IEludmFsaWQJCTsgMkVoCisJCWR3IEludmFsaWQJ CTsgMkZoCisJCWR3IEludmFsaWQJCTsgMzBoCisJCWR3IEludmFsaWQJCTsgMzFoCisJCWR3IElu dmFsaWQJCTsgMzJoCisJCWR3IEludmFsaWQJCTsgMzNoCisJCWR3IEludmFsaWQJCTsgMzRoCisJ CWR3IEludmFsaWQJCTsgMzVoCisJCWR3IEludmFsaWQJCTsgMzZoCisJCWR3IEludmFsaWQJCTsg MzdoCisJCWR3IEludmFsaWQJCTsgMzhoCisJCWR3IEludmFsaWQJCTsgMzloCisJCWR3IEludmFs aWQJCTsgM0FoCisJCWR3IEludmFsaWQJCTsgM0JoCisJCWR3IEludmFsaWQJCTsgM0NoCisJCWR3 IEludmFsaWQJCTsgM0RoCisJCWR3IEludmFsaWQJCTsgM0VoCisJCWR3IEludmFsaWQJCTsgM0Zo CisJCWR3IEludmFsaWQJCTsgNDBoCisJCWR3IEVERFByZXNlbmNlCQk7IDQxaCAtIEVERCBQUkVT RU5DRSBERVRFQ1QKKwkJZHcgRUREUmVhZAkJOyA0MmggLSBFREQgUkVBRAorCQlkdyBFRERXcml0 ZQkJOyA0M2ggLSBFREQgV1JJVEUKKwkJZHcgRUREVmVyaWZ5CQk7IDQ0aCAtIEVERCBWRVJJRlkK KwkJZHcgRURETG9jawkJOyA0NWggLSBFREQgTE9DSy9VTkxPQ0sgTUVESUEKKwkJZHcgRURERWpl Y3QJCTsgNDZoIC0gRUREIEVKRUNUCisJCWR3IEVERFNlZWsJCTsgNDdoIC0gRUREIFNFRUsKKwkJ ZHcgRURER2V0UGFybXMJCTsgNDhoIC0gRUREIEdFVCBQQVJBTUVURVJTCisJCWR3IEVERERldGVj dENoYW5nZQk7IDQ5aCAtIEVERCBNRURJQSBDSEFOR0UgU1RBVFVTCislZW5kaWYKKworSW50MTNG dW5jc0VuZAllcXUgJAorSW50MTNGdW5jc0NudAllcXUgKEludDEzRnVuY3NFbmQtSW50MTNGdW5j cykgPj4gMQorCisKKwkJYWxpZ25iIDgsIGRiIDAKK1NoYWtlcgkJZHcgU2hha2VyRW5kLSQKKwkJ ZGQgMAkJCTsgUG9pbnRlciB0byBzZWxmCisJCWR3IDAKKworU2hha2VyX1JNRFM6CWRkIDB4MDAw MGZmZmYJCTsgNjRLIGRhdGEgc2VnbWVudAorCQlkZCAweDAwMDA5MzAwCisKK1NoYWtlcl9EUzoJ ZGQgMHgwMDAwZmZmZgkJOyA0R0IgZGF0YSBzZWdtZW50CisJCWRkIDB4MDA4ZjkzMDAKKworU2hh a2VyRW5kCWVxdSAkCisKKwkJYWxpZ25iIDgsIGRiIDAKKworTW92ZXIJCWRkIDAsIDAsIDAsIDAJ CTsgTXVzdCBiZSB6ZXJvCisJCWR3IDBmZmZmaAkJOyA2NCBLIHNlZ21lbnQgc2l6ZQorTW92ZXJf c3JjMToJZGIgMCwgMCwgMAkJOyBMb3cgMjQgYml0cyBvZiBzb3VyY2UgYWRkeQorCQlkYiA5M2gJ CQk7IEFjY2VzcyByaWdodHMKKwkJZGIgMDBoCQkJOyBFeHRlbmRlZCBhY2Nlc3MgcmlnaHRzCitN b3Zlcl9zcmMyOglkYiAwCQkJOyBIaWdoIDggYml0cyBvZiBzb3VyY2UgYWRkeQorCQlkdyAwZmZm ZmgJCTsgNjQgSyBzZWdtZW50IHNpemUKK01vdmVyX2RzdDE6CWRiIDAsIDAsIDAJCTsgTG93IDI0 IGJpdHMgb2YgdGFyZ2V0IGFkZHkKKwkJZGIgOTNoCQkJOyBBY2Nlc3MgcmlnaHRzCisJCWRiIDAw aAkJCTsgRXh0ZW5kZWQgYWNjZXNzIHJpZ2h0cworTW92ZXJfZHN0MjoJZGIgMAkJCTsgSGlnaCA4 IGJpdHMgb2Ygc291cmNlIGFkZHkKK01vdmVyX2R1bW15MjoJZGQgMCwgMCwgMCwgMAkJOyBNb3Jl IHNwYWNlIGZvciB0aGUgQklPUworCisJCWFsaWduYiA0LCBkYiAwCitNZW1EaXNrX0luZm8JZXF1 ICQJCQk7IFBvaW50ZWQgdG8gYnkgaW5zdGFsbGF0aW9uIGNoZWNrCitNRElfQnl0ZXMJZHcgTURJ X0xlbgkJOyBUb3RhbCBieXRlcyBpbiBNREkgc3RydWN0dXJlCitNRElfVmVyc2lvbglkYiBWRVJT SU9OX01JTk9SLCBWRVJTSU9OX01BSk9SCTsgTUVNRElTSyB2ZXJzaW9uCisKK1BhdGNoQXJlYQll cXUgJAkJCTsgVGhpcyBnZXRzIGZpbGxlZCBpbiBieSB0aGUgaW5zdGFsbGVyCisKK0Rpc2tCdWYJ CWRkIDAJCQk7IExpbmVhciBhZGRyZXNzIG9mIGhpZ2ggbWVtb3J5IGRpc2sKK0Rpc2tTaXplCWRk IDAJCQk7IFNpemUgb2YgZGlzayBpbiBibG9ja3MKK0NvbW1hbmRMaW5lCWR3IDAsIDAJCQk7IEZh ciBwb2ludGVyIHRvIHNhdmVkIGNvbW1hbmQgbGluZQorCitPbGRJbnQxMwlkZCAwCQkJOyBJTlQg MTNoIGluIGNoYWluCitPbGRJbnQxNQlkZCAwCQkJOyBJTlQgMTVoIGluIGNoYWluCisKK09sZERv c01lbQlkdyAwCQkJOyBPbGQgcG9zaXRpb24gb2YgRE9TIG1lbSBlbmQKK0Jvb3RMb2FkZXJJRAlk YiAwCQkJOyBCb290IGxvYWRlciBJRCBmcm9tIGhlYWRlcgorCQlkYiAwCQkJOyBwYWQKKworRFBU X3B0cgkJZHcgMAkJCTsgSWYgbm9uemVybywgcG9pbnRlciB0byBEUFQKKwkJCQkJOyBPcmlnaW5h bCBEUFQgcG9pbnRlciBmb2xsb3dzCisKK01ESV9MZW4JCWVxdSAkLU1lbURpc2tfSW5mbworCis7 IC0tLS0gTURJIHN0cnVjdHVyZSBlbmRzIGhlcmUgLS0tCitJbnQxM01heEZ1bmMJZGIgSW50MTNG dW5jc0NudC0xCTsgTWF4IElOVCAxM2ggZnVuY3Rpb24gKHRvIGRpc2FibGUgRUREKQorCQlkYiAw CQkJOyBwYWQKKworCQlkdyAwCQkJOyBwYWQKK01lbUludDE1ODgJZHcgMAkJCTsgMU1CLTY1TUIg bWVtb3J5IGFtb3VudCAoMUspCisKK0N5bGluZGVycwlkdyAwCQkJOyBDeWxpbmRlciBjb3VudAor SGVhZHMJCWR3IDAJCQk7IEhlYWQgY291bnQKK1NlY3RvcnMJCWRkIDAJCQk7IFNlY3RvciBjb3Vu dCAoemVyby1leHRlbmRlZCkKKworTWVtMU1CCQlkZCAwCQkJOyAxTUItMTZNQiBtZW1vcnkgYW1v dW50ICgxSykKK01lbTE2TUIJCWRkIDAJCQk7IDE2TUItNEcgbWVtb3J5IGFtb3VudCAoNjRLKQor CitEcml2ZU5vCQlkYiAwCQkJOyBPdXIgZHJpdmUgbnVtYmVyCitEcml2ZVR5cGUJZGIgMAkJCTsg T3VyIGRyaXZlIHR5cGUgKGZsb3BwaWVzKQorRHJpdmVDbnQJZGIgMAkJCTsgRHJpdmUgY291bnQg KGZyb20gdGhlIEJJT1MpCisKK0NvbmZpZ0ZsYWdzCWRiIDAJCQk7IEJpdCAwIC0gcmVhZG9ubHkK KworTXlTdGFjawkJZHcgMAkJCTsgT2Zmc2V0IG9mIHN0YWNrCitTdGF0dXNQdHIJZHcgMAkJCTsg V2hlcmUgdG8gc2F2ZSBzdGF0dXMgKHplcm9zZWcgcHRyKQorCitEUFQJCXRpbWVzIDE2IGRiIDAJ CTsgQklPUyBwYXJhbWV0ZXIgdGFibGUgcG9pbnRlciAoZmxvcHBpZXMpCitPbGRJbnQxRQlkZCAw CQkJOyBQcmV2aW91cyBJTlQgMUUgcG9pbnRlciAoRFBUKQorCislaWYgRURECitFRERfRFBUOgor Lmxlbmd0aAkJZHcgMzAKKy5pbmZvCQlkdyAwMDI5aAorCQk7IEJpdCAwIC0gRE1BIGJvdW5kYXJp ZXMgaGFuZGxlZCB0cmFuc3BhcmVudGx5CisJCTsgQml0IDMgLSBEZXZpY2Ugc3VwcG9ydHMgd3Jp dGUgdmVyaWZ5CisJCTsgQml0IDUgLSBNZWRpYSBpcyBsb2NrYWJsZQorLmN5bGluZGVycwlkZCAw CQkJOyBGaWxsZWQgaW4gYnkgaW5zdGFsbGVyCisuaGVhZHMJCWRkIDAJCQk7IEZpbGxlZCBpbiBi eSBpbnN0YWxsZXIKKy5zZWN0b3JzCWRkIDAJCQk7IEZpbGxlZCBpbiBieSBpbnN0YWxsZXIKKy50 b3RhbHNpemUJZGQgMCwgMAkJCTsgRmlsbGVkIGluIGJ5IGluc3RhbGxlcgorLmJ5dGVzcGVyc2Vj CWR3IFNFQ1RPUlNJWkUKKy5lZGR0YWJsZQlkdyAtMSwgLTEJCTsgSW52YWxpZCBEUFRFIHBvaW50 ZXIKKworJWVuZGlmCisKKwkJOyBFbmQgcGF0Y2ggYXJlYQorU3RhY2sJCWRkIDAJCQk7IFNhdmVk IFNTOkVTUCBvbiBpbnZvY2F0aW9uCisJCWR3IDAKK1NhdmVkQVgJCWR3IDAJCQk7IEFYIHNhdmVk IG9uIGludm9jYXRpb24KKworCQlhbGlnbmIgNCwgZGIgMAkJOyBXZSAqTVVTVCogZW5kIG9uIGEg ZHdvcmQgYm91bmRhcnkKKworRTgyMFRhYmxlCWVxdSAkCQkJOyBUaGUgaW5zdGFsbGVyIGxvYWRz IHRoZSBFODIwIHRhYmxlIGhlcmUKK1RvdGFsU2l6ZQllcXUgJAkJCTsgRW5kIHBvaW50ZXIKZGlm ZiAtLWdpdCBhL21lbWRpc2svbWVtZGlza19lZGQuYXNtIGIvbWVtZGlzay9tZW1kaXNrX2VkZC5h c20KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTdkM2ZlOQotLS0gL2Rldi9u dWxsCisrKyBiL21lbWRpc2svbWVtZGlza19lZGQuYXNtCkBAIC0wLDAgKzEsMiBAQAorJWRlZmlu ZSBXSVRIX0VERAorJWluY2x1ZGUgIm1lbWRpc2suaW5jIgpkaWZmIC0tZ2l0IGEvbWVtZGlzay9z ZXR1cC5jIGIvbWVtZGlzay9zZXR1cC5jCmluZGV4IDdiMWY0NTYuLmVkMDhkNTcgMTAwNjQ0Ci0t LSBhL21lbWRpc2svc2V0dXAuYworKysgYi9tZW1kaXNrL3NldHVwLmMKQEAgLTI0LDYgKzI0LDkg QEAgY29uc3QgY2hhciBjb3B5cmlnaHRbXSA9CiAKIGV4dGVybiBjb25zdCBjaGFyIF9iaW5hcnlf bWVtZGlza19iaW5fc3RhcnRbXSwgX2JpbmFyeV9tZW1kaXNrX2Jpbl9lbmRbXTsKIGV4dGVybiBj b25zdCBjaGFyIF9iaW5hcnlfbWVtZGlza19iaW5fc2l6ZVtdOyAvKiBXZWlyZCwgSSBrbm93ICov CitleHRlcm4gY29uc3QgY2hhciBfYmluYXJ5X21lbWRpc2tfZWRkX2Jpbl9zdGFydFtdLAorICAg ICAgIF9iaW5hcnlfbWVtZGlza19lZGRfZW5kW107CitleHRlcm4gY29uc3QgY2hhciBfYmluYXJ5 X21lbWRpc2tfZWRkX2Jpbl9zaXplW107CiAKIHN0cnVjdCBtZW1kaXNrX2hlYWRlciB7CiAgIHVp bnQxNl90IGludDEzX29mZnM7CkBAIC05Myw3ICs5Niw2IEBAIHN0cnVjdCBwYXRjaF9hcmVhIHsK ICAgdWludDE2X3QgZHB0X3B0cjsKICAgLyogRW5kIG9mIHRoZSBvZmZpY2lhbCBNZW1EaXNrX0lu Zm8gKi8KICAgdWludDhfdCAgbWF4aW50MTNmdW5jOwotI2RlZmluZSBNQVhJTlQxM19OT0VERAkw eDE2CiAgIHVpbnQ4X3QgIF9wYWQyOwogCiAgIHVpbnQxNl90IF9wYWQzOwpAQCAtNTk4LDcgKzYw MCw4IEBAIHZvaWQgKnN5c19ib3VuY2U7CiAKIF9fY2RlY2wgdm9pZCBzZXR1cChfX2NkZWNsIHN5 c2NhbGxfdCBjc19zeXNjYWxsLCB2b2lkICpjc19ib3VuY2UpCiB7Ci0gIHVuc2lnbmVkIGludCBi aW5fc2l6ZSA9IChpbnQpICZfYmluYXJ5X21lbWRpc2tfYmluX3NpemU7CisgIHVuc2lnbmVkIGlu dCBiaW5fc2l6ZTsKKyAgY2hhciAqbWVtZGlza19ob29rOwogICBzdHJ1Y3QgbWVtZGlza19oZWFk ZXIgKmhwdHI7CiAgIHN0cnVjdCBwYXRjaF9hcmVhICpwcHRyOwogICB1aW50MTZfdCBkcml2ZXJz ZWc7CkBAIC02MTAsNyArNjEzLDcgQEAgX19jZGVjbCB2b2lkIHNldHVwKF9fY2RlY2wgc3lzY2Fs bF90IGNzX3N5c2NhbGwsIHZvaWQgKmNzX2JvdW5jZSkKICAgY29tMzJzeXNfdCByZWdzOwogICB1 aW50MzJfdCByYW1kaXNrX2ltYWdlLCByYW1kaXNrX3NpemU7CiAgIGludCBiaW9zX2RyaXZlczsK LSAgaW50IGRvX2VkZCA9IC0xOwkJLyogLTEgPSBkZWZhdWx0LCAwID0gbm8sIDEgPSB5ZXMgKi8K KyAgaW50IGRvX2VkZCA9IDE7CQkvKiAwID0gbm8sIDEgPSB5ZXMsIGRlZmF1bHQgaXMgeWVzICov CiAgIGludCBub19icHQ7CQkJLyogTm8gdmFsaWQgQlBUIHByZXNlbnRlZCAqLwogCiAgIC8qIFNl dCB1cCBnbG9iYWwgdmFyaWFibGVzICovCkBAIC02NDksMTMgKzY1MiwyMiBAQCBfX2NkZWNsIHZv aWQgc2V0dXAoX19jZGVjbCBzeXNjYWxsX3QgY3Nfc3lzY2FsbCwgdm9pZCAqY3NfYm91bmNlKQog ICBlbHNlCiAgICAgZG9fZWRkID0gKGdlb21ldHJ5LT5kcml2ZW5vICYgMHg4MCkgPyAxIDogMDsK IAorICAvKiBDaG9vc2UgdGhlIGFwcHJvcHJpYXRlIGluc3RhbGxhYmxlIG1lbWRpc2sgaG9vayAq LworICBpZiAoZG9fZWRkKSB7CisgICAgYmluX3NpemUgPSAoaW50KSAmX2JpbmFyeV9tZW1kaXNr X2VkZF9iaW5fc2l6ZTsKKyAgICBtZW1kaXNrX2hvb2sgPSAoY2hhciAqKSAmX2JpbmFyeV9tZW1k aXNrX2VkZF9iaW5fc3RhcnQ7CisgIH0gZWxzZSB7CisgICAgYmluX3NpemUgPSAoaW50KSAmX2Jp bmFyeV9tZW1kaXNrX2Jpbl9zaXplOworICAgIG1lbWRpc2tfaG9vayA9IChjaGFyICopICZfYmlu YXJ5X21lbWRpc2tfYmluX3N0YXJ0OworICB9CisKICAgLyogUmVzZXJ2ZSB0aGUgcmFtZGlzayBt ZW1vcnkgKi8KICAgaW5zZXJ0cmFuZ2UocmFtZGlza19pbWFnZSwgcmFtZGlza19zaXplLCAyLCAx KTsKICAgcGFyc2VfbWVtKCk7CQkJLyogUmVjb21wdXRlIHZhcmlhYmxlcyAqLwogCiAgIC8qIEZp Z3VyZSBvdXQgd2hlcmUgaXQgbmVlZHMgdG8gZ28gKi8KLSAgaHB0ciA9IChzdHJ1Y3QgbWVtZGlz a19oZWFkZXIgKikgJl9iaW5hcnlfbWVtZGlza19iaW5fc3RhcnQ7Ci0gIHBwdHIgPSAoc3RydWN0 IHBhdGNoX2FyZWEgKikoX2JpbmFyeV9tZW1kaXNrX2Jpbl9zdGFydCArIGhwdHItPnBhdGNoX29m ZnMpOworICBocHRyID0gKHN0cnVjdCBtZW1kaXNrX2hlYWRlciAqKSBtZW1kaXNrX2hvb2s7Cisg IHBwdHIgPSAoc3RydWN0IHBhdGNoX2FyZWEgKikobWVtZGlza19ob29rICsgaHB0ci0+cGF0Y2hf b2Zmcyk7CiAKICAgZG9zbWVtX2sgPSByZHpfMTYoQklPU19CQVNFTUVNKTsKICAgcHB0ci0+b2xk ZG9zbWVtID0gZG9zbWVtX2s7CkBAIC03MjYsMTAgKzczOCw2IEBAIF9fY2RlY2wgdm9pZCBzZXR1 cChfX2NkZWNsIHN5c2NhbGxfdCBjc19zeXNjYWxsLCB2b2lkICpjc19ib3VuY2UpCiAgIH0KICAg cHV0cygiIGFjY2VzcyB0byBoaWdoIG1lbW9yeVxuIik7CiAKLSAgLyogcHB0ci0+bWF4aW50MTNm dW5jIGRlZmF1bHRzIHRvIEVERCBlbmFibGVkLCBpZiBjb21waWxlZCBpbiAqLwotICBpZiAoIWRv X2VkZCkKLSAgICBwcHRyLT5tYXhpbnQxM2Z1bmMgPSBNQVhJTlQxM19OT0VERDsKLQogICAvKiBT ZXQgdXAgYSBkcml2ZSBwYXJhbWV0ZXIgdGFibGUgKi8KICAgaWYgKCBnZW9tZXRyeS0+ZHJpdmVu byAmIDB4ODAgKSB7CiAgICAgLyogSGFyZCBkaXNrICovCkBAIC04OTgsNyArOTA2LDcgQEAgX19j ZGVjbCB2b2lkIHNldHVwKF9fY2RlY2wgc3lzY2FsbF90IGNzX3N5c2NhbGwsIHZvaWQgKmNzX2Jv dW5jZSkKICAgICBocHRyID0gKHN0cnVjdCBtZW1kaXNrX2hlYWRlciAqKWRwcDsKIAogICAgIC8q IEFjdHVhbGx5IGNvcHkgdG8gbG93IG1lbW9yeSAqLwotICAgIGRwcCA9IG1lbXBjcHkoZHBwLCAm X2JpbmFyeV9tZW1kaXNrX2Jpbl9zdGFydCwgYmluX3NpemUpOworICAgIGRwcCA9IG1lbXBjcHko ZHBwLCBtZW1kaXNrX2hvb2ssIGJpbl9zaXplKTsKICAgICBkcHAgPSBtZW1wY3B5KGRwcCwgcmFu Z2VzLCAobnJhbmdlcysxKSpzaXplb2YocmFuZ2VzWzBdKSk7CiAgICAgZHBwID0gbWVtcGNweShk cHAsIHNoZHItPmNtZGxpbmUsIGNtZGxpbmVsZW4rMSk7CiAgIH0KLS0gCjEuNS4zLjQKCg= ------_=_NextPart_001_01C9A06C.565F4677--