Skip to content

Commit

Permalink
[libunwind][AArch64] Fix libunwind::Registers_arm64::jumpto
Browse files Browse the repository at this point in the history
Summary:
The AArch64 version of the libunwind function which restores the
CPU state and resumes execution is not interrupt-safe. It restores
the target value of SP before loading the floating-point registers
from the context struct, but that struct is allocated on the stack
which is being deallocated. This means that if an interrupt occurs
during this function, and uses a lot of stack space, it could
overwrite the values about to be loaded into the floating-point
registers.

This patch fixes the issue.

Patch by Oliver Stannard.

Reviewers: phosek, chill

Reviewed By: chill

Subscribers: chill, javed.absar, kristof.beyls, christof, LukeCheeseman, pbarrio, olista01, libcxx-commits

Tags: #libc

Differential Revision: https://reviews.llvm.org/D63006

llvm-svn: 363545
  • Loading branch information
miyuki committed Jun 17, 2019
1 parent 2e46312 commit d5323f6
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions libunwind/src/UnwindRegistersRestore.S
Original file line number Diff line number Diff line change
Expand Up @@ -575,16 +575,15 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)
ldp x10,x11, [x0, #0x050]
ldp x12,x13, [x0, #0x060]
ldp x14,x15, [x0, #0x070]
ldp x16,x17, [x0, #0x080]
// x16 and x17 were clobbered by the call into the unwinder, so no point in
// restoring them.
ldp x18,x19, [x0, #0x090]
ldp x20,x21, [x0, #0x0A0]
ldp x22,x23, [x0, #0x0B0]
ldp x24,x25, [x0, #0x0C0]
ldp x26,x27, [x0, #0x0D0]
ldp x28,x29, [x0, #0x0E0]
ldr x30, [x0, #0x100] // restore pc into lr
ldr x1, [x0, #0x0F8]
mov sp,x1 // restore sp

ldp d0, d1, [x0, #0x110]
ldp d2, d3, [x0, #0x120]
Expand All @@ -604,7 +603,13 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)
ldr d30, [x0, #0x200]
ldr d31, [x0, #0x208]

// Finally, restore sp. This must be done after the the last read from the
// context struct, because it is allocated on the stack, and an exception
// could clobber the de-allocated portion of the stack after sp has been
// restored.
ldr x16, [x0, #0x0F8]
ldp x0, x1, [x0, #0x000] // restore x0,x1
mov sp,x16 // restore sp
ret x30 // jump to pc

#elif defined(__arm__) && !defined(__APPLE__)
Expand Down

0 comments on commit d5323f6

Please sign in to comment.