我正面临一个奇怪的问题,有点类似于this。我有一个Windows Phone 8原生DLL项目,主要是C++,但是在其中有一个ARM汇编源代码。源处于ARM模式(即不是Thumb)。 C++被编译为Thumb。WinPhone8支持ARM(非Thumb)吗?
当C++试图调用汇编程序时,应用程序崩溃。反汇编中的调用命令是BLX,具有立即偏移量 - 它应该无条件地将模式切换回ARM,但不知何故它不会。
我有例外的细节。异常代码是0xc000001d(无效操作),崩溃上下文结构中的PC值是0x696d5985。这在任何一种模式中都是不可能的 - 它没有对齐,零位就是一个。 BLX指令执行1b f0 0c eb
- 如果您解密了,那么这是一个由两部分组成的Thumb式BLX,它具有4对齐的位移。崩溃上下文中的T标志是SET(CPSR = 0x60000010)。
我没有设备,但测试版测试人员的崩溃日志非常确凿。在调用汇编之前,我有一个调试日志记录。然后崩溃。
编辑:related。然而,他们声称汇编器本身(armasm
)将ARM转换为Thumb。对我来说情况并非如此 - 至少不是静态的。该DLL包含适当的ARM代码,如汇编源(CODE32
)中所指定。
编辑:有一个稍微不同的跳跃序列的尝试:
ldr r12, target
and r12, r12, #0xfffffffe ; To be sure
bx r12 ;BX to a register with a cleared 0th bit. Doesn't get any more explicit than that.
相同的结果。看起来存在一些奇怪的代码变形发生在商店某处,或者操作系统本身捕获模式开关并阻止它们。
通过将可执行文件的一部分与其他崩溃数据一起转储到崩溃日志中,可能会检测到代码变体。但是,如何处理操作系统干扰,将转换为整个代码转换为Thumb?它不仅仅是重新编译。
编辑dwelch:在编译的C代码的调用序列是这样的:
.text:1000A35E MOV R2, #g_Host ;Three parameters
.text:1000A366 MOV R1, R5
.text:1000A368 MOV R0, R6
.text:1000A36A BLX Func ; Code bytes 1B F0 0C EB
BLX到立即地址来切换模式。这不是有条件的,如bx register
。通话对象是一个thunk:
.text:10025984 B Func_Impl
和碰撞吸能地址是这个的thunk加一:5985.
这是一个编译的DLL的拆卸,但我不能保证,这正是所执行在设备上。在链接的MSDN线程的用户称,他们期待在调试器拆卸,看到拇指其中ARM应该去过。微软,IIRC,拥有一项专利,用于修改应用程序代码,从发布者到设备途径;这可能是原因。
在构建库和应用程序时是否启用了所有必需的交互工作标志? –
没有任何。 BLX命令表明工具链知道发生了什么。 –
hmmmmm ....必须有我们不知道的东西。诚然,Thumb指令过去是非常有限的,但Thumb2是一种不同的动物,甚至比ARM模式更有效。我认为现在是时候转储ARM模式并转换到Thumb2模式的编码。 –