[PATCH 0/6] Fix unwinding through sigreturn trampolines
Daniel Kiss
Daniel.Kiss at arm.com
Mon Jul 6 05:29:24 EDT 2020
Hi Ard,
I like your suggestions and tuned a bit and now it works with the LLVM’s unwinders.
Register 96 is out of the DWARF spec[1] and will collide with SVE registers[2] so 32 is better which is the reserved register for PC.
my version:
#define ARM64_SIGFRAME_REGS_OFFSET 312 /* offsetof (struct rt_sigframe, uc.uc_mcontext.regs) */
.text
.cfi_startproc
.cfi_signal_frame
.cfi_def_cfa sp, ARM64_SIGFRAME_REGS_OFFSET
.irp x, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, \
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, \
24, 25, 26, 27, 28, 29, 30, 31
.cfi_offset \x, \x * 8
.endr
.cfi_offset 32, 32 * 8 // regs->pc
.cfi_return_column 32
nop
ENTRY(__kernel_rt_sigreturn)
mov x8, #__NR_rt_sigreturn
svc #0
.cfi_endproc
ENDPROC(__kernel_rt_sigreturn)
[1] https://developer.arm.com/documentation/ihi0057/e
[2] https://developer.arm.com/documentation/100985/0000/
>
>
>> On 23 Jun 2020, at 17:43, Ard Biesheuvel <ardb at kernel.org> wrote:
>>
>> On Tue, 23 Jun 2020 at 17:34, Daniel Kiss <Daniel.Kiss at arm.com> wrote:
>>>
>>> Hi Will,
>>>
>>> The CFI is correct for PowerPC[1] and X86[2] at least; I did not check others.
>>> so LLVM’s unwinder can unwind/backtrace sigreturn without any specific hack on those architectures.
>>> The a4eb355a3fda change implements the same CFI as PowerPC and X86 have so the generic unwind logic is able to process the sigreturn.
>>
>> It most certainly did not implement the same CFI. The x86 and PowerPC
>> examples you quote have elaborate asm foo to emit the eh_frame by
>> hand.
>>
>>> IMHO the kernel change was fine.
>>>
>>
>> It creates easily reproducible segfaults in the libgcc unwinder.
>>
>>> I’m not comfortable to say the instruction sequence is the ABI that describe the unwinding information.
>>> I guess the pattern matching was implemented due to the CFI was wrong.
>>>
>>> The .cfi_signal_frame could be useful once the entry is found, but needs the right .CFI annotations at the right place.
>>>
>>> This change definitely a not good for LLVM’s unwinder.
>>>
>>
>> I agree that it would be better for the CFI to be correct, but that
>> takes a bit of work at the very least, and even then, the variable
>> nature of our sigframe may make it impossible to restore the FP/SIMD
>> register state reliably.
>>
>> I did some tests with the below CFI directives, where
>> ARM64_SIGFRAME_REGS_OFFSET is emitted by asm-offsets as the offset
>> from the top of the sigframe to the regs[] array. This fixes the
>> segfaults, and seems to do the right thing if i single step through
>> the unwinder as it unwinds the stack in response to a call to
>> pthread_cancel(). But we need a lot of testing to ensure that this is
>> correct.
>>
>>
>> .cfi_def_cfa_offset ARM64_SIGFRAME_REGS_OFFSET
>> .irp r, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, \
>> 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, \
>> 24, 25, 26, 27, 28, 29, 30, 31
>> .cfi_offset \r, \r * 8
>> .endr
>>
>> .cfi_offset 96, 32 * 8 // regs->pc
>> .cfi_return_column 96
>
More information about the linux-arm-kernel
mailing list