Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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