Thumb和ARM指令不能切换问题(error:unsupported interworking call (Thumb -> ARM))

Posted 代二毛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Thumb和ARM指令不能切换问题(error:unsupported interworking call (Thumb -> ARM))相关的知识,希望对你有一定的参考价值。

1、报错现象

xxx.ko:ection 3 reloc 4 sym 'xxxxxx': unsupported interworking call (Thumb -> ARM)

2、报错原因和分析

报错信息的翻译:程序不支持代码交织,thumb态切换arm态失败。首先要知道ARM架构的CPU分ARM态和Thumb态,执行ARM指令的时候是ARM态,执行Thumb指令的时候是Thumb态;ARM架构的CPU是支持ARM指令集和Thumb指令集的,在编译系统内核的时候可以通过编译参数指定编译成ARM指令集还是Thumb指令集。假设内核是按ARM指令集编译,引用的某个驱动ko文件是按Thumb指令集编译,就会出现上面的报错。
总结:报错的原因就是两个库编译时候采用的指令集不同。

3、解决步骤

3.1、确定当前编译采用的指令集

在编译选项中,"-marm"是指定编译成ARM指令集,"-mthumb"是指定编译成Thumb指令集;
(1)如果你有源码,直接去查看编译脚本确定;
(2)如果你只有编译好的库文件,比如.a文件获取.ko文件,尝试用文本编辑软件(natepad++)去打开,在里面查找上面的两个编译选项;

3.2解决方法

解决的思路总体上就是让两个库的指令集兼容:
(1)先确定两个库编译时候采用的指令集;
(2)方案一:两个库采用同样的指令集,在编译选项里采用同样的编译参数,都用"-marm"或者"-mthumb";
(3)方案二:两个库还是采用不同的指令集,但是要额外加上编译参数"-mthumb-interwork",支持代码交织;

3.3、注意事项

上面提到的两种方案都涉及修改当前库编译采用的指令集,修改采用的指令集是有影响的,不同指令集的优缺点是不同的,根据需求来选择。修改完之后测试一下性能,不要看到没有错误打印就觉得这个问题已经解决,修改指令集有可能会导致性能的下降。

4、arm指令集、thumb指令集、thumb2指令集

(1)arm指令集:速度快,占更多空间。每条指令都是 32bit 的,每条指令能承载更多的信息,因此使用最少的指令完成功能, 所以在相同频率下运行速度也是最快的, 但也因为每条指令是32bit 的而占用了最多的程序空间。
(2)thumb指令集:速度相对慢,省空间。每条指令都是16bit 的,每条指令所能承载的信息少,因此它需要使用更多的指令才能完成功能, 因此运行速度慢, 但它也占用了最少的程序空间。
(3)thumb2指令集:arm指令集和thumb指令集的折中,指令集中既有16bit的指令也有32bit的指令。

5、代码交织

编译选项:-mthumb-interwork
所谓代码交织就是生成的目标文件中不同的部分采用了不同的指令集去编译,一部分是arm指令集一部分是thumb指令集。默认情况下,编译选项是-mno-thumb-interwork,是不支持代码交织的,目标文件不能正常运行。要想目标文件支持代码交织只需要在每部分编译的时候加上编译选项:-mthumb-interwork,在使用了-mthumb-interwork参数后,生成的代码大小将略微增大,执行效率降低,这就是为什么不默认支持代码交织。

以上是关于Thumb和ARM指令不能切换问题(error:unsupported interworking call (Thumb -> ARM))的主要内容,如果未能解决你的问题,请参考以下文章

ida Pro ARM指令集和Thumb指令集的切换

Thumb指令集与ARM指令集的差别

ARM的编程模式

arm函数内部进行模式切换的技巧

ARM指令和THUMB指令有啥区别

ARM指令集Thumb指令集Thumb-2指令集