Skip to content

Commit 8849616

Browse files
H. Peter Anvinhansendc
authored andcommitted
x86/entry/vdso32: Remove open-coded DWARF in sigreturn.S
The vdso32 sigreturn.S contains open-coded DWARF bytecode, which includes a hack for gdb to not try to step back to a previous call instruction when backtracing from a signal handler. Neither of those are necessary anymore: the backtracing issue is handled by ".cfi_entry simple" and ".cfi_signal_frame", both of which have been supported for a very long time now, which allows the remaining frame to be built using regular .cfi annotations. Add a few more register offsets to the signal frame just for good measure. Replace the nop on fallthrough of the system call (which should never, ever happen) with a ud2a trap. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://patch.msgid.link/20251216212606.1325678-7-hpa@zytor.com
1 parent 98d3e99 commit 8849616

3 files changed

Lines changed: 39 additions & 114 deletions

File tree

Lines changed: 32 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,54 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22
#include <linux/linkage.h>
33
#include <asm/unistd_32.h>
4+
#include <asm/dwarf2.h>
45
#include <asm/asm-offsets.h>
56

7+
.macro STARTPROC_SIGNAL_FRAME sc
8+
CFI_STARTPROC simple
9+
CFI_SIGNAL_FRAME
10+
/* -4 as pretcode has already been popped */
11+
CFI_DEF_CFA esp, \sc - 4
12+
CFI_OFFSET eip, IA32_SIGCONTEXT_ip
13+
CFI_OFFSET eax, IA32_SIGCONTEXT_ax
14+
CFI_OFFSET ebx, IA32_SIGCONTEXT_bx
15+
CFI_OFFSET ecx, IA32_SIGCONTEXT_cx
16+
CFI_OFFSET edx, IA32_SIGCONTEXT_dx
17+
CFI_OFFSET esp, IA32_SIGCONTEXT_sp
18+
CFI_OFFSET ebp, IA32_SIGCONTEXT_bp
19+
CFI_OFFSET esi, IA32_SIGCONTEXT_si
20+
CFI_OFFSET edi, IA32_SIGCONTEXT_di
21+
CFI_OFFSET es, IA32_SIGCONTEXT_es
22+
CFI_OFFSET cs, IA32_SIGCONTEXT_cs
23+
CFI_OFFSET ss, IA32_SIGCONTEXT_ss
24+
CFI_OFFSET ds, IA32_SIGCONTEXT_ds
25+
CFI_OFFSET eflags, IA32_SIGCONTEXT_flags
26+
.endm
27+
628
.text
729
.globl __kernel_sigreturn
830
.type __kernel_sigreturn,@function
9-
nop /* this guy is needed for .LSTARTFDEDLSI1 below (watch for HACK) */
1031
ALIGN
1132
__kernel_sigreturn:
12-
.LSTART_sigreturn:
13-
popl %eax /* XXX does this mean it needs unwind info? */
33+
STARTPROC_SIGNAL_FRAME IA32_SIGFRAME_sigcontext
34+
popl %eax
35+
CFI_ADJUST_CFA_OFFSET -4
1436
movl $__NR_sigreturn, %eax
1537
int $0x80
16-
.LEND_sigreturn:
1738
SYM_INNER_LABEL(vdso32_sigreturn_landing_pad, SYM_L_GLOBAL)
18-
nop
19-
.size __kernel_sigreturn,.-.LSTART_sigreturn
39+
ud2a
40+
CFI_ENDPROC
41+
.size __kernel_sigreturn,.-__kernel_sigreturn
2042

