git: 8f9635dc99f5 - main - linux(4): Retire handmade DWARF annotations from signal trampolines
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 15 May 2022 18:12:27 UTC
The branch main has been updated by dchagin: URL: https://cgit.FreeBSD.org/src/commit/?id=8f9635dc99f571a0ae4e613b9a0439e68da7b160 commit 8f9635dc99f571a0ae4e613b9a0439e68da7b160 Author: Dmitry Chagin <dchagin@FreeBSD.org> AuthorDate: 2022-05-15 18:08:12 +0000 Commit: Dmitry Chagin <dchagin@FreeBSD.org> CommitDate: 2022-05-15 18:08:12 +0000 linux(4): Retire handmade DWARF annotations from signal trampolines The Linux exports __kernel_sigreturn and __kernel_rt_sigreturn from the vdso. Modern glibc's sigaction sets the sa_restorer field of sigaction to the corresponding vdso __sigreturn, and sets the SA_RESTORER. Our signal trampolines uses the FreeBSD-way to call a signal handler, so does not use the sigaction's sa_restorer. However, as glibc's runtime linker depends on the existment of the vdso __sigreturn symbols, for all Linuxulators was added separate trampolines named __sigcode with DWARF anotations and left separate __sigreturn methods, which are exported. MFC after: 2 weeks --- sys/amd64/linux/linux_genassym.c | 20 ++++- sys/amd64/linux/linux_locore.asm | 92 ++++++++++++-------- sys/amd64/linux32/linux32_genassym.c | 17 +++- sys/amd64/linux32/linux32_locore.asm | 161 ++++++++++++++++------------------- sys/amd64/linux32/linux32_sysvec.c | 8 +- sys/amd64/linux32/linux32_vdso.lds.s | 2 + sys/i386/linux/linux_genassym.c | 19 ++++- sys/i386/linux/linux_locore.asm | 160 +++++++++++++++------------------- sys/i386/linux/linux_sysvec.c | 8 +- sys/i386/linux/linux_vdso.lds.s | 2 + 10 files changed, 259 insertions(+), 230 deletions(-) diff --git a/sys/amd64/linux/linux_genassym.c b/sys/amd64/linux/linux_genassym.c index a9658b006be8..14880afcc89b 100644 --- a/sys/amd64/linux/linux_genassym.c +++ b/sys/amd64/linux/linux_genassym.c @@ -12,5 +12,23 @@ __FBSDID("$FreeBSD$"); ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_uc)); ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext)); +ASSYM(L_SC_R8, offsetof(struct l_sigcontext, sc_r8)); +ASSYM(L_SC_R9, offsetof(struct l_sigcontext, sc_r9)); +ASSYM(L_SC_R10, offsetof(struct l_sigcontext, sc_r10)); +ASSYM(L_SC_R11, offsetof(struct l_sigcontext, sc_r11)); +ASSYM(L_SC_R12, offsetof(struct l_sigcontext, sc_r12)); +ASSYM(L_SC_R13, offsetof(struct l_sigcontext, sc_r13)); +ASSYM(L_SC_R14, offsetof(struct l_sigcontext, sc_r14)); +ASSYM(L_SC_R15, offsetof(struct l_sigcontext, sc_r15)); +ASSYM(L_SC_RDI, offsetof(struct l_sigcontext, sc_rdi)); +ASSYM(L_SC_RSI, offsetof(struct l_sigcontext, sc_rsi)); +ASSYM(L_SC_RBP, offsetof(struct l_sigcontext, sc_rbp)); +ASSYM(L_SC_RBX, offsetof(struct l_sigcontext, sc_rbx)); +ASSYM(L_SC_RDX, offsetof(struct l_sigcontext, sc_rdx)); +ASSYM(L_SC_RAX, offsetof(struct l_sigcontext, sc_rax)); +ASSYM(L_SC_RCX, offsetof(struct l_sigcontext, sc_rcx)); +ASSYM(L_SC_RSP, offsetof(struct l_sigcontext, sc_rsp)); +ASSYM(L_SC_RIP, offsetof(struct l_sigcontext, sc_rip)); +ASSYM(L_SC_RFLAGS, offsetof(struct l_sigcontext, sc_rflags)); +ASSYM(L_SC_CS, offsetof(struct l_sigcontext, sc_cs)); ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE); -ASSYM(LINUX_SC_RSP, offsetof(struct l_sigcontext, sc_rsp)); diff --git a/sys/amd64/linux/linux_locore.asm b/sys/amd64/linux/linux_locore.asm index 8b6833d7352f..f26996980007 100644 --- a/sys/amd64/linux/linux_locore.asm +++ b/sys/amd64/linux/linux_locore.asm @@ -1,4 +1,31 @@ -/* $FreeBSD$ */ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015-2022 Dmitry Chagin <dchagin@freeBSD.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ #include "linux_assym.h" /* system definitions */ #include <machine/asmacros.h> /* miscellaneous asm macros */ @@ -14,15 +41,37 @@ linux_platform: .text ENTRY(linux_rt_sigcode) + .cfi_startproc + .cfi_signal_frame + .cfi_def_cfa %rsp, LINUX_RT_SIGF_SC + .cfi_offset %r8, L_SC_R8 + .cfi_offset %r9, L_SC_R9 + .cfi_offset %r10, L_SC_R10 + .cfi_offset %r11, L_SC_R11 + .cfi_offset %r12, L_SC_R12 + .cfi_offset %r13, L_SC_R13 + .cfi_offset %r14, L_SC_R14 + .cfi_offset %r15, L_SC_R15 + .cfi_offset %rdi, L_SC_RDI + .cfi_offset %rsi, L_SC_RSI + .cfi_offset %rbp, L_SC_RBP + .cfi_offset %rbx, L_SC_RBX + .cfi_offset %rdx, L_SC_RDX + .cfi_offset %rax, L_SC_RAX + .cfi_offset %rcx, L_SC_RCX + .cfi_offset %rip, L_SC_RIP + .cfi_offset 49, L_SC_RFLAGS + .cfi_offset %cs, L_SC_CS + .cfi_offset %rsp, L_SC_RSP + movq %rsp, %rbx /* rt_sigframe for rt_sigreturn */ call *%rcx /* call signal handler */ -.startrtsigcode: movq $LINUX_SYS_linux_rt_sigreturn, %rax syscall - hlt -.endrtsigcode: -0: jmp 0b - +0: hlt + jmp 0b + .cfi_endproc +END(linux_rt_sigcode) #if 0 .section .note.Linux, "a",@note @@ -40,34 +89,3 @@ ENTRY(linux_rt_sigcode) .balign 4 .previous #endif - - .section .eh_frame,"a",@progbits -.LSTARTFRAMEDLSI0: - .long .LENDCIEDLSI0-.LSTARTCIEDLSI0 -.LSTARTCIEDLSI0: - .long 0 /* CIE ID */ - .byte 1 /* Version number */ - .string "zR" /* NULL-terminated - * augmentation string - */ - .uleb128 1 /* Code alignment factor */ - .sleb128 -4 /* Data alignment factor */ - .byte 8 /* Return address register column */ - .uleb128 1 /* Augmentation value length */ - .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ - .byte 0x0c /* DW_CFA_def_cfa */ - .uleb128 4 - .uleb128 4 - .byte 0x88 /* DW_CFA_offset, column 0x8 */ - .uleb128 1 - .align 4 -.LENDCIEDLSI0: - .long .LENDFDEDLSI0-.LSTARTFDEDLSI0 /* Length FDE */ -.LSTARTFDEDLSI0: - .long .LSTARTFDEDLSI0-.LSTARTFRAMEDLSI0 /* CIE pointer */ - .long .startrtsigcode-. /* PC-relative start address */ - .long .endrtsigcode-.startrtsigcode - .uleb128 0 - .align 4 -.LENDFDEDLSI0: - .previous diff --git a/sys/amd64/linux32/linux32_genassym.c b/sys/amd64/linux32/linux32_genassym.c index 1465863dd08c..4a87b5a423bc 100644 --- a/sys/amd64/linux32/linux32_genassym.c +++ b/sys/amd64/linux32/linux32_genassym.c @@ -14,5 +14,20 @@ __FBSDID("$FreeBSD$"); ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc)); ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_uc)); ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext)); +ASSYM(L_SC_GS, offsetof(struct l_sigcontext, sc_gs)); +ASSYM(L_SC_FS, offsetof(struct l_sigcontext, sc_fs)); +ASSYM(L_SC_ES, offsetof(struct l_sigcontext, sc_es)); +ASSYM(L_SC_DS, offsetof(struct l_sigcontext, sc_ds)); +ASSYM(L_SC_CS, offsetof(struct l_sigcontext, sc_cs)); +ASSYM(L_SC_SS, offsetof(struct l_sigcontext, sc_ss)); +ASSYM(L_SC_EFLAGS, offsetof(struct l_sigcontext, sc_eflags)); +ASSYM(L_SC_EDI, offsetof(struct l_sigcontext, sc_edi)); +ASSYM(L_SC_ESI, offsetof(struct l_sigcontext, sc_esi)); +ASSYM(L_SC_EBP, offsetof(struct l_sigcontext, sc_ebp)); +ASSYM(L_SC_EBX, offsetof(struct l_sigcontext, sc_ebx)); +ASSYM(L_SC_EDX, offsetof(struct l_sigcontext, sc_edx)); +ASSYM(L_SC_ECX, offsetof(struct l_sigcontext, sc_ecx)); +ASSYM(L_SC_EAX, offsetof(struct l_sigcontext, sc_eax)); +ASSYM(L_SC_EIP, offsetof(struct l_sigcontext, sc_eip)); +ASSYM(L_SC_ESP, offsetof(struct l_sigcontext, sc_esp_at_signal)); ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE); -ASSYM(LINUX_SC_ESP, offsetof(struct l_sigcontext, sc_esp)); diff --git a/sys/amd64/linux32/linux32_locore.asm b/sys/amd64/linux32/linux32_locore.asm index e0409969ee3b..f4cdc5fc1559 100644 --- a/sys/amd64/linux32/linux32_locore.asm +++ b/sys/amd64/linux32/linux32_locore.asm @@ -14,30 +14,96 @@ linux_platform: .text .code32 +ENTRY(linux32_vdso_sigcode) + .cfi_startproc + .cfi_signal_frame + .cfi_def_cfa %esp, LINUX_SIGF_SC + .cfi_offset %gs, L_SC_GS + .cfi_offset %fs, L_SC_FS + .cfi_offset %es, L_SC_ES + .cfi_offset %ds, L_SC_DS + .cfi_offset %cs, L_SC_CS + .cfi_offset %ss, L_SC_SS + .cfi_offset %flags, L_SC_EFLAGS + .cfi_offset %edi, L_SC_EDI + .cfi_offset %esi, L_SC_ESI + .cfi_offset %ebp, L_SC_EBP + .cfi_offset %ebx, L_SC_EBX + .cfi_offset %edx, L_SC_EDX + .cfi_offset %ecx, L_SC_ECX + .cfi_offset %eax, L_SC_EAX + .cfi_offset %eip, L_SC_EIP + .cfi_offset %esp, L_SC_ESP + + movl %esp, %ebx /* sigframe for sigreturn */ + call *%edi /* call signal handler */ + popl %eax /* gcc unwind code need this */ + .cfi_def_cfa %esp, LINUX_SIGF_SC-4 + movl $LINUX32_SYS_linux_sigreturn, %eax + int $0x80 +0: jmp 0b + .cfi_endproc +END(linux32_vdso_sigcode) + + +ENTRY(linux32_vdso_rt_sigcode) + .cfi_startproc + .cfi_signal_frame + .cfi_def_cfa %esp, LINUX_RT_SIGF_UC + LINUX_RT_SIGF_SC + .cfi_offset %gs, L_SC_GS + .cfi_offset %fs, L_SC_FS + .cfi_offset %es, L_SC_ES + .cfi_offset %ds, L_SC_DS + .cfi_offset %cs, L_SC_CS + .cfi_offset %ss, L_SC_SS + .cfi_offset %flags, L_SC_EFLAGS + .cfi_offset %edi, L_SC_EDI + .cfi_offset %esi, L_SC_ESI + .cfi_offset %ebp, L_SC_EBP + .cfi_offset %ebx, L_SC_EBX + .cfi_offset %edx, L_SC_EDX + .cfi_offset %ecx, L_SC_ECX + .cfi_offset %eax, L_SC_EAX + .cfi_offset %eip, L_SC_EIP + .cfi_offset %esp, L_SC_ESP + + leal LINUX_RT_SIGF_UC(%esp), %ebx /* linux ucontext for rt_sigreturn */ + call *%edi /* call signal handler */ + movl $LINUX32_SYS_linux_rt_sigreturn, %eax + int $0x80 +0: jmp 0b + .cfi_endproc +END(linux32_vdso_rt_sigcode) + ENTRY(__kernel_sigreturn) + .cfi_startproc + .cfi_signal_frame movl %esp, %ebx /* sigframe for sigreturn */ call *%edi /* call signal handler */ -.startsigcode: popl %eax /* gcc unwind code need this */ movl $LINUX32_SYS_linux_sigreturn, %eax int $0x80 -.endsigcode: 0: jmp 0b + .cfi_endproc +END(__kernel_sigreturn) ENTRY(__kernel_rt_sigreturn) + .cfi_startproc + .cfi_signal_frame leal LINUX_RT_SIGF_UC(%esp), %ebx /* linux ucontext for rt_sigreturn */ call *%edi /* call signal handler */ -.startrtsigcode: movl $LINUX32_SYS_linux_rt_sigreturn, %eax int $0x80 -.endrtsigcode: 0: jmp 0b + .cfi_endproc +END(__kernel_rt_sigreturn) ENTRY(__kernel_vsyscall) -.startvsyscall: + .cfi_startproc int $0x80 ret -.endvsyscall: + .cfi_endproc +END(__kernel_vsyscall) #if 0 .section .note.Linux, "a",@note @@ -55,86 +121,3 @@ ENTRY(__kernel_vsyscall) .balign 4 .previous #endif - -#define do_cfa_expr(offset) \ - .byte 0x0f; /* DW_CFA_def_cfa_expression */ \ - .uleb128 11f-10f; /* length */ \ -10: .byte 0x74; /* DW_OP_breg4 */ \ - .sleb128 offset; /* offset */ \ - .byte 0x06; /* DW_OP_deref */ \ -11: - - - /* CIE */ - .section .eh_frame,"a",@progbits -.LSTARTFRAMEDLSI1: - .long .LENDCIEDLSI1-.LSTARTCIEDLSI1 -.LSTARTCIEDLSI1: - .long 0 /* CIE ID */ - .byte 1 /* Version number */ - .string "zRS" /* NULL-terminated - * augmentation string - */ - .uleb128 1 /* Code alignment factor */ - .sleb128 -4 /* Data alignment factor */ - .byte 8 /* Return address - * register column - */ - .uleb128 1 /* Augmentation value length */ - .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ - .byte 0 /* DW_CFA_nop */ - .align 4 -.LENDCIEDLSI1: - - /* FDE */ - .long .LENDFDEDLSI1-.LSTARTFDEDLSI1 /* Length FDE */ -.LSTARTFDEDLSI1: - .long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */ - .long .startsigcode-. /* PC-relative start address */ - .long .endsigcode-.startsigcode - .uleb128 0 /* Augmentation */ - do_cfa_expr(LINUX_SIGF_SC-8) - .align 4 -.LENDFDEDLSI1: - - .long .LENDFDEDLSI2-.LSTARTFDEDLSI2 /* Length FDE */ -.LSTARTFDEDLSI2: - .long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1 /* CIE pointer */ - .long .startrtsigcode-. /* PC-relative start address */ - .long .endrtsigcode-.startrtsigcode - .uleb128 0 /* Augmentation */ - do_cfa_expr(LINUX_RT_SIGF_SC-4+LINUX_SC_ESP) - .align 4 -.LENDFDEDLSI2: - .previous - - .section .eh_frame,"a",@progbits -.LSTARTFRAMEDLSI2: - .long .LENDCIEDLSI2-.LSTARTCIEDLSI2 -.LSTARTCIEDLSI2: - .long 0 /* CIE ID */ - .byte 1 /* Version number */ - .string "zR" /* NULL-terminated - * augmentation string - */ - .uleb128 1 /* Code alignment factor */ - .sleb128 -4 /* Data alignment factor */ - .byte 8 /* Return address register column */ - .uleb128 1 /* Augmentation value length */ - .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ - .byte 0x0c /* DW_CFA_def_cfa */ - .uleb128 4 - .uleb128 4 - .byte 0x88 /* DW_CFA_offset, column 0x8 */ - .uleb128 1 - .align 4 -.LENDCIEDLSI2: - .long .LENDFDEDLSI3-.LSTARTFDEDLSI3 /* Length FDE */ -.LSTARTFDEDLSI3: - .long .LSTARTFDEDLSI3-.LSTARTFRAMEDLSI2 /* CIE pointer */ - .long .startvsyscall-. /* PC-relative start address */ - .long .endvsyscall-.startvsyscall - .uleb128 0 - .align 4 -.LENDFDEDLSI3: - .previous diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index 729c000cc628..79409fc63828 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -183,8 +183,8 @@ struct linux32_ps_strings { sizeof(struct linux32_ps_strings)) LINUX_VDSO_SYM_INTPTR(__kernel_vsyscall); -LINUX_VDSO_SYM_INTPTR(__kernel_sigreturn); -LINUX_VDSO_SYM_INTPTR(__kernel_rt_sigreturn); +LINUX_VDSO_SYM_INTPTR(linux32_vdso_sigcode); +LINUX_VDSO_SYM_INTPTR(linux32_vdso_rt_sigcode); LINUX_VDSO_SYM_INTPTR(kern_timekeep_base); LINUX_VDSO_SYM_INTPTR(kern_tsc_selector); LINUX_VDSO_SYM_INTPTR(kern_cpu_selector); @@ -367,7 +367,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* Build context to run handler in. */ regs->tf_rsp = PTROUT(fp); - regs->tf_rip = __kernel_rt_sigreturn; + regs->tf_rip = linux32_vdso_rt_sigcode; regs->tf_rdi = PTROUT(catcher); regs->tf_rflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucode32sel; @@ -473,7 +473,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* Build context to run handler in. */ regs->tf_rsp = PTROUT(fp); - regs->tf_rip = __kernel_sigreturn; + regs->tf_rip = linux32_vdso_sigcode; regs->tf_rdi = PTROUT(catcher); regs->tf_rflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucode32sel; diff --git a/sys/amd64/linux32/linux32_vdso.lds.s b/sys/amd64/linux32/linux32_vdso.lds.s index cd5b4a20dee0..6b47a120847e 100644 --- a/sys/amd64/linux32/linux32_vdso.lds.s +++ b/sys/amd64/linux32/linux32_vdso.lds.s @@ -77,6 +77,8 @@ VERSION kern_timekeep_base; kern_tsc_selector; kern_cpu_selector; + linux32_vdso_sigcode; + linux32_vdso_rt_sigcode; local: *; }; } diff --git a/sys/i386/linux/linux_genassym.c b/sys/i386/linux/linux_genassym.c index 65757a51a190..a775a2525d4c 100644 --- a/sys/i386/linux/linux_genassym.c +++ b/sys/i386/linux/linux_genassym.c @@ -11,9 +11,22 @@ __FBSDID("$FreeBSD$"); #include <x86/linux/linux_x86_sigframe.h> ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc)); -ASSYM(LINUX_SC_GS, offsetof(struct l_sigcontext, sc_gs)); -ASSYM(LINUX_SC_EFLAGS, offsetof(struct l_sigcontext, sc_eflags)); ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_uc)); ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext)); -ASSYM(LINUX_SC_ESP, offsetof(struct l_sigcontext, sc_esp)); +ASSYM(L_SC_GS, offsetof(struct l_sigcontext, sc_gs)); +ASSYM(L_SC_FS, offsetof(struct l_sigcontext, sc_fs)); +ASSYM(L_SC_ES, offsetof(struct l_sigcontext, sc_es)); +ASSYM(L_SC_DS, offsetof(struct l_sigcontext, sc_ds)); +ASSYM(L_SC_CS, offsetof(struct l_sigcontext, sc_cs)); +ASSYM(L_SC_SS, offsetof(struct l_sigcontext, sc_ss)); +ASSYM(L_SC_EFLAGS, offsetof(struct l_sigcontext, sc_eflags)); +ASSYM(L_SC_EDI, offsetof(struct l_sigcontext, sc_edi)); +ASSYM(L_SC_ESI, offsetof(struct l_sigcontext, sc_esi)); +ASSYM(L_SC_EBP, offsetof(struct l_sigcontext, sc_ebp)); +ASSYM(L_SC_EBX, offsetof(struct l_sigcontext, sc_ebx)); +ASSYM(L_SC_EDX, offsetof(struct l_sigcontext, sc_edx)); +ASSYM(L_SC_ECX, offsetof(struct l_sigcontext, sc_ecx)); +ASSYM(L_SC_EAX, offsetof(struct l_sigcontext, sc_eax)); +ASSYM(L_SC_EIP, offsetof(struct l_sigcontext, sc_eip)); +ASSYM(L_SC_ESP, offsetof(struct l_sigcontext, sc_esp_at_signal)); ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE); diff --git a/sys/i386/linux/linux_locore.asm b/sys/i386/linux/linux_locore.asm index 3459fb5a56de..6b3cf01a8edc 100644 --- a/sys/i386/linux/linux_locore.asm +++ b/sys/i386/linux/linux_locore.asm @@ -15,30 +15,91 @@ linux_platform: .text -ENTRY(__kernel_sigreturn) +ENTRY(linux_vdso_sigcode) + .cfi_startproc + .cfi_signal_frame + .cfi_def_cfa %esp, LINUX_SIGF_SC + .cfi_offset %gs, L_SC_GS + .cfi_offset %fs, L_SC_FS + .cfi_offset %es, L_SC_ES + .cfi_offset %ds, L_SC_DS + .cfi_offset %cs, L_SC_CS + .cfi_offset %ss, L_SC_SS + .cfi_offset %flags, L_SC_EFLAGS + .cfi_offset %edi, L_SC_EDI + .cfi_offset %esi, L_SC_ESI + .cfi_offset %ebp, L_SC_EBP + .cfi_offset %ebx, L_SC_EBX + .cfi_offset %edx, L_SC_EDX + .cfi_offset %ecx, L_SC_ECX + .cfi_offset %eax, L_SC_EAX + .cfi_offset %eip, L_SC_EIP + .cfi_offset %esp, L_SC_ESP + movl %esp, %ebx /* sigframe for sigreturn */ call *%edi /* call signal handler */ -.startsigcode: popl %eax /* gcc unwind code need this */ + .cfi_def_cfa %esp, LINUX_SIGF_SC-4 movl $LINUX_SYS_linux_sigreturn, %eax int $0x80 -.endsigcode: 0: jmp 0b + .cfi_endproc +END(linux_vdso_sigcode) + +ENTRY(linux_vdso_rt_sigcode) + .cfi_startproc + .cfi_signal_frame + .cfi_def_cfa %esp, LINUX_RT_SIGF_UC + LINUX_RT_SIGF_SC + .cfi_offset %gs, L_SC_GS + .cfi_offset %fs, L_SC_FS + .cfi_offset %es, L_SC_ES + .cfi_offset %ds, L_SC_DS + .cfi_offset %cs, L_SC_CS + .cfi_offset %ss, L_SC_SS + .cfi_offset %flags, L_SC_EFLAGS + .cfi_offset %edi, L_SC_EDI + .cfi_offset %esi, L_SC_ESI + .cfi_offset %ebp, L_SC_EBP + .cfi_offset %ebx, L_SC_EBX + .cfi_offset %edx, L_SC_EDX + .cfi_offset %ecx, L_SC_ECX + .cfi_offset %eax, L_SC_EAX + .cfi_offset %eip, L_SC_EIP + .cfi_offset %esp, L_SC_ESP -ENTRY(__kernel_rt_sigreturn) leal LINUX_RT_SIGF_UC(%esp), %ebx /* linux ucontext for rt_sigreturn */ call *%edi /* call signal handler */ -.startrtsigcode: movl $LINUX_SYS_linux_rt_sigreturn, %eax int $0x80 -.endrtsigcode: 0: jmp 0b + .cfi_endproc +END(linux_vdso_rt_sigcode) + +ENTRY(__kernel_sigreturn) + .cfi_startproc + .cfi_signal_frame + popl %eax /* gcc unwind code need this */ + movl $LINUX_SYS_linux_sigreturn, %eax + int $0x80 +0: jmp 0b + .cfi_endproc +END(__kernel_sigreturn) + +ENTRY(__kernel_rt_sigreturn) + .cfi_startproc + .cfi_signal_frame + movl $LINUX_SYS_linux_rt_sigreturn, %eax + int $0x80 +0: jmp 0b + .cfi_endproc +END(__kernel_rt_sigreturn) ENTRY(__kernel_vsyscall) -.startvsyscall: + .cfi_startproc int $0x80 ret -.endvsyscall: + .cfi_endproc +END(__kernel_vsyscall) #if 0 .section .note.Linux, "a",@note @@ -56,86 +117,3 @@ ENTRY(__kernel_vsyscall) .balign 4 .previous #endif - -#define do_cfa_expr(offset) \ - .byte 0x0f; /* DW_CFA_def_cfa_expression */ \ - .uleb128 11f-10f; /* length */ \ -10: .byte 0x74; /* DW_OP_breg4 */ \ - .sleb128 offset; /* offset */ \ - .byte 0x06; /* DW_OP_deref */ \ -11: - - - /* CIE */ - .section .eh_frame,"a",@progbits -.LSTARTFRAMEDLSI1: - .long .LENDCIEDLSI1-.LSTARTCIEDLSI1 -.LSTARTCIEDLSI1: - .long 0 /* CIE ID */ - .byte 1 /* Version number */ - .string "zRS" /* NULL-terminated - * augmentation string - */ - .uleb128 1 /* Code alignment factor */ - .sleb128 -4 /* Data alignment factor */ - .byte 8 /* Return address - * register column - */ - .uleb128 1 /* Augmentation value length */ - .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ - .byte 0 /* DW_CFA_nop */ - .align 4 -.LENDCIEDLSI1: - - /* FDE */ - .long .LENDFDEDLSI1-.LSTARTFDEDLSI1 /* Length FDE */ -.LSTARTFDEDLSI1: - .long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */ - .long .startsigcode-. /* PC-relative start address */ - .long .endsigcode-.startsigcode - .uleb128 0 /* Augmentation */ - do_cfa_expr(LINUX_SIGF_SC-8) - .align 4 -.LENDFDEDLSI1: - - .long .LENDFDEDLSI2-.LSTARTFDEDLSI2 /* Length FDE */ -.LSTARTFDEDLSI2: - .long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1 /* CIE pointer */ - .long .startrtsigcode-. /* PC-relative start address */ - .long .endrtsigcode-.startrtsigcode - .uleb128 0 /* Augmentation */ - do_cfa_expr(LINUX_RT_SIGF_SC-4+LINUX_SC_ESP) - .align 4 -.LENDFDEDLSI2: - .previous - - .section .eh_frame,"a",@progbits -.LSTARTFRAMEDLSI2: - .long .LENDCIEDLSI2-.LSTARTCIEDLSI2 -.LSTARTCIEDLSI2: - .long 0 /* CIE ID */ - .byte 1 /* Version number */ - .string "zR" /* NULL-terminated - * augmentation string - */ - .uleb128 1 /* Code alignment factor */ - .sleb128 -4 /* Data alignment factor */ - .byte 8 /* Return address register column */ - .uleb128 1 /* Augmentation value length */ - .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ - .byte 0x0c /* DW_CFA_def_cfa */ - .uleb128 4 - .uleb128 4 - .byte 0x88 /* DW_CFA_offset, column 0x8 */ - .uleb128 1 - .align 4 -.LENDCIEDLSI2: - .long .LENDFDEDLSI3-.LSTARTFDEDLSI3 /* Length FDE */ -.LSTARTFDEDLSI3: - .long .LSTARTFDEDLSI3-.LSTARTFRAMEDLSI2 /* CIE pointer */ - .long .startvsyscall-. /* PC-relative start address */ - .long .endvsyscall-.startvsyscall - .uleb128 0 - .align 4 -.LENDFDEDLSI3: - .previous diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index ab53ccbf6bb1..a4d1980fd33e 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -158,8 +158,8 @@ static int _bsd_to_linux_trapcode[] = { LINUX_VDSO_SYM_CHAR(linux_platform); LINUX_VDSO_SYM_INTPTR(__kernel_vsyscall); -LINUX_VDSO_SYM_INTPTR(__kernel_sigreturn); -LINUX_VDSO_SYM_INTPTR(__kernel_rt_sigreturn); +LINUX_VDSO_SYM_INTPTR(linux_vdso_sigcode); +LINUX_VDSO_SYM_INTPTR(linux_vdso_rt_sigcode); LINUX_VDSO_SYM_INTPTR(kern_timekeep_base); LINUX_VDSO_SYM_INTPTR(kern_tsc_selector); LINUX_VDSO_SYM_INTPTR(kern_cpu_selector); @@ -473,7 +473,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* Build context to run handler in. */ regs->tf_esp = PTROUT(fp); - regs->tf_eip = __kernel_rt_sigreturn; + regs->tf_eip = linux_vdso_rt_sigcode; regs->tf_edi = PTROUT(catcher); regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); regs->tf_cs = _ucodesel; @@ -574,7 +574,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* Build context to run handler in. */ regs->tf_esp = PTROUT(fp); - regs->tf_eip = __kernel_sigreturn; + regs->tf_eip = linux_vdso_sigcode; regs->tf_edi = PTROUT(catcher); regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); regs->tf_cs = _ucodesel; diff --git a/sys/i386/linux/linux_vdso.lds.s b/sys/i386/linux/linux_vdso.lds.s index cd5b4a20dee0..818685800d83 100644 --- a/sys/i386/linux/linux_vdso.lds.s +++ b/sys/i386/linux/linux_vdso.lds.s @@ -77,6 +77,8 @@ VERSION kern_timekeep_base; kern_tsc_selector; kern_cpu_selector; + linux_vdso_sigcode; + linux_vdso_rt_sigcode; local: *; }; }