vdso for ia32 on amd64
Reviewed by: emaste Discussed with: jrtc27 Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 month Differential revision: https://reviews.freebsd.org/D32960
This commit is contained in:
parent
290e05dde0
commit
98c8b62524
@ -81,6 +81,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/trap.h>
|
||||
|
||||
#include "vdso_ia32_offsets.h"
|
||||
|
||||
extern const char _binary_elf_vdso32_so_1_start[];
|
||||
extern const char _binary_elf_vdso32_so_1_end[];
|
||||
extern char _binary_elf_vdso32_so_1_size;
|
||||
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
static void freebsd4_ia32_sendsig(sig_t, ksiginfo_t *, sigset_t *);
|
||||
#endif
|
||||
@ -416,7 +422,9 @@ ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
}
|
||||
|
||||
regs->tf_rsp = (uintptr_t)fp;
|
||||
regs->tf_rip = p->p_sysent->sv_psstrings - sz_ia32_osigcode;
|
||||
regs->tf_rip = p->p_sysent->sv_psstrings -
|
||||
(_binary_elf_vdso32_so_1_end - _binary_elf_vdso32_so_1_start) +
|
||||
VDSO_IA32_OSIGCODE_OFFSET;
|
||||
regs->tf_rflags &= ~(PSL_T | PSL_D);
|
||||
regs->tf_cs = _ucode32sel;
|
||||
regs->tf_ds = _udatasel;
|
||||
@ -527,8 +535,8 @@ freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
}
|
||||
|
||||
regs->tf_rsp = (uintptr_t)sfp;
|
||||
regs->tf_rip = p->p_sysent->sv_sigcode_base + sz_ia32_sigcode -
|
||||
sz_freebsd4_ia32_sigcode;
|
||||
regs->tf_rip = p->p_sysent->sv_sigcode_base +
|
||||
VDSO_FREEBSD4_IA32_SIGCODE_OFFSET - VDSO_IA32_SIGCODE_OFFSET;
|
||||
regs->tf_rflags &= ~(PSL_T | PSL_D);
|
||||
regs->tf_cs = _ucode32sel;
|
||||
regs->tf_ss = _udatasel;
|
||||
|
@ -32,14 +32,13 @@
|
||||
#include "ia32_assym.h"
|
||||
|
||||
.text
|
||||
.code32
|
||||
/*
|
||||
* Signal trampoline, copied to top of user stack
|
||||
* XXX may need to be MD to match backend sendsig handoff protocol
|
||||
* Signal trampoline, mapped as vdso into shared page, or copied to
|
||||
* top of user stack for old binaries.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
.globl ia32_sigcode
|
||||
ia32_sigcode:
|
||||
.globl __vdso_ia32_sigcode
|
||||
__vdso_ia32_sigcode:
|
||||
calll *IA32_SIGF_HANDLER(%esp)
|
||||
leal IA32_SIGF_UC(%esp),%eax /* get ucontext */
|
||||
pushl %eax
|
||||
@ -52,7 +51,8 @@ ia32_sigcode:
|
||||
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
ALIGN_TEXT
|
||||
freebsd4_ia32_sigcode:
|
||||
.globl __vdso_freebsd4_ia32_sigcode
|
||||
__vdso_freebsd4_ia32_sigcode:
|
||||
calll *IA32_SIGF_HANDLER(%esp)
|
||||
leal IA32_SIGF_UC4(%esp),%eax/* get ucontext */
|
||||
pushl %eax
|
||||
@ -66,7 +66,8 @@ freebsd4_ia32_sigcode:
|
||||
|
||||
#ifdef COMPAT_43
|
||||
ALIGN_TEXT
|
||||
ia32_osigcode:
|
||||
.globl __vdso_ia32_osigcode
|
||||
__vdso_ia32_osigcode:
|
||||
calll *IA32_SIGF_HANDLER(%esp)/* call signal handler */
|
||||
leal IA32_SIGF_SC(%esp),%eax /* get sigcontext */
|
||||
pushl %eax
|
||||
@ -90,28 +91,9 @@ ia32_osigcode:
|
||||
* vfork() and harder for other syscalls.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
lcall_tramp:
|
||||
.globl __vdso_lcall_tramp
|
||||
__vdso_lcall_tramp:
|
||||
int $0x80
|
||||
1: jmp 1b
|
||||
#endif
|
||||
|
||||
ALIGN_TEXT
|
||||
esigcode:
|
||||
|
||||
.data
|
||||
.globl sz_ia32_sigcode
|
||||
sz_ia32_sigcode:
|
||||
.long esigcode-ia32_sigcode
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
.globl sz_freebsd4_ia32_sigcode
|
||||
sz_freebsd4_ia32_sigcode:
|
||||
.long esigcode-freebsd4_ia32_sigcode
|
||||
#endif
|
||||
#ifdef COMPAT_43
|
||||
.globl sz_ia32_osigcode
|
||||
sz_ia32_osigcode:
|
||||
.long esigcode-ia32_osigcode
|
||||
.globl sz_lcall_tramp
|
||||
sz_lcall_tramp:
|
||||
.long esigcode-lcall_tramp
|
||||
#endif
|
||||
.p2align 1
|
||||
|
@ -92,6 +92,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
#include "vdso_ia32_offsets.h"
|
||||
|
||||
extern const char _binary_elf_vdso32_so_1_start[];
|
||||
extern const char _binary_elf_vdso32_so_1_end[];
|
||||
extern char _binary_elf_vdso32_so_1_size;
|
||||
|
||||
#define IDTVEC(name) __CONCAT(X,name)
|
||||
|
||||
extern inthand_t IDTVEC(int0x80_syscall), IDTVEC(int0x80_syscall_pti),
|
||||
@ -264,7 +270,9 @@ setup_lcall_gate(void)
|
||||
bzero(&uap, sizeof(uap));
|
||||
uap.start = 0;
|
||||
uap.num = 1;
|
||||
lcall_addr = curproc->p_sysent->sv_psstrings - sz_lcall_tramp;
|
||||
lcall_addr = curproc->p_sysent->sv_psstrings -
|
||||
(_binary_elf_vdso32_so_1_end - _binary_elf_vdso32_so_1_start) +
|
||||
VDSO_LCALL_TRAMP_OFFSET;
|
||||
bzero(&desc, sizeof(desc));
|
||||
desc.sd_type = SDT_MEMERA;
|
||||
desc.sd_dpl = SEL_UPL;
|
||||
|
@ -195,14 +195,6 @@ struct ia32_sigframe3 {
|
||||
|
||||
struct ksiginfo;
|
||||
struct image_params;
|
||||
extern char ia32_sigcode[];
|
||||
extern char freebsd4_ia32_sigcode[];
|
||||
extern char ia32_osigcode[];
|
||||
extern char lcall_tramp;
|
||||
extern int sz_ia32_sigcode;
|
||||
extern int sz_freebsd4_ia32_sigcode;
|
||||
extern int sz_ia32_osigcode;
|
||||
extern int sz_lcall_tramp;
|
||||
void ia32_sendsig(sig_t, struct ksiginfo *, sigset_t *);
|
||||
void ia32_setregs(struct thread *td, struct image_params *imgp,
|
||||
uintptr_t stack);
|
||||
|
@ -83,6 +83,12 @@ CTASSERT(sizeof(struct ia32_ucontext4) == 324);
|
||||
CTASSERT(sizeof(struct ia32_sigframe4) == 408);
|
||||
#endif
|
||||
|
||||
#include "vdso_ia32_offsets.h"
|
||||
|
||||
extern const char _binary_elf_vdso32_so_1_start[];
|
||||
extern const char _binary_elf_vdso32_so_1_end[];
|
||||
extern char _binary_elf_vdso32_so_1_size;
|
||||
|
||||
extern const char *freebsd32_syscallnames[];
|
||||
|
||||
static SYSCTL_NODE(_compat, OID_AUTO, ia32, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
|
||||
@ -101,8 +107,9 @@ struct sysentvec ia32_freebsd_sysvec = {
|
||||
.sv_transtrap = NULL,
|
||||
.sv_fixup = elf32_freebsd_fixup,
|
||||
.sv_sendsig = ia32_sendsig,
|
||||
.sv_sigcode = ia32_sigcode,
|
||||
.sv_szsigcode = &sz_ia32_sigcode,
|
||||
.sv_sigcode = _binary_elf_vdso32_so_1_start,
|
||||
.sv_szsigcode = (int *)&_binary_elf_vdso32_so_1_size,
|
||||
.sv_sigcodeoff = VDSO_IA32_SIGCODE_OFFSET,
|
||||
.sv_name = "FreeBSD ELF32",
|
||||
.sv_coredump = elf32_coredump,
|
||||
.sv_elf_core_osabi = ELFOSABI_FREEBSD,
|
||||
@ -121,7 +128,7 @@ struct sysentvec ia32_freebsd_sysvec = {
|
||||
.sv_fixlimit = ia32_fixlimit,
|
||||
.sv_maxssiz = &ia32_maxssiz,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_ASLR | SV_IA32 | SV_ILP32 |
|
||||
SV_SHP | SV_TIMEKEEP | SV_RNG_SEED_VER,
|
||||
SV_SHP | SV_TIMEKEEP | SV_RNG_SEED_VER | SV_DSO_SIG,
|
||||
.sv_set_syscall_retval = ia32_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = ia32_fetch_syscall_args,
|
||||
.sv_syscallnames = freebsd32_syscallnames,
|
||||
|
@ -18,6 +18,12 @@ elf-vdso.so.o standard \
|
||||
no-implicit-rule before-depend \
|
||||
clean "elf-vdso.so.o elf-vdso.so.1 vdso_offsets.h sigtramp.pico"
|
||||
#
|
||||
elf-vdso32.so.o optional compat_freebsd32 \
|
||||
dependency "$S/amd64/ia32/ia32_sigtramp.S ia32_assym.h $S/tools/amd64_ia32_vdso.sh" \
|
||||
compile-with "env AWK='${AWK}' NM='${NM}' LD='${LD}' CC='${CC}' OBJCOPY='${OBJCOPY}' S='${S}' sh $S/tools/amd64_ia32_vdso.sh" \
|
||||
no-implicit-rule before-depend \
|
||||
clean "elf-vdso32.so.o elf-vdso32.so.1 vdso_ia32_offsets.h ia32_sigtramp.pico"
|
||||
#
|
||||
ia32_genassym.o standard \
|
||||
dependency "$S/compat/ia32/ia32_genassym.c offset.inc" \
|
||||
compile-with "${CC} ${CFLAGS:N-flto:N-fno-common} -fcommon -c ${.IMPSRC}" \
|
||||
@ -368,7 +374,6 @@ kern/link_elf_obj.c standard
|
||||
#amd64/ia32/ia32_exception.S optional compat_freebsd32
|
||||
amd64/ia32/ia32_reg.c optional compat_freebsd32
|
||||
amd64/ia32/ia32_signal.c optional compat_freebsd32
|
||||
amd64/ia32/ia32_sigtramp.S optional compat_freebsd32
|
||||
amd64/ia32/ia32_syscall.c optional compat_freebsd32
|
||||
amd64/ia32/ia32_misc.c optional compat_freebsd32
|
||||
compat/ia32/ia32_sysvec.c optional compat_freebsd32
|
||||
|
94
sys/conf/vdso_amd64_ia32.ldscript
Normal file
94
sys/conf/vdso_amd64_ia32.ldscript
Normal file
@ -0,0 +1,94 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2021 The FreeBSD Foundation
|
||||
*
|
||||
* This software was developed by Konstantin Belousov <kib@FreeBSD.org>
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Linker script for ia32 (32bit) vdso on amd64.
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH(i386)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
|
||||
dynamic PT_DYNAMIC FLAGS(5);
|
||||
eh_frame_hdr PT_GNU_EH_FRAME FLAGS(5);
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = . + SIZEOF_HEADERS;
|
||||
|
||||
.hash : { *(.hash) } :text
|
||||
.gnu.hash : { *(.gnu.hash) } :text
|
||||
.dynsym : { *(.dynsym) } :text
|
||||
.dynstr : { *(.dynstr) } :text
|
||||
.gnu.version : { *(.gnu.version) } :text
|
||||
.gnu.version_d : { *(.gnu.version_d) } :text
|
||||
.gnu.version_r : { *(.gnu.version_r) } :text
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
|
||||
.eh_frame : { KEEP (*(.eh_frame)) } :text
|
||||
.dynamic : { *(.dynamic) } :text :dynamic
|
||||
.rodata : { *(.rodata*) } :text
|
||||
.data : {
|
||||
*(.got.plt) *(.got)
|
||||
} :text
|
||||
/DISCARD/ /* .data */: {
|
||||
*(.data*)
|
||||
*(.sdata*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.bss*)
|
||||
*(.dynbss*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(.ctors)
|
||||
*(.dtors)
|
||||
*(.jcr)
|
||||
*(.init_array)
|
||||
*(.init)
|
||||
*(.fini)
|
||||
*(.debug*)
|
||||
*(.comment)
|
||||
}
|
||||
|
||||
. = ALIGN(0x10);
|
||||
.text : { *(.text .text*) } :text =0x90909090
|
||||
}
|
||||
|
||||
VERSION
|
||||
{
|
||||
FBSD_1.7 {
|
||||
global:
|
||||
__vdso_ia32_sigcode;
|
||||
__vdso_freebsd4_ia32_sigcode;
|
||||
__vdso_ia32_osigcode;
|
||||
__vdso_lcall_tramp;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
}
|
@ -108,6 +108,12 @@ struct sysentvec aout_sysvec = {
|
||||
|
||||
#elif defined(__amd64__)
|
||||
|
||||
#include "vdso_ia32_offsets.h"
|
||||
|
||||
extern const char _binary_elf_vdso32_so_1_start[];
|
||||
extern const char _binary_elf_vdso32_so_1_end[];
|
||||
extern char _binary_elf_vdso32_so_1_size;
|
||||
|
||||
#define AOUT32_PS_STRINGS \
|
||||
(AOUT32_USRSTACK - sizeof(struct freebsd32_ps_strings))
|
||||
#define AOUT32_MINUSER FREEBSD32_MINUSER
|
||||
@ -115,14 +121,16 @@ struct sysentvec aout_sysvec = {
|
||||
extern const char *freebsd32_syscallnames[];
|
||||
extern u_long ia32_maxssiz;
|
||||
|
||||
static int aout_szsigcode;
|
||||
|
||||
struct sysentvec aout_sysvec = {
|
||||
.sv_size = FREEBSD32_SYS_MAXSYSCALL,
|
||||
.sv_table = freebsd32_sysent,
|
||||
.sv_transtrap = NULL,
|
||||
.sv_fixup = aout_fixup,
|
||||
.sv_sendsig = ia32_sendsig,
|
||||
.sv_sigcode = ia32_sigcode,
|
||||
.sv_szsigcode = &sz_ia32_sigcode,
|
||||
.sv_sigcode = _binary_elf_vdso32_so_1_start,
|
||||
.sv_szsigcode = &aout_szsigcode,
|
||||
.sv_name = "FreeBSD a.out",
|
||||
.sv_coredump = NULL,
|
||||
.sv_imgact_try = NULL,
|
||||
@ -144,6 +152,13 @@ struct sysentvec aout_sysvec = {
|
||||
.sv_onexit = exit_onexit,
|
||||
.sv_set_fork_retval = x86_set_fork_retval,
|
||||
};
|
||||
|
||||
static void
|
||||
aout_sysent(void *arg __unused)
|
||||
{
|
||||
aout_szsigcode = (int)(uintptr_t)&_binary_elf_vdso32_so_1_size;
|
||||
}
|
||||
SYSINIT(aout_sysent, SI_SUB_EXEC, SI_ORDER_ANY, aout_sysent, NULL);
|
||||
#else
|
||||
#error "Only ia32 arch is supported"
|
||||
#endif
|
||||
|
53
sys/tools/amd64_ia32_vdso.sh
Normal file
53
sys/tools/amd64_ia32_vdso.sh
Normal file
@ -0,0 +1,53 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
#
|
||||
# Copyright (c) 2021 The FreeBSD Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# This software was developed by Konstantin Belousov <kib@FreeBSD.org>
|
||||
# under sponsorship from the FreeBSD Foundation.
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
${CC} -x assembler-with-cpp -DLOCORE -fPIC -nostdinc -c -m32 \
|
||||
-o ia32_sigtramp.pico -I. -I"${S}" -include opt_global.h \
|
||||
"${S}"/amd64/ia32/ia32_sigtramp.S
|
||||
|
||||
${LD} --shared -Bsymbolic -soname="elf-vdso32.so.1" \
|
||||
-T "${S}"/conf/vdso_amd64_ia32.ldscript \
|
||||
--eh-frame-hdr --no-undefined -z rodynamic -z norelro -nmagic \
|
||||
--hash-style=sysv --fatal-warnings --strip-all \
|
||||
-o elf-vdso32.so.1 ia32_sigtramp.pico
|
||||
|
||||
${CC} -x assembler-with-cpp -DLOCORE -fPIC -nostdinc -c \
|
||||
-o elf-vdso32.so.o -I. -I"${S}" -include opt_global.h \
|
||||
-DVDSO_NAME=elf_vdso32_so_1 -DVDSO_FILE=elf-vdso32.so.1 \
|
||||
"${S}"/tools/vdso_wrap.S
|
||||
|
||||
${NM} -D elf-vdso32.so.1 | ${AWK} \
|
||||
'/__vdso_ia32_sigcode/{printf "#define VDSO_IA32_SIGCODE_OFFSET 0x%s\n",$1}
|
||||
/__vdso_freebsd4_ia32_sigcode/{printf "#define VDSO_FREEBSD4_IA32_SIGCODE_OFFSET 0x%s\n",$1}
|
||||
/__vdso_ia32_osigcode/{printf "#define VDSO_IA32_OSIGCODE_OFFSET 0x%s\n",$1}
|
||||
/__vdso_lcall_tramp/{printf "#define VDSO_LCALL_TRAMP_OFFSET 0x%s\n",$1}' \
|
||||
>vdso_ia32_offsets.h
|
Loading…
Reference in New Issue
Block a user