diff mbox

[nios2,committed] Fix stdlib/tst-makecontext regression for Nios II

Message ID 05c99014-2aac-3202-b8d8-784cf1246f15@codesourcery.com
State New
Headers show

Commit Message

Chung-Lin Tang April 25, 2016, 7:19 a.m. UTC
This patch fixes the backtrace infinite loop regression for the stdlib/tst-makecontext testcase
that happened for a number of targets, Nios II included. Most archs fixed this by a combination
of removing FDEs and/or launching the makecontext wrapped function from the trampoline,
but this one is slightly different.

Basically FDE lookup does not use exactly the return address, but rather (return_address - 1).
This causes the use of ra == &__start_context (beginning of function), to actually lookup the FDE
of the prior __setcontext instead. Since the CFIs in __setcontext has nothing to
alter/restore/undefine RA, it just keeps spinning at that FDE until the testcase backtrace
callback's counter is up, and asserts fail.

So this regression can be fixed by simply adding an NOP before __startcontext, which allows
the FDE lookup to just fail and return NULL there, and close the backtrace.

Tested and committed.

2016-04-25  Chung-Lin Tang  <cltang@codesourcery.com>

        * sysdeps/unix/sysv/linux/nios2/setcontext.S (__startcontext):
        Add nop before __startcontext, add explaining comments.
diff mbox

Patch

diff --git a/sysdeps/unix/sysv/linux/nios2/setcontext.S b/sysdeps/unix/sysv/linux/nios2/setcontext.S
index f10e8ff..177aa4b 100644
--- a/sysdeps/unix/sysv/linux/nios2/setcontext.S
+++ b/sysdeps/unix/sysv/linux/nios2/setcontext.S
@@ -85,6 +85,18 @@  ENTRY(__setcontext)
 PSEUDO_END (__setcontext)
 weak_alias (__setcontext, setcontext)
 
+	/* We add an NOP here to separate between __setcontext/__startcontext.
+	   The wanted behavior that happens is: when unwinding from a function
+	   called inside a makecontext() context, FDE lookup will use
+	   '&__startcontext - 1', then returns NULL for no FDE found,
+	   and immediately ends the unwind, in a normal fashion.
+
+	   If this NOP word does not exist, FDE lookup just repeatedly finds
+	   __setcontext's FDE in an infinite loop, due to the convention of
+	   using 'address - 1' for FDE lookup. Modifiying/deleting the below
+	   __startcontext's FDE has no help on this.  */
+	nop
+
 ENTRY(__startcontext)
 	mov	r4, r16
 	bne	r4, zero, __setcontext