libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libunwind-devel] [PATCH 20/27] ARM: fix non-signal-frame local unw_resu


From: Tommi Rantala
Subject: [Libunwind-devel] [PATCH 20/27] ARM: fix non-signal-frame local unw_resume() due to compiler optimization cleverness
Date: Wed, 22 Aug 2012 14:28:46 +0300

When cross-compiling libunwind with optimizations (-O1 or higher),
gcc-4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) optimizes away the memory
writes prior to the inline asm() statement in arm_local_resume() in the
non-signal-frame path, causing the `regs' array to be only allocated on
the stack, but not populated. This means that we are restoring garbage
to the registers.

As suggested in the GCC docs, add a fixed size input memory constraint
for the array content. This is enough to get the desired code to be
generated.

Adding __builtin_unreachable() to the point that we should never reach
was also in itself enough to inhibit the optimization. It also reduces
the function size by a few instructions.
---
 src/arm/Gresume.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/arm/Gresume.c b/src/arm/Gresume.c
index da45dec..4100d87 100644
--- a/src/arm/Gresume.c
+++ b/src/arm/Gresume.c
@@ -1,6 +1,7 @@
 /* libunwind - a platform-independent unwind library
    Copyright (C) 2008 CodeSourcery
    Copyright 2011 Linaro Limited
+   Copyright (C) 2012 Tommi Rantala <address@hidden>
 
 This file is part of libunwind.
 
@@ -51,11 +52,16 @@ arm_local_resume (unw_addr_space_t as, unw_cursor_t 
*cursor, void *arg)
       regs[8] = uc->regs[13]; /* SP */
       regs[9] = uc->regs[14]; /* LR */
 
+      struct regs_overlay {
+             char x[sizeof(regs)];
+      };
+
       asm __volatile__ (
        "ldmia %0, {r4-r12, lr}\n"
        "mov sp, r12\n"
        "bx lr\n"
-       : : "r" (regs)
+       : : "r" (regs),
+           "m" (*(struct regs_overlay *)regs)
       );
     }
   else
@@ -90,6 +96,7 @@ arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, 
void *arg)
        : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc)
       );
    }
+  __builtin_unreachable();
 #else
   printf ("%s: implement me\n", __FUNCTION__);
 #endif
-- 
1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]