Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Branch/Call/Jump (BCJ) filter decoders
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Authors: Lasse Collin <lasse.collin@tukaani.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *          Igor Pavlov <https://7-zip.org/>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This file has been put into the public domain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * You can do whatever you want with this file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "xz_private.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * The rest of the file is inside this ifdef. It makes things a little more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * convenient when building without support for any BCJ filters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #ifdef XZ_DEC_BCJ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) struct xz_dec_bcj {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	/* Type of the BCJ filter being used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 		BCJ_X86 = 4,        /* x86 or x86-64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 		BCJ_POWERPC = 5,    /* Big endian only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 		BCJ_IA64 = 6,       /* Big or little endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 		BCJ_ARM = 7,        /* Little endian only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 		BCJ_ARMTHUMB = 8,   /* Little endian only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 		BCJ_SPARC = 9       /* Big or little endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	} type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	 * Return value of the next filter in the chain. We need to preserve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	 * this information across calls, because we must not call the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	 * filter anymore once it has returned XZ_STREAM_END.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	enum xz_ret ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	/* True if we are operating in single-call mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	bool single_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	 * Absolute position relative to the beginning of the uncompressed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	 * data (in a single .xz Block). We care only about the lowest 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	 * bits so this doesn't need to be uint64_t even with big files.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	uint32_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	/* x86 filter state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	uint32_t x86_prev_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	/* Temporary space to hold the variables from struct xz_buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	uint8_t *out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	size_t out_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	size_t out_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		/* Amount of already filtered data in the beginning of buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		size_t filtered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		/* Total amount of data currently stored in buf  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		 * Buffer to hold a mix of filtered and unfiltered data. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		 * needs to be big enough to hold Alignment + 2 * Look-ahead:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		 * Type         Alignment   Look-ahead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		 * x86              1           4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		 * PowerPC          4           0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		 * IA-64           16           0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		 * ARM              4           0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		 * ARM-Thumb        2           2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		 * SPARC            4           0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		uint8_t buf[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	} temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #ifdef XZ_DEC_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * This is used to test the most significant byte of a memory address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * in an x86 instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) static inline int bcj_x86_test_msbyte(uint8_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	return b == 0x00 || b == 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	static const bool mask_to_allowed_status[8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		= { true, true, true, false, true, false, false, false };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	static const uint8_t mask_to_bit_num[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	size_t prev_pos = (size_t)-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	uint32_t prev_mask = s->x86_prev_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	uint32_t src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	uint32_t dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	uint32_t j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	uint8_t b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (size <= 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	size -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	for (i = 0; i < size; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		if ((buf[i] & 0xFE) != 0xE8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		prev_pos = i - prev_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		if (prev_pos > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			prev_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			prev_mask = (prev_mask << (prev_pos - 1)) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			if (prev_mask != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 				b = buf[i + 4 - mask_to_bit_num[prev_mask]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				if (!mask_to_allowed_status[prev_mask]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 						|| bcj_x86_test_msbyte(b)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 					prev_pos = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 					prev_mask = (prev_mask << 1) | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		prev_pos = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		if (bcj_x86_test_msbyte(buf[i + 4])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			src = get_unaligned_le32(buf + i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			while (true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 				dest = src - (s->pos + (uint32_t)i + 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 				if (prev_mask == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 				j = mask_to_bit_num[prev_mask] * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 				b = (uint8_t)(dest >> (24 - j));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 				if (!bcj_x86_test_msbyte(b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 				src = dest ^ (((uint32_t)1 << (32 - j)) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			dest &= 0x01FFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			dest |= (uint32_t)0 - (dest & 0x01000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			put_unaligned_le32(dest, buf + i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			i += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			prev_mask = (prev_mask << 1) | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	prev_pos = i - prev_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	s->x86_prev_mask = prev_pos > 3 ? 0 : prev_mask << (prev_pos - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #ifdef XZ_DEC_POWERPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static size_t bcj_powerpc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	uint32_t instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	for (i = 0; i + 4 <= size; i += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		instr = get_unaligned_be32(buf + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		if ((instr & 0xFC000003) == 0x48000001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			instr &= 0x03FFFFFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			instr -= s->pos + (uint32_t)i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			instr &= 0x03FFFFFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			instr |= 0x48000001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 			put_unaligned_be32(instr, buf + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #ifdef XZ_DEC_IA64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	static const uint8_t branch_table[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		0, 0, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		0, 0, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		4, 4, 6, 6, 0, 0, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		4, 4, 0, 0, 4, 4, 0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	 * The local variables take a little bit stack space, but it's less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	 * than what LZMA2 decoder takes, so it doesn't make sense to reduce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	 * stack usage here without doing that for the LZMA2 decoder too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	/* Loop counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	size_t j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	/* Instruction slot (0, 1, or 2) in the 128-bit instruction word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	uint32_t slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	/* Bitwise offset of the instruction indicated by slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	uint32_t bit_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	/* bit_pos split into byte and bit parts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	uint32_t byte_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	uint32_t bit_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	/* Address part of an instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	uint32_t addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	/* Mask used to detect which instructions to convert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	uint32_t mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	/* 41-bit instruction stored somewhere in the lowest 48 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	uint64_t instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	/* Instruction normalized with bit_res for easier manipulation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	uint64_t norm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	for (i = 0; i + 16 <= size; i += 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		mask = branch_table[buf[i] & 0x1F];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			if (((mask >> slot) & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			byte_pos = bit_pos >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			bit_res = bit_pos & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			instr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			for (j = 0; j < 6; ++j)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 				instr |= (uint64_t)(buf[i + j + byte_pos])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 						<< (8 * j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			norm = instr >> bit_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			if (((norm >> 37) & 0x0F) == 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 					&& ((norm >> 9) & 0x07) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 				addr = (norm >> 13) & 0x0FFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 				addr |= ((uint32_t)(norm >> 36) & 1) << 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 				addr <<= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 				addr -= s->pos + (uint32_t)i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 				addr >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 				norm &= ~((uint64_t)0x8FFFFF << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 				norm |= (uint64_t)(addr & 0x0FFFFF) << 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 				norm |= (uint64_t)(addr & 0x100000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 						<< (36 - 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 				instr &= (1 << bit_res) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 				instr |= norm << bit_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 				for (j = 0; j < 6; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 					buf[i + j + byte_pos]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 						= (uint8_t)(instr >> (8 * j));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #ifdef XZ_DEC_ARM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	uint32_t addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	for (i = 0; i + 4 <= size; i += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		if (buf[i + 3] == 0xEB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 					| ((uint32_t)buf[i + 2] << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			addr <<= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			addr -= s->pos + (uint32_t)i + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			addr >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			buf[i] = (uint8_t)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			buf[i + 1] = (uint8_t)(addr >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			buf[i + 2] = (uint8_t)(addr >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #ifdef XZ_DEC_ARMTHUMB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static size_t bcj_armthumb(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	uint32_t addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	for (i = 0; i + 4 <= size; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		if ((buf[i + 1] & 0xF8) == 0xF0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 				&& (buf[i + 3] & 0xF8) == 0xF8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 			addr = (((uint32_t)buf[i + 1] & 0x07) << 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 					| ((uint32_t)buf[i] << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 					| (((uint32_t)buf[i + 3] & 0x07) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 					| (uint32_t)buf[i + 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			addr <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			addr -= s->pos + (uint32_t)i + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			addr >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			buf[i + 1] = (uint8_t)(0xF0 | ((addr >> 19) & 0x07));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 			buf[i] = (uint8_t)(addr >> 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			buf[i + 3] = (uint8_t)(0xF8 | ((addr >> 8) & 0x07));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			buf[i + 2] = (uint8_t)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 			i += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) #ifdef XZ_DEC_SPARC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	uint32_t instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	for (i = 0; i + 4 <= size; i += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		instr = get_unaligned_be32(buf + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 			instr <<= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 			instr -= s->pos + (uint32_t)i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 			instr >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			instr = ((uint32_t)0x40000000 - (instr & 0x400000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 					| 0x40000000 | (instr & 0x3FFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			put_unaligned_be32(instr, buf + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  * Apply the selected BCJ filter. Update *pos and s->pos to match the amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)  * of data that got filtered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)  * NOTE: This is implemented as a switch statement to avoid using function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)  * pointers, which could be problematic in the kernel boot code, which must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)  * avoid pointers to static data (at least on x86).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static void bcj_apply(struct xz_dec_bcj *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		      uint8_t *buf, size_t *pos, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	size_t filtered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	buf += *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	size -= *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	switch (s->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) #ifdef XZ_DEC_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	case BCJ_X86:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		filtered = bcj_x86(s, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) #ifdef XZ_DEC_POWERPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	case BCJ_POWERPC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		filtered = bcj_powerpc(s, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) #ifdef XZ_DEC_IA64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	case BCJ_IA64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		filtered = bcj_ia64(s, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) #ifdef XZ_DEC_ARM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	case BCJ_ARM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		filtered = bcj_arm(s, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) #ifdef XZ_DEC_ARMTHUMB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	case BCJ_ARMTHUMB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		filtered = bcj_armthumb(s, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) #ifdef XZ_DEC_SPARC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	case BCJ_SPARC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		filtered = bcj_sparc(s, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		/* Never reached but silence compiler warnings. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		filtered = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	*pos += filtered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	s->pos += filtered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  * Flush pending filtered data from temp to the output buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  * Move the remaining mixture of possibly filtered and unfiltered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  * data to the beginning of temp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static void bcj_flush(struct xz_dec_bcj *s, struct xz_buf *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	size_t copy_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	copy_size = min_t(size_t, s->temp.filtered, b->out_size - b->out_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	memcpy(b->out + b->out_pos, s->temp.buf, copy_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	b->out_pos += copy_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	s->temp.filtered -= copy_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	s->temp.size -= copy_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	memmove(s->temp.buf, s->temp.buf + copy_size, s->temp.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)  * The BCJ filter functions are primitive in sense that they process the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)  * data in chunks of 1-16 bytes. To hide this issue, this function does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)  * some buffering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 				     struct xz_dec_lzma2 *lzma2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 				     struct xz_buf *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	size_t out_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	 * Flush pending already filtered data to the output buffer. Return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	 * immediatelly if we couldn't flush everything, or if the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	 * filter in the chain had already returned XZ_STREAM_END.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	if (s->temp.filtered > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		bcj_flush(s, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		if (s->temp.filtered > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			return XZ_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		if (s->ret == XZ_STREAM_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			return XZ_STREAM_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	 * If we have more output space than what is currently pending in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	 * temp, copy the unfiltered data from temp to the output buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	 * and try to fill the output buffer by decoding more data from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	 * next filter in the chain. Apply the BCJ filter on the new data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	 * in the output buffer. If everything cannot be filtered, copy it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	 * to temp and rewind the output buffer position accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	 * This needs to be always run when temp.size == 0 to handle a special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	 * case where the output buffer is full and the next filter has no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	 * more output coming but hasn't returned XZ_STREAM_END yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		out_start = b->out_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		b->out_pos += s->temp.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		s->ret = xz_dec_lzma2_run(lzma2, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		if (s->ret != XZ_STREAM_END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 				&& (s->ret != XZ_OK || s->single_call))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 			return s->ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		bcj_apply(s, b->out, &out_start, b->out_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		 * As an exception, if the next filter returned XZ_STREAM_END,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		 * we can do that too, since the last few bytes that remain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		 * unfiltered are meant to remain unfiltered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		if (s->ret == XZ_STREAM_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 			return XZ_STREAM_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		s->temp.size = b->out_pos - out_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		b->out_pos -= s->temp.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		 * If there wasn't enough input to the next filter to fill
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		 * the output buffer with unfiltered data, there's no point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		 * to try decoding more data to temp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		if (b->out_pos + s->temp.size < b->out_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			return XZ_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	 * We have unfiltered data in temp. If the output buffer isn't full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	 * yet, try to fill the temp buffer by decoding more data from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	 * next filter. Apply the BCJ filter on temp. Then we hopefully can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	 * fill the actual output buffer by copying filtered data from temp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	 * A mix of filtered and unfiltered data may be left in temp; it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	 * be taken care on the next call to this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	if (b->out_pos < b->out_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		/* Make b->out{,_pos,_size} temporarily point to s->temp. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		s->out = b->out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		s->out_pos = b->out_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		s->out_size = b->out_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		b->out = s->temp.buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		b->out_pos = s->temp.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		b->out_size = sizeof(s->temp.buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		s->ret = xz_dec_lzma2_run(lzma2, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		s->temp.size = b->out_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		b->out = s->out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		b->out_pos = s->out_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		b->out_size = s->out_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		if (s->ret != XZ_OK && s->ret != XZ_STREAM_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			return s->ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		bcj_apply(s, s->temp.buf, &s->temp.filtered, s->temp.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		 * If the next filter returned XZ_STREAM_END, we mark that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		 * everything is filtered, since the last unfiltered bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		 * of the stream are meant to be left as is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		if (s->ret == XZ_STREAM_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 			s->temp.filtered = s->temp.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		bcj_flush(s, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		if (s->temp.filtered > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 			return XZ_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	return s->ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) XZ_EXTERN struct xz_dec_bcj *xz_dec_bcj_create(bool single_call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	struct xz_dec_bcj *s = kmalloc(sizeof(*s), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	if (s != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		s->single_call = single_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	switch (id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) #ifdef XZ_DEC_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	case BCJ_X86:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) #ifdef XZ_DEC_POWERPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	case BCJ_POWERPC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) #ifdef XZ_DEC_IA64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	case BCJ_IA64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) #ifdef XZ_DEC_ARM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	case BCJ_ARM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) #ifdef XZ_DEC_ARMTHUMB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	case BCJ_ARMTHUMB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) #ifdef XZ_DEC_SPARC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	case BCJ_SPARC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		/* Unsupported Filter ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		return XZ_OPTIONS_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	s->type = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	s->ret = XZ_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	s->pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	s->x86_prev_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	s->temp.filtered = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	s->temp.size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	return XZ_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) #endif