Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
2.7 KiB

  1. /*
  2. * xlat.c
  3. *
  4. * Translate
  5. */
  6. #include "decoder.h"
  7. #include <memory.h>
  8. #pragma intrinsic(memcpy,memset)
  9. void NEAR init_decoder_translation(t_decoder_context *context)
  10. {
  11. context->dec_instr_pos = 0;
  12. }
  13. #ifdef ASM_TRANSLATE_E8
  14. ulong __cdecl asm_decoder_translate_e8(ulong instr_pos, ulong file_size, byte *mem, long bytes);
  15. void NEAR decoder_translate_e8(t_decoder_context *context, byte *mem, long bytes)
  16. {
  17. /*
  18. * We don't want the ASM code to have to worry about where in the
  19. * context structure a particular element is
  20. */
  21. context->dec_instr_pos = asm_decoder_translate_e8(
  22. context->dec_instr_pos,
  23. context->dec_current_file_size,
  24. mem,
  25. bytes
  26. );
  27. }
  28. #else /* !ASM_TRANSLATE_E8 */
  29. void NEAR decoder_translate_e8(t_decoder_context *context, byte *mem, long bytes)
  30. {
  31. ulong end_instr_pos;
  32. byte temp[6];
  33. byte *mem_backup;
  34. if (bytes <= 6)
  35. {
  36. context->dec_instr_pos += bytes;
  37. return;
  38. }
  39. mem_backup = mem;
  40. /* backup these bytes */
  41. memcpy(temp, &mem[bytes-6], 6);
  42. /* overwrite them with 0xE8 */
  43. memset(&mem[bytes-6], 0xE8, 6);
  44. end_instr_pos = context->dec_instr_pos + bytes - 6;
  45. while (1)
  46. {
  47. unsigned long absolute;
  48. /*
  49. * We are guaranteed to hit one of the 6 0xE8's we stuck at the
  50. * end of the buffer, even if we ran into some corrupted data
  51. * that resulted in our jumping over 5 bytes due to a translation
  52. */
  53. while (*mem++ != 0xE8)
  54. context->dec_instr_pos++;
  55. if (context->dec_instr_pos >= end_instr_pos)
  56. break;
  57. /*
  58. * There are 5 or more bytes in the buffer
  59. * (i.e. E8 xx xx xx xx)
  60. *
  61. * We have a complete offset available to (potentially) translate
  62. */
  63. absolute = *(UNALIGNED ulong *) mem;
  64. if (absolute < context->dec_current_file_size)
  65. {
  66. /* absolute >= 0 && absolute < dec_current_file_size */
  67. *(UNALIGNED ulong *) mem = absolute - context->dec_instr_pos;
  68. }
  69. else if ((ulong) (-(long) absolute) <= context->dec_instr_pos)
  70. {
  71. /* absolute >= -instr_pos && absolute < 0 */
  72. *(UNALIGNED ulong *) mem = absolute + context->dec_current_file_size;
  73. }
  74. mem += 4;
  75. context->dec_instr_pos += 5;
  76. }
  77. context->dec_instr_pos = end_instr_pos + 6;
  78. /* restore these bytes */
  79. memcpy(&mem_backup[bytes-6], temp, 6);
  80. }
  81. #endif