소스 검색

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>
Max Filippov 10 년 전
부모
커밋
382f51ae1c
1개의 변경된 파일6개의 추가작업 그리고 4개의 파일을 삭제
  1. 6 4
      libc/sysdeps/linux/xtensa/vfork.S

+ 6 - 4
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 */