@@ -430,6 +430,44 @@ PerformBaseRelocation(PMEMORYMODULE module, ptrdiff_t delta)
430430 }
431431 break ;
432432
433+ case IMAGE_REL_BASED_THUMB_MOV32 :
434+ {
435+ DWORD inst = * (DWORD * )(dest + offset );
436+ DWORD imm16 = ((inst << 1 ) & 0x0800 ) + ((inst << 12 ) & 0xf000 ) +
437+ ((inst >> 20 ) & 0x0700 ) + ((inst >> 16 ) & 0x00ff );
438+ DWORD hi_delta ;
439+
440+ if ((inst & 0x8000fbf0 ) != 0x0000f240 )
441+ fwprintf (stdout , L"wrong Thumb2 instruction %08x, expected MOVW\n" , inst );
442+
443+ imm16 += LOWORD (delta );
444+ hi_delta = HIWORD (delta ) + HIWORD (imm16 );
445+ * (DWORD * )(dest + offset ) = (inst & 0x8f00fbf0 ) + ((imm16 >> 1 ) & 0x0400 ) +
446+ ((imm16 >> 12 ) & 0x000f ) +
447+ ((imm16 << 20 ) & 0x70000000 ) +
448+ ((imm16 << 16 ) & 0xff0000 );
449+
450+ if (hi_delta != 0 )
451+ {
452+ inst = * (DWORD * )(dest + offset + 4 );
453+ imm16 = ((inst << 1 ) & 0x0800 ) + ((inst << 12 ) & 0xf000 ) +
454+ ((inst >> 20 ) & 0x0700 ) + ((inst >> 16 ) & 0x00ff );
455+
456+ if ((inst & 0x8000fbf0 ) != 0x0000f2c0 )
457+ fwprintf (stdout , L"wrong Thumb2 instruction %08x, expected MOVT\n" , inst );
458+
459+ imm16 += hi_delta ;
460+ if (imm16 > 0xffff )
461+ fwprintf (stdout , L"resulting immediate value won't fit: %08x\n" , imm16 );
462+ * (DWORD * )(dest + offset + 4 ) = (inst & 0x8f00fbf0 ) +
463+ ((imm16 >> 1 ) & 0x0400 ) +
464+ ((imm16 >> 12 ) & 0x000f ) +
465+ ((imm16 << 20 ) & 0x70000000 ) +
466+ ((imm16 << 16 ) & 0xff0000 );
467+ }
468+ }
469+ break ;
470+
433471 default :
434472 //printf("Unknown relocation: %d\n", type);
435473 break ;
0 commit comments