diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2015-12-29 03:13:13 +0300 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2015-12-29 11:59:47 +0100 |
commit | 382f51ae1cafb977d7a17b9aee62e098396886f3 (patch) | |
tree | 7e3fa03bd5cc5d63bab024c26da6381972f67746 | |
parent | 0ad73077c230093ae004829da44418597f330c6a (diff) |
xtensa: fix vfork return address calculations
vfork internally unwinds stack up one frame, saving the original return
address in the a3 of the unwound frame. To do this in windowed ABI it
needs to exchange two topmost bits of the original return address and of
the helper entry point. Current code doesn't do it correctly for
addresses above 0x40000000, resulting in illegal instruction exception
for configurations that put code high, e.g. for noMMU.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
-rw-r--r-- | libc/sysdeps/linux/xtensa/vfork.S | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/libc/sysdeps/linux/xtensa/vfork.S b/libc/sysdeps/linux/xtensa/vfork.S index b8db5c1a1..8058fb057 100644 --- a/libc/sysdeps/linux/xtensa/vfork.S +++ b/libc/sysdeps/linux/xtensa/vfork.S @@ -59,11 +59,13 @@ HIDDEN_ENTRY (__vfork) movi a0, .Ljumptable extui a2, a3, 30, 2 # call-size: call4/8/12 = 1/2/3 addx4 a0, a2, a0 # find return address in jumptable - slli a2, a2, 30 l32i a0, a0, 0 - - xor a3, a3, a2 # remove call-size from return address - or a0, a0, a2 # create temporary return address + # exchange top 2 bits of a0 and a3: + xor a2, a0, a3 + extui a2, a2, 30, 2 + slli a2, a2, 30 + xor a0, a0, a2 + xor a3, a3, a2 retw /* a7: return address */ |