2143
.globl __kernel_rt_sigreturn
2244
.type __kernel_rt_sigreturn,@function
2345
ALIGN
2446
__kernel_rt_sigreturn:
25-
.LSTART_rt_sigreturn:
47+
STARTPROC_SIGNAL_FRAME IA32_RT_SIGFRAME_sigcontext
2648
movl $__NR_rt_sigreturn, %eax
2749
int $0x80
28-
.LEND_rt_sigreturn:
2950
SYM_INNER_LABEL(vdso32_rt_sigreturn_landing_pad, SYM_L_GLOBAL)
30-
nop
31-
.size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
32-
.previous
33-
34-
.section .eh_frame,"a",@progbits
35-
.LSTARTFRAMEDLSI1:
36-
.long .LENDCIEDLSI1-.LSTARTCIEDLSI1
37-
.LSTARTCIEDLSI1:
38-
.long 0 /* CIE ID */
39-
.byte 1 /* Version number */
40-
.string "zRS" /* NUL-terminated augmentation string */
41-
.uleb128 1 /* Code alignment factor */
42-
.sleb128 -4 /* Data alignment factor */
43-
.byte 8 /* Return address register column */
44-
.uleb128 1 /* Augmentation value length */
45-
.byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
46-
.byte 0 /* DW_CFA_nop */
47-
.align 4
48-
.LENDCIEDLSI1:
49-
.long .LENDFDEDLSI1-.LSTARTFDEDLSI1 /* Length FDE */
50-
.LSTARTFDEDLSI1:
51-
.long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */
52-
/* HACK: The dwarf2 unwind routines will subtract 1 from the
53-
return address to get an address in the middle of the
54-
presumed call instruction. Since we didn't get here via
55-
a call, we need to include the nop before the real start
56-
to make up for it. */
57-
.long .LSTART_sigreturn-1-. /* PC-relative start address */
58-
.long .LEND_sigreturn-.LSTART_sigreturn+1
59-
.uleb128 0 /* Augmentation */
60-
/* What follows are the instructions for the table generation.
61-
We record the locations of each register saved. This is
62-
complicated by the fact that the "CFA" is always assumed to
63-
be the value of the stack pointer in the caller. This means
64-
that we must define the CFA of this body of code to be the
65-
saved value of the stack pointer in the sigcontext. Which
66-
also means that there is no fixed relation to the other
67-
saved registers, which means that we must use DW_CFA_expression
68-
to compute their addresses. It also means that when we
69-
adjust the stack with the popl, we have to do it all over again. */
70-
71-
#define do_cfa_expr(offset) \
72-
.byte 0x0f; /* DW_CFA_def_cfa_expression */ \
73-
.uleb128 1f-0f; /* length */ \
74-
0: .byte 0x74; /* DW_OP_breg4 */ \
75-
.sleb128 offset; /* offset */ \
76-
.byte 0x06; /* DW_OP_deref */ \
77-
1:
78-
79-
#define do_expr(regno, offset) \
80-
.byte 0x10; /* DW_CFA_expression */ \
81-
.uleb128 regno; /* regno */ \
82-
.uleb128 1f-0f; /* length */ \
83-
0: .byte 0x74; /* DW_OP_breg4 */ \
84-
.sleb128 offset; /* offset */ \
85-
1:
86-
87-
do_cfa_expr(IA32_SIGCONTEXT_sp+4)
88-
do_expr(0, IA32_SIGCONTEXT_ax+4)
89-
do_expr(1, IA32_SIGCONTEXT_cx+4)
90-
do_expr(2, IA32_SIGCONTEXT_dx+4)
91-
do_expr(3, IA32_SIGCONTEXT_bx+4)
92-
do_expr(5, IA32_SIGCONTEXT_bp+4)
93-
do_expr(6, IA32_SIGCONTEXT_si+4)
94-
do_expr(7, IA32_SIGCONTEXT_di+4)
95-
do_expr(8, IA32_SIGCONTEXT_ip+4)
96-
97-
.byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */
98-
99-
do_cfa_expr(IA32_SIGCONTEXT_sp)
100-
do_expr(0, IA32_SIGCONTEXT_ax)
101-
do_expr(1, IA32_SIGCONTEXT_cx)
102-
do_expr(2, IA32_SIGCONTEXT_dx)
103-
do_expr(3, IA32_SIGCONTEXT_bx)
104-
do_expr(5, IA32_SIGCONTEXT_bp)
105-
do_expr(6, IA32_SIGCONTEXT_si)
106-
do_expr(7, IA32_SIGCONTEXT_di)
107-
do_expr(8, IA32_SIGCONTEXT_ip)
108-
109-
.align 4
110-
.LENDFDEDLSI1:
111-
112-
.long .LENDFDEDLSI2-.LSTARTFDEDLSI2 /* Length FDE */
113-
.LSTARTFDEDLSI2:
114-
.long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1 /* CIE pointer */
115-
/* HACK: See above wrt unwind library assumptions. */
116-
.long .LSTART_rt_sigreturn-1-. /* PC-relative start address */
117-
.long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1
118-
.uleb128 0 /* Augmentation */
119-
/* What follows are the instructions for the table generation.
120-
We record the locations of each register saved. This is
121-
slightly less complicated than the above, since we don't
122-
modify the stack pointer in the process. */
123-
124-
do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_sp)
125-
do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ax)
126-
do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_cx)
127-
do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_dx)
128-
do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_bx)
129-
do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_bp)
130-
do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_si)
131-
do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_di)
132-
do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ip)
133-
134-
.align 4
135-
.LENDFDEDLSI2:
51+
ud2a
52+
CFI_ENDPROC
53+
.size __kernel_rt_sigreturn,.-__kernel_rt_sigreturn
13654
.previous

arch/x86/include/asm/dwarf2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define CFI_RESTORE_STATE .cfi_restore_state
2121
#define CFI_UNDEFINED .cfi_undefined
2222
#define CFI_ESCAPE .cfi_escape
23+
#define CFI_SIGNAL_FRAME .cfi_signal_frame
2324

2425
#ifndef BUILD_VDSO
2526
/*

arch/x86/kernel/asm-offsets.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,14 @@ static void __used common(void)
6363
OFFSET(IA32_SIGCONTEXT_bp, sigcontext_32, bp);
6464
OFFSET(IA32_SIGCONTEXT_sp, sigcontext_32, sp);
6565
OFFSET(IA32_SIGCONTEXT_ip, sigcontext_32, ip);
66+
OFFSET(IA32_SIGCONTEXT_es, sigcontext_32, es);
67+
OFFSET(IA32_SIGCONTEXT_cs, sigcontext_32, cs);
68+
OFFSET(IA32_SIGCONTEXT_ss, sigcontext_32, ss);
69+
OFFSET(IA32_SIGCONTEXT_ds, sigcontext_32, ds);
70+
OFFSET(IA32_SIGCONTEXT_flags, sigcontext_32, flags);
6671

6772
BLANK();
73+
OFFSET(IA32_SIGFRAME_sigcontext, sigframe_ia32, sc);
6874
OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe_ia32, uc.uc_mcontext);
6975
#endif
7076

0 commit comments

Comments
 (0)