-
-
-/* Undo the 'E8' preprocessing, where the targets of x86 CALL instructions were
- * changed from relative offsets to absolute offsets. This type of
- * preprocessing can be used on any binary data even if it is not actually
- * machine code. It seems to always be used in WIM files, even though there is
- * no bit to indicate that it actually is used, unlike in the LZX compressed
- * format as used in other file formats, where a bit is reserved for that
- * purpose. */
-static void undo_call_insn_preprocessing(u8 uncompressed_data[],
- unsigned uncompressed_data_len)
-{
- int i = 0;
- int file_size = LZX_MAGIC_FILESIZE;
- int32_t abs_offset;
- int32_t rel_offset;
-
- /* Not enabled in the last 6 bytes, which means the 5-byte call
- * instruction cannot start in the last *10* bytes. */
- while (i < uncompressed_data_len - 10) {
- if (uncompressed_data[i] != 0xe8) {
- i++;
- continue;
- }
- abs_offset = le32_to_cpu(*(int32_t*)(uncompressed_data + i + 1));
-
- if (abs_offset >= -i && abs_offset < file_size) {
- if (abs_offset >= 0) {
- /* "good translation" */
- rel_offset = abs_offset - i;
- } else {
- /* "compensating translation" */
- rel_offset = abs_offset + file_size;
- }
- *(int32_t*)(uncompressed_data + i + 1) =
- cpu_to_le32(rel_offset);
- }
- i += 5;
- }
-}
-