You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

unlzma.S 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. /*
  2. * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program 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 the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. */
  19. FILE_LICENCE ( GPL2_OR_LATER );
  20. /****************************************************************************
  21. *
  22. * This file provides the decompress() and decompress16() functions
  23. * which can be called in order to decompress an LZMA-compressed
  24. * image. The code is modelled on the public-domain "XZ Embedded"
  25. * implementation as used by the Linux kernel. Symbol names are
  26. * chosen to match the XZ Embedded implementation where possible, for
  27. * ease of reference.
  28. *
  29. * This code is optimised for size rather than speed, since the amount
  30. * of data to be decompressed is trivially small by modern standards.
  31. *
  32. * The same basic assembly code is used to compile both decompress()
  33. * and decompress16().
  34. *
  35. * Note that these functions require large amounts of stack space.
  36. *
  37. ****************************************************************************
  38. */
  39. .text
  40. .arch i586
  41. .section ".prefix.lib", "ax", @progbits
  42. #ifdef CODE16
  43. #define ADDR16
  44. #define ADDR32 addr32
  45. #define decompress decompress16
  46. .code16
  47. #else /* CODE16 */
  48. #define ADDR16 addr16
  49. #define ADDR32
  50. .code32
  51. #endif /* CODE16 */
  52. /****************************************************************************
  53. * Debugging
  54. ****************************************************************************
  55. *
  56. * This code will usually run in 16-bit protected mode, in which case
  57. * only the 0xe9 debug port (present on some virtual machines) can be
  58. * used.
  59. *
  60. * To debug on real hardware, build with DEBUG=libprefix. This will
  61. * cause this code to be called in flat real mode, and so DEBUG_INT10
  62. * may be used.
  63. */
  64. /* Enable debugging via 0xe9 debug port */
  65. #define DEBUG_E9 0
  66. /* Enable debugging via BIOS INT 10 (works only when in flat real mode) */
  67. #define DEBUG_INT10 0
  68. #if ( DEBUG_E9 || DEBUG_INT10 )
  69. .macro print_character, reg
  70. pushfl
  71. pushw %ax
  72. pushw %bx
  73. pushw %bp
  74. movb \reg, %al
  75. movw $0x0007, %bx
  76. movb $0x0e, %ah
  77. #if DEBUG_E9
  78. outb %al, $0xe9
  79. #endif
  80. #if DEBUG_INT10
  81. cmpb $('\n'), %al
  82. jne L\@
  83. int $0x10
  84. movb $('\r'), %al
  85. L\@: int $0x10
  86. #endif
  87. popw %bp
  88. popw %bx
  89. popw %ax
  90. popfl
  91. .endm
  92. .macro print_hex_nibble
  93. pushfl
  94. pushw %ax
  95. cmpb $10, %al
  96. sbb $0x69, %al
  97. das
  98. print_character %al
  99. popw %ax
  100. popfl
  101. .endm
  102. .macro print_hex_byte, reg
  103. pushfl
  104. pushw %ax
  105. movb \reg, %al
  106. pushw %ax
  107. shrb $4, %al
  108. print_hex_nibble
  109. popw %ax
  110. andb $0x0f, %al
  111. print_hex_nibble
  112. popw %ax
  113. popfl
  114. .endm
  115. .macro print_hex_word, reg
  116. pushw %ax
  117. movw \reg, %ax
  118. print_hex_byte %ah
  119. print_hex_byte %al
  120. popw %ax
  121. .endm
  122. .macro print_hex_dword, reg
  123. pushl %eax
  124. movl \reg, %eax
  125. rorl $16, %eax
  126. print_hex_word %ax
  127. rorl $16, %eax
  128. print_hex_word %ax
  129. popl %eax
  130. .endm
  131. #else
  132. .macro print_character, char
  133. .endm
  134. .macro print_hex_byte, reg
  135. .endm
  136. .macro print_hex_word, reg
  137. .endm
  138. .macro print_hex_dword, reg
  139. .endm
  140. #endif
  141. /****************************************************************************
  142. * LZMA parameters and data structures
  143. ****************************************************************************
  144. */
  145. /* LZMA decompressor states (as used in XZ Embedded) */
  146. #define STATE_LIT_LIT 0x00
  147. #define STATE_MATCH_LIT_LIT 0x01
  148. #define STATE_REP_LIT_LIT 0x02
  149. #define STATE_SHORTREP_LIT_LIT 0x03
  150. #define STATE_MATCH_LIT 0x04
  151. #define STATE_REP_LIT 0x05
  152. #define STATE_SHORTREP_LIT 0x06
  153. #define STATE_LIT_MATCH 0x07
  154. #define STATE_LIT_LONGREP 0x08
  155. #define STATE_LIT_SHORTREP 0x09
  156. #define STATE_NONLIT_MATCH 0x0a
  157. #define STATE_NONLIT_REP 0x0b
  158. /* LZMA maximum decompressor state in which most recent symbol was a literal */
  159. #define STATE_LIT_MAX 0x06
  160. /* LZMA number of literal context bits ("lc=" parameter) */
  161. #define LZMA_LC 2
  162. .struct 0
  163. lzma_len_dec:
  164. choice: .word 0
  165. choice2: .word 0
  166. low: .rept ( 1 << 3 )
  167. .word 0
  168. .endr
  169. mid: .rept ( 1 << 3 )
  170. .word 0
  171. .endr
  172. high: .rept ( 1 << 8 )
  173. .word 0
  174. .endr
  175. .equ sizeof__lzma_len_dec, . - lzma_len_dec
  176. .previous
  177. .struct 0
  178. lzma_dec:
  179. in_start: .long 0
  180. out_start: .long 0
  181. rc_code: .long 0
  182. rc_range: .long 0
  183. len: .word 0
  184. reps:
  185. rep0: .long 0
  186. rep1: .long 0
  187. rep2: .long 0
  188. rep3: .long 0
  189. probs:
  190. is_match: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  191. is_rep: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  192. is_rep0: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  193. is_rep1: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  194. is_rep2: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  195. is_rep0_long: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  196. dist_slot: .rept ( 4 * ( 1 << 6 ) )
  197. .word 0
  198. .endr
  199. dist_special: .rept ( ( 1 << ( 14 / 2 ) ) - 14 )
  200. .word 0
  201. .endr
  202. dist_align: .rept ( 1 << 4 )
  203. .word 0
  204. .endr
  205. match_len_dec: .space sizeof__lzma_len_dec
  206. rep_len_dec: .space sizeof__lzma_len_dec
  207. literal: .rept ( ( 1 << LZMA_LC ) * 0x300 )
  208. .word 0
  209. .endr
  210. .align 4
  211. .equ sizeof__lzma_dec, . - lzma_dec
  212. .previous
  213. /*****************************************************************************
  214. * Normalise range encoder
  215. *
  216. * Parameters:
  217. * %ss:%ebp : LZMA parameter block
  218. * %ds:%esi : compressed input data pointer
  219. * Returns:
  220. * %ds:%esi : compressed input data pointer (possibly updated)
  221. * %eax : current range
  222. *****************************************************************************
  223. */
  224. rc_normalise:
  225. /* Check if rc_range is less than 1<<24 */
  226. testb $0xff, (rc_range+3)(%ebp)
  227. jnz 1f
  228. /* If it is, shift in a new byte from the compressed input data */
  229. shll $8, rc_range(%ebp)
  230. shll $8, rc_code(%ebp)
  231. ADDR32 lodsb
  232. movb %al, (rc_code+0)(%ebp)
  233. 1: /* Return current range */
  234. movl rc_range(%ebp), %eax
  235. ret
  236. .size rc_normalise, . - rc_normalise
  237. /*****************************************************************************
  238. * Decode single range-encoded bit using a probability estimate
  239. *
  240. * Parameters:
  241. * %ss:%ebp : LZMA parameter block
  242. * %ds:%esi : compressed input data pointer
  243. * %ebx : probability estimate pointer (offset from %ebp)
  244. * Returns:
  245. * %ds:%esi : compressed input data pointer (possibly updated)
  246. * CF : decoded bit
  247. * ZF : inverse of decoded bit
  248. * Corrupts:
  249. * none
  250. *****************************************************************************
  251. */
  252. rc_bit:
  253. /* Preserve registers */
  254. pushl %eax
  255. pushl %edx
  256. /* Perform normalisation */
  257. call rc_normalise
  258. /* Calculate bound in %eax and probability estimate in %dx */
  259. shrl $11, %eax
  260. movzwl (%ebp,%ebx), %edx
  261. mul %edx /* will zero %edx */
  262. movw (%ebp,%ebx), %dx
  263. /* Compare code against bound */
  264. cmpl %eax, rc_code(%ebp)
  265. jae 2f
  266. 1: /* Code is less than bound */
  267. movl %eax, rc_range(%ebp)
  268. negw %dx
  269. addw $(1<<11), %dx
  270. shrw $5, %dx
  271. addw %dx, (%ebp,%ebx)
  272. xorw %ax, %ax /* Clear CF, set ZF */
  273. jmp 99f
  274. 2: /* Code is greater than or equal to bound */
  275. subl %eax, rc_range(%ebp)
  276. subl %eax, rc_code(%ebp)
  277. shrw $5, %dx
  278. subw %dx, (%ebp,%ebx)
  279. incw %dx /* Clear ZF (%dx is 11-bit; can never wrap) */
  280. stc /* Set CF */
  281. 99: /* Restore registers and return */
  282. popl %edx
  283. popl %eax
  284. ret
  285. .size rc_bit, . - rc_bit
  286. /*****************************************************************************
  287. * Decode MSB-first bittree
  288. *
  289. * Parameters:
  290. * %ss:%ebp : LZMA parameter block
  291. * %ds:%esi : compressed input data pointer
  292. * %ebx : probability estimate set pointer (offset from %ebp)
  293. * %cx : number of bits to decode
  294. * Returns:
  295. * %ds:%esi : compressed input data pointer (possibly updated)
  296. * %eax : decoded bittree
  297. * Corrupts:
  298. * none
  299. *****************************************************************************
  300. */
  301. rc_bittree:
  302. /* Preserve registers */
  303. pushl %edi
  304. pushw %cx
  305. movl %ebx, %edi
  306. /* Initialise registers */
  307. movl $1, %eax
  308. 1: /* Decode bit */
  309. leaw (%edi,%eax,2), %bx /* high word always zero anyway */
  310. call rc_bit
  311. rclw %ax
  312. ADDR16 loop 1b
  313. /* Restore registers, clear unwanted high bit of result, and return */
  314. movl %edi, %ebx
  315. popw %cx
  316. popl %edi
  317. btrw %cx, %ax
  318. ret
  319. .size rc_bittree, . - rc_bittree
  320. /*****************************************************************************
  321. * Decode LSB-first bittree
  322. *
  323. * Parameters:
  324. * %ss:%ebp : LZMA parameter block
  325. * %ds:%esi : compressed input data pointer
  326. * %ebx : probability estimate set pointer (offset from %ebp)
  327. * %cx : number of bits to decode
  328. * Returns:
  329. * %ds:%esi : compressed input data pointer (possibly updated)
  330. * %eax : decoded bittree
  331. * Corrupts:
  332. * none
  333. *****************************************************************************
  334. */
  335. rc_bittree_reverse:
  336. /* Preserve registers */
  337. pushw %cx
  338. /* Decode bittree */
  339. call rc_bittree
  340. 1: /* Reverse result */
  341. rcrb %al
  342. rclb %ah
  343. ADDR16 loop 1b
  344. shrw $8, %ax
  345. /* Restore registers and return */
  346. popw %cx
  347. ret
  348. .size rc_bittree_reverse, . - rc_bittree_reverse
  349. /*****************************************************************************
  350. * Decode MSB-first bittree with optional match byte
  351. *
  352. * Parameters:
  353. * %ss:%ebp : LZMA parameter block
  354. * %ds:%esi : compressed input data pointer
  355. * %ebx : probability estimate set pointer (offset from %ebp)
  356. * %cl : match byte
  357. * %ch : 1 to use match byte, 0 to ignore match byte
  358. * Returns:
  359. * %ds:%esi : compressed input data pointer (possibly updated)
  360. * %eax : decoded bittree
  361. * Corrupts:
  362. * none
  363. *****************************************************************************
  364. */
  365. rc_bittree_match:
  366. /* Preserve registers */
  367. pushl %edi
  368. pushw %cx
  369. pushw %dx
  370. movl %ebx, %edi
  371. /* Initialise registers */
  372. movl $1, %eax
  373. 1: /* Decode bit */
  374. rolb $1, %cl
  375. movw %cx, %dx
  376. andb %dh, %dl /* match_bit in %dl */
  377. movw %dx, %bx
  378. addb %bl, %bh
  379. xorb %bl, %bl
  380. addw %ax, %bx /* offset + match_bit + symbol */
  381. leaw (%edi,%ebx,2), %bx /* high word always zero anyway */
  382. call rc_bit
  383. rclw %ax
  384. movb %al, %dh
  385. notb %dh
  386. xorb %dh, %dl
  387. andb %dl, %ch /* offset &= ( match_bit ^ bit ) */
  388. testb %ah, %ah
  389. jz 1b
  390. /* Restore registers, clear unwanted high bit of result, and return */
  391. movl %edi, %ebx
  392. popw %dx
  393. popw %cx
  394. popl %edi
  395. xorb %ah, %ah
  396. ret
  397. .size rc_bittree_match, . - rc_bittree_match
  398. /*****************************************************************************
  399. * Decode direct bits (no probability estimates)
  400. *
  401. * Parameters:
  402. * %ss:%ebp : LZMA parameter block
  403. * %ds:%esi : compressed input data pointer
  404. * %cx : number of bits to decode
  405. * Returns:
  406. * %ds:%esi : compressed input data pointer (possibly updated)
  407. * %eax : decoded bits
  408. * Corrupts:
  409. * none
  410. *****************************************************************************
  411. */
  412. rc_direct:
  413. /* Preserve registers */
  414. pushl %ebx
  415. pushw %cx
  416. pushl %edx
  417. /* Initialise registers */
  418. xorl %edx, %edx
  419. 1: /* Perform normalisation */
  420. call rc_normalise
  421. /* Decode bit */
  422. shrl $1, %eax
  423. movl %eax, rc_range(%ebp)
  424. movl rc_code(%ebp), %ebx
  425. subl %eax, %ebx
  426. js 2f
  427. movl %ebx, rc_code(%ebp)
  428. 2: rcll %ebx
  429. rcll %edx
  430. xorb $1, %dl
  431. ADDR16 loop 1b
  432. /* Restore registers and return */
  433. movl %edx, %eax
  434. popl %edx
  435. popw %cx
  436. popl %ebx
  437. ret
  438. .size rc_direct, . - rc_direct
  439. /*****************************************************************************
  440. * Decode an LZMA literal
  441. *
  442. * Parameters:
  443. * %ss:%ebp : LZMA parameter block
  444. * %ds:%esi : compressed input data pointer
  445. * %es:%edi : uncompressed output data pointer
  446. * %edx : LZMA state
  447. * Returns:
  448. * %ds:%esi : compressed input data pointer (possibly updated)
  449. * %es:%edi : uncompressed output data pointer (updated)
  450. * %edx : LZMA state
  451. * CF : end of payload marker found (always zero)
  452. * Corrupts:
  453. * %eax
  454. * %ebx
  455. * %ecx
  456. *****************************************************************************
  457. *
  458. * Literals are coded as an eight-bit tree, using a match byte if the
  459. * previous symbol was not a literal.
  460. *
  461. */
  462. lzma_literal:
  463. /* Get most recent output byte, if available */
  464. xorl %ebx, %ebx
  465. cmpl %esi, in_start(%ebp)
  466. je 1f
  467. movb %es:-1(%edi), %bh
  468. 1: /* Locate probability estimate set */
  469. shrb $( 8 - LZMA_LC ), %bh
  470. shlb $1, %bh
  471. leaw literal(%ebx,%ebx,2), %bx
  472. /* Get match byte, if applicable */
  473. xorw %cx, %cx
  474. cmpb $STATE_LIT_MAX, %dl
  475. jbe 1f
  476. movl rep0(%ebp), %eax
  477. notl %eax
  478. movb %es:(%edi,%eax), %cl
  479. movb $1, %ch
  480. 1: /* Decode bittree */
  481. call rc_bittree_match
  482. /* Store output byte */
  483. ADDR32 stosb
  484. print_hex_byte %al
  485. print_character $(' ')
  486. /* Update LZMA state */
  487. subb $3, %dl
  488. jns 1f
  489. xorb %dl, %dl
  490. 1: cmpb $7, %dl
  491. jb 1f
  492. subb $3, %dl
  493. 1: /* Clear CF and return */
  494. clc
  495. ret
  496. .size lzma_literal, . - lzma_literal
  497. /*****************************************************************************
  498. * Decode an LZMA length
  499. *
  500. * Parameters:
  501. * %ss:%ebp : LZMA parameter block
  502. * %ds:%esi : compressed input data pointer
  503. * %ebx : length parameter pointer (offset from %ebp)
  504. * Returns:
  505. * %ds:%esi : compressed input data pointer (possibly updated)
  506. * Corrupts:
  507. * %ebx
  508. *****************************************************************************
  509. *
  510. * Lengths are encoded as:
  511. *
  512. * "0" + 3 bits : lengths 2-9 ("low")
  513. * "10" + 3 bits : lengths 10-17 ("mid")
  514. * "11" + 8 bits : lengths 18-273 ("high")
  515. */
  516. lzma_len:
  517. /* Preserve registers */
  518. pushl %eax
  519. pushl %ecx
  520. pushl %edi
  521. movl %ebx, %edi
  522. /* Start by assuming three bits and a base length of 2 */
  523. movw $3, %cx
  524. movw $2, len(%ebp)
  525. /* Check low-length choice bit */
  526. leal choice(%edi), %ebx
  527. call rc_bit
  528. leal low(%edi), %ebx
  529. jz 1f
  530. /* Check high-length choice bit */
  531. leal choice2(%edi), %ebx
  532. call rc_bit
  533. leal mid(%edi), %ebx
  534. movb $10, len(%ebp)
  535. jz 1f
  536. leal high(%edi), %ebx
  537. movb $8, %cl
  538. movb $18, len(%ebp)
  539. 1: /* Get encoded length */
  540. call rc_bittree
  541. addw %ax, len(%ebp)
  542. /* Restore registers and return */
  543. movl %edi, %ebx
  544. popl %edi
  545. popl %ecx
  546. popl %eax
  547. ret
  548. .size lzma_len, . - lzma_len
  549. /*****************************************************************************
  550. * Copy (possibly repeated) matched data
  551. *
  552. * Parameters:
  553. * %ss:%ebp : LZMA parameter block
  554. * %ds:%esi : compressed input data pointer
  555. * %es:%edi : uncompressed output data pointer
  556. * %cl : repeated match distance index (for repeated matches)
  557. * %eax : match distance (for non-repeated matches)
  558. * Returns:
  559. * %ds:%esi : compressed input data pointer (possibly updated)
  560. * %es:%edi : uncompressed output data pointer
  561. * CF : match distance is out of range
  562. * Corrupts:
  563. * %eax
  564. * %ebx
  565. * %ecx
  566. *****************************************************************************
  567. */
  568. match: /* Update repeated match list */
  569. print_character $('[')
  570. movl $3, %ecx
  571. jmp 1f
  572. match_rep:
  573. print_character $('[')
  574. print_character $('R')
  575. print_hex_byte %cl
  576. print_character $('=')
  577. movzbl %cl, %ecx
  578. movl reps(%ebp,%ecx,4), %eax
  579. jcxz 2f
  580. 1: movl (reps-4)(%ebp,%ecx,4), %ebx
  581. movl %ebx, reps(%ebp,%ecx,4)
  582. loop 1b
  583. movl %eax, rep0(%ebp)
  584. 2: /* Preserve registers */
  585. pushl %esi
  586. /* Get stored match length */
  587. movzwl len(%ebp), %ecx
  588. print_hex_dword %eax
  589. print_character $('+')
  590. print_hex_word %cx
  591. print_character $(']')
  592. print_character $(' ')
  593. /* Abort with CF set if match distance is out of range */
  594. movl out_start(%ebp), %esi
  595. negl %esi
  596. leal -1(%edi,%esi), %esi
  597. cmpl %eax, %esi
  598. jc 99f
  599. /* Perform copy */
  600. notl %eax
  601. leal (%edi,%eax), %esi
  602. ADDR32 es rep movsb
  603. 99: /* Restore registers and return */
  604. popl %esi
  605. ret
  606. .size match, . - match
  607. /*****************************************************************************
  608. * Decode an LZMA match
  609. *
  610. * Parameters:
  611. * %ss:%ebp : LZMA parameter block
  612. * %ds:%esi : compressed input data pointer
  613. * %es:%edi : uncompressed output data pointer
  614. * %edx : LZMA state
  615. * Returns:
  616. * %ds:%esi : compressed input data pointer (possibly updated)
  617. * %es:%edi : uncompressed output data pointer
  618. * %edx : LZMA state
  619. * CF : end of payload marker found
  620. * Corrupts:
  621. * %eax
  622. * %ebx
  623. * %ecx
  624. *****************************************************************************
  625. *
  626. * Matches are encoded as an LZMA length followed by a 6-bit "distance
  627. * slot" code, 0-26 fixed-probability bits, and 0-5 context encoded
  628. * bits.
  629. */
  630. lzma_match:
  631. /* Preserve registers */
  632. pushl %edi
  633. /* Update LZMA state */
  634. cmpb $STATE_LIT_MAX, %dl
  635. movb $STATE_LIT_MATCH, %dl
  636. jbe 1f
  637. movb $STATE_NONLIT_MATCH, %dl
  638. 1: /* Decode length */
  639. movl $match_len_dec, %ebx
  640. call lzma_len
  641. /* Decode distance slot */
  642. movw len(%ebp), %bx
  643. subw $2, %bx
  644. cmpw $4, %bx
  645. jb 1f
  646. movw $3, %bx
  647. 1: shlw $7, %bx
  648. addw $dist_slot, %bx
  649. movw $6, %cx
  650. call rc_bittree
  651. /* Distance slots 0-3 are literal distances */
  652. cmpb $4, %al
  653. jb 99f
  654. /* Determine initial bits: 10/11 for even/odd distance codes */
  655. movl %eax, %edi
  656. andw $1, %di
  657. orw $2, %di
  658. /* Determine number of context-encoded bits */
  659. movw %ax, %cx
  660. shrb $1, %cl
  661. decb %cl
  662. /* Select context to be used in absence of fixed-probability bits */
  663. movl %edi, %ebx
  664. shlw %cl, %bx
  665. subw %ax, %bx
  666. leaw (dist_special-2)(%ebx,%ebx), %bx
  667. /* Decode fixed-probability bits, if any */
  668. cmpb $6, %cl
  669. jb 1f
  670. subb $4, %cl
  671. shll %cl, %edi
  672. call rc_direct
  673. orl %eax, %edi
  674. /* Select context to be used in presence of fixed-probability bits */
  675. movb $4, %cl
  676. movl $dist_align, %ebx
  677. 1: /* Decode context-encoded bits */
  678. shll %cl, %edi
  679. call rc_bittree_reverse
  680. orl %edi, %eax
  681. 99: /* Restore registers and tail-call */
  682. popl %edi
  683. jmp match
  684. .size lzma_match, . - lzma_match
  685. /*****************************************************************************
  686. * Decode an LZMA repeated match
  687. *
  688. * Parameters:
  689. * %ss:%ebp : LZMA parameter block
  690. * %ds:%esi : compressed input data pointer
  691. * %es:%edi : uncompressed output data pointer
  692. * %edx : LZMA state
  693. * Returns:
  694. * %ds:%esi : compressed input data pointer (possibly updated)
  695. * %es:%edi : uncompressed output data pointer
  696. * %edx : LZMA state
  697. * CF : end of payload marker found
  698. * Corrupts:
  699. * %eax
  700. * %ebx
  701. * %ecx
  702. *****************************************************************************
  703. *
  704. * Repeated matches are encoded as:
  705. *
  706. * "00" : shortrep0 (implicit length 1)
  707. * "01" + len : longrep0
  708. * "10" + len : longrep1
  709. * "110" + len : longrep2
  710. * "111" + len : longrep3
  711. */
  712. lzma_rep_match:
  713. /* Initially assume longrep0 */
  714. movw $(STATE_LIT_LONGREP << 8), %cx
  715. /* Get is_rep0 bit */
  716. leal is_rep0(,%edx,2), %ebx
  717. call rc_bit
  718. jnz 1f
  719. /* Get is_rep0_long bit */
  720. leal is_rep0_long(,%edx,2), %ebx
  721. call rc_bit
  722. jnz 98f
  723. movw $1, len(%ebp)
  724. movb $STATE_LIT_SHORTREP, %ch
  725. jmp 99f
  726. 1: /* Get is_rep1 bit */
  727. incb %cl
  728. leal is_rep1(,%edx,2), %ebx
  729. call rc_bit
  730. jz 98f
  731. /* Get is_rep2 bit */
  732. incb %cl
  733. leal is_rep2(,%edx,2), %ebx
  734. call rc_bit
  735. adcb $0, %cl
  736. 98: /* Decode length */
  737. movl $rep_len_dec, %ebx
  738. call lzma_len
  739. 99: /* Update LZMA state */
  740. cmpb $STATE_LIT_MAX, %dl
  741. movb %ch, %dl
  742. jbe 1f
  743. movb $STATE_NONLIT_REP, %dl
  744. 1: /* Tail call */
  745. jmp match_rep
  746. .size lzma_match, . - lzma_match
  747. /*****************************************************************************
  748. * Decode one LZMA symbol
  749. *
  750. * Parameters:
  751. * %ss:%ebp : LZMA parameter block
  752. * %ds:%esi : compressed input data pointer
  753. * %es:%edi : uncompressed output data pointer
  754. * %edx : LZMA state
  755. * Returns:
  756. * %ds:%esi : compressed input data pointer (possibly updated)
  757. * %es:%edi : uncompressed output data pointer (updated)
  758. * %edx : LZMA state
  759. * CF : end of payload marker found
  760. * Corrupts:
  761. * %eax
  762. * %ebx
  763. * %ecx
  764. *****************************************************************************
  765. */
  766. lzma_decode:
  767. /* Get is_match bit */
  768. leal is_match(,%edx,2), %ebx
  769. call rc_bit
  770. jz lzma_literal
  771. /* Get is_rep bit */
  772. leal is_rep(,%edx,2), %ebx
  773. call rc_bit
  774. jz lzma_match
  775. jmp lzma_rep_match
  776. .size lzma_decode, . - lzma_decode
  777. /****************************************************************************
  778. * Undo effect of branch-call-jump (BCJ) filter
  779. *
  780. * Parameters:
  781. * %es:%esi : start of uncompressed output data (note %es)
  782. * %es:%edi : end of uncompressed output data
  783. * Returns:
  784. * Corrupts:
  785. * %eax
  786. * %ebx
  787. * %ecx
  788. * %edx
  789. * %esi
  790. *****************************************************************************
  791. */
  792. bcj_filter:
  793. /* Store (negative) start of data in %edx */
  794. movl %esi, %edx
  795. negl %edx
  796. /* Calculate limit in %ecx */
  797. leal -5(%edi,%edx), %ecx
  798. 1: /* Calculate offset in %ebx */
  799. leal (%esi,%edx), %ebx
  800. /* Check for end of data */
  801. cmpl %ecx, %ebx
  802. ja 99f
  803. /* Check for an opcode which would be followed by a rel32 address */
  804. ADDR32 es lodsb
  805. andb $0xfe, %al
  806. cmpb $0xe8, %al
  807. jne 1b
  808. /* Get current jump target value in %eax */
  809. ADDR32 es lodsl
  810. /* Convert absolute addresses in the range [0,limit) back to
  811. * relative addresses in the range [-offset,limit-offset).
  812. */
  813. cmpl %ecx, %eax
  814. jae 2f
  815. subl %ebx,%es:-4(%esi)
  816. 2: /* Convert negative numbers in the range [-offset,0) back to
  817. * positive numbers in the range [limit-offset,limit).
  818. */
  819. notl %eax /* Range is now [0,offset) */
  820. cmpl %ebx, %eax
  821. jae 1b
  822. addl %ecx,%es:-4(%esi)
  823. jmp 1b
  824. 99: /* Return */
  825. ret
  826. .size bcj_filter, . - bcj_filter
  827. /****************************************************************************
  828. * decompress (real-mode or 16/32-bit protected-mode near call)
  829. *
  830. * Decompress data
  831. *
  832. * Parameters (passed via registers):
  833. * %ds:%esi : Start of compressed input data
  834. * %es:%edi : Start of output buffer
  835. * Returns:
  836. * %ds:%esi - End of compressed input data
  837. * %es:%edi - End of decompressed output data
  838. * All other registers are preserved
  839. *
  840. * NOTE: It would be possible to build a smaller version of the
  841. * decompression code for -DKEEP_IT_REAL by using 16-bit registers
  842. * where possible.
  843. ****************************************************************************
  844. */
  845. .globl decompress
  846. decompress:
  847. /* Preserve registers */
  848. pushl %eax
  849. pushl %ebx
  850. pushl %ecx
  851. pushl %edx
  852. pushl %ebp
  853. /* Allocate parameter block */
  854. subl $sizeof__lzma_dec, %esp
  855. movl %esp, %ebp
  856. /* Zero parameter block and set all probabilities to 0.5 */
  857. pushl %edi
  858. pushw %es
  859. pushw %ss
  860. popw %es
  861. movl %ebp, %edi
  862. xorl %eax, %eax
  863. movl $( sizeof__lzma_dec / 4 ), %ecx
  864. ADDR32 rep stosl
  865. leal probs(%ebp), %edi
  866. movw $( ( 1 << 11 ) / 2 ), %ax
  867. movl $( ( sizeof__lzma_dec - probs ) / 2 ), %ecx
  868. ADDR32 rep stosw
  869. popw %es
  870. popl %edi
  871. /* Initialise remaining parameters */
  872. movl %esi, in_start(%ebp)
  873. movl %edi, out_start(%ebp)
  874. print_character $('\n')
  875. ADDR32 lodsb /* discard initial byte */
  876. print_hex_byte %al
  877. ADDR32 lodsl
  878. bswapl %eax
  879. print_hex_dword %eax
  880. print_character $('\n')
  881. movl %eax, rc_code(%ebp)
  882. decl rc_range(%ebp)
  883. movl $STATE_LIT_LIT, %edx
  884. 1: /* Decompress until we reach end of buffer */
  885. call lzma_decode
  886. jnc 1b
  887. call rc_normalise
  888. print_character $('\n')
  889. /* Undo BCJ filter */
  890. pushl %esi
  891. movl out_start(%ebp), %esi
  892. call bcj_filter
  893. popl %esi
  894. /* Restore registers and return */
  895. addl $sizeof__lzma_dec, %esp
  896. popl %ebp
  897. popl %edx
  898. popl %ecx
  899. popl %ebx
  900. popl %eax
  901. ret
  902. /* Specify minimum amount of stack space required */
  903. .globl _min_decompress_stack
  904. .equ _min_decompress_stack, ( sizeof__lzma_dec + 512 /* margin */ )