-static void undo_call_insn_translation(u32 *call_insn_target, int input_pos,
- int32_t file_size)
-{
- int32_t abs_offset;
- int32_t rel_offset;
-
- abs_offset = le32_to_cpu(*call_insn_target);
- if (abs_offset >= -input_pos && abs_offset < file_size) {
- if (abs_offset >= 0) {
- /* "good translation" */
- rel_offset = abs_offset - input_pos;
- } else {
- /* "compensating translation" */
- rel_offset = abs_offset + file_size;
- }
- *call_insn_target = cpu_to_le32(rel_offset);
- }
-}
-
-/* Undo the 'E8' preprocessing, where the targets of x86 CALL instructions were
- * changed from relative offsets to absolute offsets.
- *
- * Note that this call instruction preprocessing can and will be used on any
- * data even if it is not actually x86 machine code. In fact, this type of
- * preprocessing appears to always be used in LZX-compressed resources in WIM
- * files; there is no bit to indicate whether it is used or not, unlike in the
- * LZX compressed format as used in cabinet files, where a bit is reserved for
- * that purpose.
- *
- * Call instruction preprocessing is disabled in the last 6 bytes of the
- * uncompressed data, which really means the 5-byte call instruction cannot
- * start in the last 10 bytes of the uncompressed data. This is one of the
- * errors in the LZX documentation.
- *
- * Call instruction preprocessing does not appear to be disabled after the
- * 32768th chunk of a WIM stream, which is apparently is yet another difference
- * from the LZX compression used in cabinet files.
- *
- * Call instruction processing is supposed to take the file size as a parameter,
- * as it is used in calculating the translated jump targets. But in WIM files,
- * this file size is always the same (LZX_WIM_MAGIC_FILESIZE == 12000000).*/
-static void undo_call_insn_preprocessing(u8 uncompressed_data[],
- int uncompressed_data_len)
-{
- for (int i = 0; i < uncompressed_data_len - 10; i++) {
- if (uncompressed_data[i] == 0xe8) {
- undo_call_insn_translation((u32*)&uncompressed_data[i + 1],
- i,
- LZX_WIM_MAGIC_FILESIZE);
- i += 4;
- }
- }
-}
-