
On 08/13/2012 08:39 PM, V, Aneesh wrote:
On Mon, Aug 13, 2012 at 5:36 PM, Allen Martin amartin@nvidia.com wrote:
On Mon, Aug 13, 2012 at 04:44:05PM -0700, Stephen Warren wrote:
On 08/01/2012 02:32 PM, Allen Martin wrote:
Add function required by some thumb switch statements
diff --git a/arch/arm/lib/_thumb1_case_uqi.S b/arch/arm/lib/_thumb1_case_uqi.S
- .force_thumb
I believe that line should be removed.
The issue here is that when gcc emits Thumb code to call this function, it actually emits:
108af8: f000 f94a bl 108d90 <____gnu_thumb1_case_uqi_from_thumb>
which is implemented as:
00108d90 <____gnu_thumb1_case_uqi_from_thumb>: 108d90: 4778 bx pc 108d92: 46c0 nop ; (mov r8, r8) 108d94: eafffde1 b 108520 <__gnu_thumb1_case_uqi>
i.e. it switches to ARM mode then jumps to that function. Hence, __gnu_thumb1_case_uqi must be compiled as ARM, not as Thumb.
The function is supposed to be thumb code, it's basically a thumb optimization of a switch statement, and in the ARM case the compiler just emits the code directly instead of calling into libgcc. So it doesn't really make sense for the function to be anything but thumb.
I think the real problem is the linker incorrectly thought the code was ARM so it generated a thumb to ARM interworking veneer.
Can you try adding a ".type __gnu_thumb1_case_uqi STT_FUNC" instead? I've seen cases where the assembler generates the wrong type of symbol without some explicit guidance which messes up the linker's interworking generator. This might be one of those.
Yes, not having STT_FUNC or %function is troublesome. I have faced this before.
Maybe you should wrap the assembly functions with standard ENTRY, END_PROC macros from linkage.h. This will take care of STT_FUNC
Yes. In fact patch 7/9 of this series is doing exactly that for some other assembly function.
So, the patch below fixes this problem; I see the function being called directly without any compiler-synthesized "from_thumb" stub/trampoline being used.
diff --git a/arch/arm/lib/_thumb1_case_uqi.S b/arch/arm/lib/_thumb1_case_uqi.S index e4bb194..a4241f6 100644 --- a/arch/arm/lib/_thumb1_case_uqi.S +++ b/arch/arm/lib/_thumb1_case_uqi.S @@ -25,10 +25,11 @@ along with this program; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+#include <linux/linkage.h>
.force_thumb .syntax unified
.globl __gnu_thumb1_case_uqi
-__gnu_thumb1_case_uqi: +ENTRY(__gnu_thumb1_case_uqi) push {r1} mov r1, lr lsrs r1, r1, #1 @@ -38,4 +39,4 @@ __gnu_thumb1_case_uqi: add lr, lr, r1 pop {r1} bx lr
+ENDPROC(__gnu_thumb1_case_uqi)