2N/A * GRUB -- GRand Unified Bootloader 2N/A * Copyright (C) 2010 Free Software Foundation, Inc. 2N/A * GRUB is free software: you can redistribute it and/or modify 2N/A * it under the terms of the GNU General Public License as published by 2N/A * the Free Software Foundation, either version 3 of the License, or 2N/A * (at your option) any later version. 2N/A * GRUB is distributed in the hope that it will be useful, 2N/A * but WITHOUT ANY WARRANTY; without even the implied warranty of 2N/A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2N/A * GNU General Public License for more details. 2N/A * You should have received a copy of the GNU General Public License 2N/A * This file is based on code from XZ embedded project 2N/A /* Type of the BCJ filter being used */ 2N/A * Return value of the next filter in the chain. We need to preserve 2N/A * this information across calls, because we must not call the next 2N/A * filter anymore once it has returned XZ_STREAM_END. 2N/A /* True if we are operating in single-call mode. */ 2N/A * Absolute position relative to the beginning of the uncompressed 2N/A * data (in a single .xz Block). We care only about the lowest 32 2N/A * bits so this doesn't need to be uint64_t even with big files. 2N/A /* x86 filter state */ 2N/A /* Temporary space to hold the variables from struct xz_buf */ 2N/A /* Amount of already filtered data in the beginning of buf */ 2N/A /* Total amount of data currently stored in buf */ 2N/A * Buffer to hold a mix of filtered and unfiltered data. This 2N/A * needs to be big enough to hold Alignment + 2 * Look-ahead: 2N/A * Type Alignment Look-ahead 2N/A * This is macro used to test the most significant byte of a memory address 2N/A * in an x86 instruction. 2N/A = {
true,
true,
true,
false,
true,
false,
false,
false };
2N/A for (i = 0; i +
4 <=
size; i +=
4) {
2N/A if ((
instr &
0xFC000003) ==
0x48000001) {
2N/A 0, 0, 0, 0, 0, 0, 0, 0,
2N/A 0, 0, 0, 0, 0, 0, 0, 0,
2N/A 4,
4,
6,
6, 0, 0,
7,
7,
2N/A 4,
4, 0, 0,
4,
4, 0, 0
2N/A * The local variables take a little bit stack space, but it's less 2N/A * than what LZMA2 decoder takes, so it doesn't make sense to reduce 2N/A * stack usage here without doing that for the LZMA2 decoder too. 2N/A /* Instruction slot (0, 1, or 2) in the 128-bit instruction word */ 2N/A /* Bitwise offset of the instruction indicated by slot */ 2N/A /* bit_pos split into byte and bit parts */ 2N/A /* Address part of an instruction */ 2N/A /* Mask used to detect which instructions to convert */ 2N/A /* 41-bit instruction stored somewhere in the lowest 48 bits */ 2N/A /* Instruction normalized with bit_res for easier manipulation */ 2N/A for (i = 0; i +
16 <=
size; i +=
16) {
2N/A for (j = 0; j <
6; ++j)
2N/A for (j = 0; j <
6; j++)
2N/A for (i = 0; i +
4 <=
size; i +=
4) {
2N/A for (i = 0; i +
4 <=
size; i +=
2) {
2N/A if ((
buf[i +
1] &
0xF8) ==
0xF0 2N/A && (
buf[i +
3] &
0xF8) ==
0xF8) {
2N/A for (i = 0; i +
4 <=
size; i +=
4) {
2N/A * Apply the selected BCJ filter. Update *pos and s->pos to match the amount 2N/A * of data that got filtered. 2N/A * NOTE: This is implemented as a switch statement to avoid using function 2N/A * pointers, which could be problematic in the kernel boot code, which must 2N/A * avoid pointers to static data (at least on x86). 2N/A /* Never reached but silence compiler warnings. */ 2N/A * Flush pending filtered data from temp to the output buffer. 2N/A * Move the remaining mixture of possibly filtered and unfiltered 2N/A * data to the beginning of temp. 2N/A * The BCJ filter functions are primitive in sense that they process the 2N/A * data in chunks of 1-16 bytes. To hide this issue, this function does 2N/A * Flush pending already filtered data to the output buffer. Return 2N/A * immediatelly if we couldn't flush everything, or if the next 2N/A * filter in the chain had already returned XZ_STREAM_END. 2N/A * If we have more output space than what is currently pending in 2N/A * temp, copy the unfiltered data from temp to the output buffer 2N/A * and try to fill the output buffer by decoding more data from the 2N/A * next filter in the chain. Apply the BCJ filter on the new data 2N/A * in the output buffer. If everything cannot be filtered, copy it 2N/A * to temp and rewind the output buffer position accordingly. 2N/A * As an exception, if the next filter returned XZ_STREAM_END, 2N/A * we can do that too, since the last few bytes that remain 2N/A * unfiltered are meant to remain unfiltered. 2N/A * If we have unfiltered data in temp, try to fill by decoding more 2N/A * data from the next filter. Apply the BCJ filter on temp. Then we 2N/A * hopefully can fill the actual output buffer by copying filtered 2N/A * data from temp. A mix of filtered and unfiltered data may be left 2N/A * in temp; it will be taken care on the next call to this function. 2N/A /* Make b->out{,_pos,_size} temporarily point to s->temp. */ 2N/A * If the next filter returned XZ_STREAM_END, we mark that 2N/A * everything is filtered, since the last unfiltered bytes 2N/A * of the stream are meant to be left as is. 2N/A /* Unsupported Filter ID */