-static s32
-lzms_try_x86_translation(u8 *ubuf, s32 i, s32 num_op_bytes,
- s32 *closest_target_usage_p, s32 last_target_usages[],
- s32 max_trans_offset)
-{
- u16 pos;
-
- if (i - *closest_target_usage_p <= max_trans_offset) {
- LZMS_DEBUG("Performed x86 translation at position %d "
- "(opcode 0x%02x)", i, ubuf[i]);
- le32 *p32 = (le32*)&ubuf[i + num_op_bytes];
- u32 n = le32_to_cpu(*p32);
- *p32 = cpu_to_le32(n - i);
- }
-
- pos = i + le16_to_cpu(*(const le16*)&ubuf[i + num_op_bytes]);
-
- i += num_op_bytes + sizeof(le32) - 1;
-
- if (i - last_target_usages[pos] <= LZMS_X86_MAX_GOOD_TARGET_OFFSET)
- *closest_target_usage_p = i;
-
- last_target_usages[pos] = i;
-
- return i + 1;
-}
-
-static s32
-lzms_process_x86_translation(u8 *ubuf, s32 i, s32 *closest_target_usage_p,
- s32 last_target_usages[])
-{
- /* Switch on first byte of the opcode, assuming it is really an x86
- * instruction. */
- switch (ubuf[i]) {
- case 0x48:
- if (ubuf[i + 1] == 0x8b) {
- if (ubuf[i + 2] == 0x5 || ubuf[i + 2] == 0xd) {
- /* Load relative (x86_64) */
- return lzms_try_x86_translation(ubuf, i, 3,
- closest_target_usage_p,
- last_target_usages,
- LZMS_X86_MAX_TRANSLATION_OFFSET);
- }
- } else if (ubuf[i + 1] == 0x8d) {
- if ((ubuf[i + 2] & 0x7) == 0x5) {
- /* Load effective address relative (x86_64) */
- return lzms_try_x86_translation(ubuf, i, 3,
- closest_target_usage_p,
- last_target_usages,
- LZMS_X86_MAX_TRANSLATION_OFFSET);
- }
- }
- break;
-
- case 0x4c:
- if (ubuf[i + 1] == 0x8d) {
- if ((ubuf[i + 2] & 0x7) == 0x5) {
- /* Load effective address relative (x86_64) */
- return lzms_try_x86_translation(ubuf, i, 3,
- closest_target_usage_p,
- last_target_usages,
- LZMS_X86_MAX_TRANSLATION_OFFSET);
- }
- }
- break;
-
- case 0xe8:
- /* Call relative */
- return lzms_try_x86_translation(ubuf, i, 1, closest_target_usage_p,
- last_target_usages,
- LZMS_X86_MAX_TRANSLATION_OFFSET / 2);
-
- case 0xe9:
- /* Jump relative */
- return i + 5;
-
- case 0xf0:
- if (ubuf[i + 1] == 0x83 && ubuf[i + 2] == 0x05) {
- /* Lock add relative */
- return lzms_try_x86_translation(ubuf, i, 3,
- closest_target_usage_p,
- last_target_usages,
- LZMS_X86_MAX_TRANSLATION_OFFSET);
- }
- break;
-
- case 0xff:
- if (ubuf[i + 1] == 0x15) {
- /* Call indirect */
- return lzms_try_x86_translation(ubuf, i, 2,
- closest_target_usage_p,
- last_target_usages,
- LZMS_X86_MAX_TRANSLATION_OFFSET);
- }
- break;
- }
- return i + 1;
-}
-
-/* Postprocess the uncompressed data by undoing the translation of relative
- * addresses embedded in x86 instructions into absolute addresses.
- *
- * There does not appear to be any way to check to see if this postprocessing
- * actually needs to be done (or to plug in alternate filters, like in LZMA),
- * and the corresponding preprocessing seems to be done unconditionally. */
-static void
-lzms_postprocess_data(u8 *ubuf, s32 ulen)