ARM EABI / Thumb vs. gdb
Johannes Stezenbach
js at sig21.net
Thu Jul 17 14:42:52 UTC 2008
Hi,
I've built an ARM EABI toolchain with uClibc compiled as
Thumb code using buildroot (BR2_TARGET_OPTIMIZATION="-Os -mthumb").
This works fine except that in gdb (6.8), if you stop your program
with some threads blocked in syscalls, gdb is unable to display
a call stack for those threads.
The reason for this is that gdb's calculation of the stack
frame size is off because of the "push {r7}" used in the syscall code.
(INTERNAL_SYSCALL in uClibc/libc/sysdeps/linux/arm/bits/syscalls.h)
Rather than fixing gdb (specifically thumb_analyze_prologue() in
arm-tdep.c), I made a local change to avoid changing the stack
pointer in INTERNAL_SYSCALL, like so:
- asm volatile ("push {r7}\n" \
- "\tmov r7, v3\n" \
- "\tswi 0 @ syscall " #name "\n" \
- "\tpop {r7}" \
+ __asm__ volatile ("push {r7}\n" \
+ "\tmov r7, v3\n" \
+ "\tpop {v3}\n" \
+ "\tswi 0 @ syscall " #name "\n" \
+ "\tmov r7, v3\n" \
But just before posting here I took a peek into the NPTL
branch and noticed that there is a better patch which avoids
the "push {r7}" altogether:
$ svn diff svn://uclibc.org/trunk/uClibc/libc/sysdeps/linux/arm/bits/syscalls.h svn://uclibc.org/branches/uClibc-nptl/libc/sysdeps/linux/arm/bits/syscalls.h
Index: syscalls.h
===================================================================
--- syscalls.h (.../trunk/uClibc/libc/sysdeps/linux/arm/bits/syscalls.h) (revision 22865)
+++ syscalls.h (.../branches/uClibc-nptl/libc/sysdeps/linux/arm/bits/syscalls.h) (revision 22865)
@@ -137,17 +137,21 @@
(int) __sys_result; })
#endif
#else /* !defined(__thumb__) */
-
+/* We can't use push/pop inside the asm because that breaks
+ unwinding (ie. thread cancellation).
+ */
#define INTERNAL_SYSCALL(name, err, nr, args...) \
({ unsigned int __sys_result; \
{ \
+ int _sys_buf[2]; \
register int _a1 __asm__ ("a1"); \
+ register int *_v3 asm ("v3") = _sys_buf; \
+ *_v3 = (int) (SYS_ify(name)); \
LOAD_ARGS_##nr (args) \
- register int _v3 __asm__ ("v3") = (int) (SYS_ify(name)); \
- __asm__ __volatile__ ("push {r7}\n" \
- "\tmov r7, v3\n" \
- "\tswi 0 @ syscall " #name "\n" \
- "\tpop {r7}" \
+ asm volatile ("str r7, [v3, #4]\n" \
+ "\tldr r7, [v3]\n" \
+ "\tswi 0 @ syscall " #name "\n" \
+ "\tldr r7, [v3, #4]" \
: "=r" (_a1) \
: "r" (_v3) ASM_ARGS_##nr \
: "memory"); \
Please consider merging this change into trunk.
Thanks,
Johannes
More information about the uClibc
mailing list