|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer ! 3: * ! 4: * This file is free software; you can redistribute it and/or ! 5: * modify it under the terms of the GNU General Public License as ! 6: * published by the Free Software Foundation; either version 2 of ! 7: * the License, or (at your option) any later version. ! 8: * ! 9: * Originally this code was part of ucl the data compression library ! 10: * for upx the ``Ultimate Packer of eXecutables''. ! 11: * ! 12: * - Converted to gas assembly, and refitted to work with etherboot. ! 13: * Eric Biederman 20 Aug 2002 ! 14: * ! 15: * - Structure modified to be a subroutine call rather than an ! 16: * executable prefix. ! 17: * Michael Brown 30 Mar 2004 ! 18: * ! 19: * - Modified to be compilable as either 16-bit or 32-bit code. ! 20: * Michael Brown 9 Mar 2005 ! 21: */ ! 22: ! 23: FILE_LICENCE ( GPL2_OR_LATER ) ! 24: ! 25: /**************************************************************************** ! 26: * This file provides the decompress() and decompress16() functions ! 27: * which can be called in order to decompress an image compressed with ! 28: * the nrv2b utility in src/util. ! 29: * ! 30: * These functions are designed to be called by the prefix. They are ! 31: * position-independent code. ! 32: * ! 33: * The same basic assembly code is used to compile both ! 34: * decompress() and decompress16(). ! 35: **************************************************************************** ! 36: */ ! 37: ! 38: .text ! 39: .arch i386 ! 40: .section ".prefix.lib", "ax", @progbits ! 41: ! 42: #ifdef CODE16 ! 43: /**************************************************************************** ! 44: * decompress16 (real-mode near call, position independent) ! 45: * ! 46: * Decompress data in 16-bit mode ! 47: * ! 48: * Parameters (passed via registers): ! 49: * %ds:%esi - Start of compressed input data ! 50: * %es:%edi - Start of output buffer ! 51: * Returns: ! 52: * %ds:%esi - End of compressed input data ! 53: * %es:%edi - End of decompressed output data ! 54: * All other registers are preserved ! 55: * ! 56: * NOTE: It would be possible to build a smaller version of the ! 57: * decompression code for -DKEEP_IT_REAL by using ! 58: * #define REG(x) x ! 59: * to use 16-bit registers where possible. This would impose limits ! 60: * that the compressed data size must be in the range [1,65533-%si] ! 61: * and the uncompressed data size must be in the range [1,65536-%di] ! 62: * (where %si and %di are the input values for those registers). Note ! 63: * particularly that the lower limit is 1, not 0, and that the upper ! 64: * limit on the input (compressed) data really is 65533, since the ! 65: * algorithm may read up to three bytes beyond the end of the input ! 66: * data, since it reads dwords. ! 67: **************************************************************************** ! 68: */ ! 69: ! 70: #define REG(x) e ## x ! 71: #define ADDR32 addr32 ! 72: ! 73: .code16 ! 74: .globl decompress16 ! 75: decompress16: ! 76: ! 77: #else /* CODE16 */ ! 78: ! 79: /**************************************************************************** ! 80: * decompress (32-bit protected-mode near call, position independent) ! 81: * ! 82: * Parameters (passed via registers): ! 83: * %ds:%esi - Start of compressed input data ! 84: * %es:%edi - Start of output buffer ! 85: * Returns: ! 86: * %ds:%esi - End of compressed input data ! 87: * %es:%edi - End of decompressed output data ! 88: * All other registers are preserved ! 89: **************************************************************************** ! 90: */ ! 91: ! 92: #define REG(x) e ## x ! 93: #define ADDR32 ! 94: ! 95: .code32 ! 96: .globl decompress ! 97: decompress: ! 98: ! 99: #endif /* CODE16 */ ! 100: ! 101: #define xAX REG(ax) ! 102: #define xCX REG(cx) ! 103: #define xBP REG(bp) ! 104: #define xSI REG(si) ! 105: #define xDI REG(di) ! 106: ! 107: /* Save registers */ ! 108: push %xAX ! 109: pushl %ebx ! 110: push %xCX ! 111: push %xBP ! 112: /* Do the decompression */ ! 113: cld ! 114: xor %xBP, %xBP ! 115: dec %xBP /* last_m_off = -1 */ ! 116: jmp dcl1_n2b ! 117: ! 118: decompr_literals_n2b: ! 119: ADDR32 movsb ! 120: decompr_loop_n2b: ! 121: addl %ebx, %ebx ! 122: jnz dcl2_n2b ! 123: dcl1_n2b: ! 124: call getbit32 ! 125: dcl2_n2b: ! 126: jc decompr_literals_n2b ! 127: xor %xAX, %xAX ! 128: inc %xAX /* m_off = 1 */ ! 129: loop1_n2b: ! 130: call getbit1 ! 131: adc %xAX, %xAX /* m_off = m_off*2 + getbit() */ ! 132: call getbit1 ! 133: jnc loop1_n2b /* while(!getbit()) */ ! 134: sub $3, %xAX ! 135: jb decompr_ebpeax_n2b /* if (m_off == 2) goto decompr_ebpeax_n2b ? */ ! 136: shl $8, %xAX ! 137: ADDR32 movb (%xSI), %al /* m_off = (m_off - 3)*256 + src[ilen++] */ ! 138: inc %xSI ! 139: xor $-1, %xAX ! 140: jz decompr_end_n2b /* if (m_off == 0xffffffff) goto decomp_end_n2b */ ! 141: mov %xAX, %xBP /* last_m_off = m_off ?*/ ! 142: decompr_ebpeax_n2b: ! 143: xor %xCX, %xCX ! 144: call getbit1 ! 145: adc %xCX, %xCX /* m_len = getbit() */ ! 146: call getbit1 ! 147: adc %xCX, %xCX /* m_len = m_len*2 + getbit()) */ ! 148: jnz decompr_got_mlen_n2b /* if (m_len == 0) goto decompr_got_mlen_n2b */ ! 149: inc %xCX /* m_len++ */ ! 150: loop2_n2b: ! 151: call getbit1 ! 152: adc %xCX, %xCX /* m_len = m_len*2 + getbit() */ ! 153: call getbit1 ! 154: jnc loop2_n2b /* while(!getbit()) */ ! 155: inc %xCX ! 156: inc %xCX /* m_len += 2 */ ! 157: decompr_got_mlen_n2b: ! 158: cmp $-0xd00, %xBP ! 159: adc $1, %xCX /* m_len = m_len + 1 + (last_m_off > 0xd00) */ ! 160: push %xSI ! 161: ADDR32 lea (%xBP,%xDI), %xSI /* m_pos = dst + olen + -m_off */ ! 162: rep ! 163: es ADDR32 movsb /* dst[olen++] = *m_pos++ while(m_len > 0) */ ! 164: pop %xSI ! 165: jmp decompr_loop_n2b ! 166: ! 167: ! 168: getbit1: ! 169: addl %ebx, %ebx ! 170: jnz 1f ! 171: getbit32: ! 172: ADDR32 movl (%xSI), %ebx ! 173: sub $-4, %xSI /* sets carry flag */ ! 174: adcl %ebx, %ebx ! 175: 1: ! 176: ret ! 177: ! 178: decompr_end_n2b: ! 179: /* Restore registers and return */ ! 180: pop %xBP ! 181: pop %xCX ! 182: popl %ebx ! 183: pop %xAX ! 184: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.