aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2021-11-15 18:29:45 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2021-12-06 18:47:17 +0000
commit5b8918fac6fa9c150f68a0ec0805385ee7029ec3 (patch)
treec6210bec4d6d378a21c1703a1f899c1e49295bbc
parenteb029587481e8d6f610eb31d7f50d34b9240f2f2 (diff)
downloadsrc-5b8918fac6fa9c150f68a0ec0805385ee7029ec3.tar.gz
src-5b8918fac6fa9c150f68a0ec0805385ee7029ec3.zip
amd64 native vdso: add unwind annotations to the signal trampoline
Reviewed by: emaste Discussed with: jhb, jrtc27 Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 month Differential revision: https://reviews.freebsd.org/D32960
-rw-r--r--sys/amd64/amd64/genassym.c27
-rw-r--r--sys/amd64/amd64/sigtramp.S50
-rw-r--r--sys/tools/amd64_vdso.sh2
3 files changed, 78 insertions, 1 deletions
diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c
index 7c29368828d0..f61ce120d156 100644
--- a/sys/amd64/amd64/genassym.c
+++ b/sys/amd64/amd64/genassym.c
@@ -205,6 +205,33 @@ ASSYM(PTI_SIZE, sizeof(struct pti_frame));
ASSYM(SIGF_HANDLER, offsetof(struct sigframe, sf_ahu.sf_handler));
ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
ASSYM(UC_EFLAGS, offsetof(ucontext_t, uc_mcontext.mc_rflags));
+ASSYM(UC_RDI, offsetof(ucontext_t, uc_mcontext.mc_rdi));
+ASSYM(UC_RSI, offsetof(ucontext_t, uc_mcontext.mc_rsi));
+ASSYM(UC_RDX, offsetof(ucontext_t, uc_mcontext.mc_rdx));
+ASSYM(UC_RCX, offsetof(ucontext_t, uc_mcontext.mc_rcx));
+ASSYM(UC_R8, offsetof(ucontext_t, uc_mcontext.mc_r8));
+ASSYM(UC_R9, offsetof(ucontext_t, uc_mcontext.mc_r9));
+ASSYM(UC_RAX, offsetof(ucontext_t, uc_mcontext.mc_rax));
+ASSYM(UC_RBX, offsetof(ucontext_t, uc_mcontext.mc_rbx));
+ASSYM(UC_RBP, offsetof(ucontext_t, uc_mcontext.mc_rbp));
+ASSYM(UC_R10, offsetof(ucontext_t, uc_mcontext.mc_r10));
+ASSYM(UC_R11, offsetof(ucontext_t, uc_mcontext.mc_r11));
+ASSYM(UC_R12, offsetof(ucontext_t, uc_mcontext.mc_r12));
+ASSYM(UC_R13, offsetof(ucontext_t, uc_mcontext.mc_r13));
+ASSYM(UC_R14, offsetof(ucontext_t, uc_mcontext.mc_r14));
+ASSYM(UC_R15, offsetof(ucontext_t, uc_mcontext.mc_r15));
+ASSYM(UC_FS, offsetof(ucontext_t, uc_mcontext.mc_fs));
+ASSYM(UC_GS, offsetof(ucontext_t, uc_mcontext.mc_gs));
+ASSYM(UC_ES, offsetof(ucontext_t, uc_mcontext.mc_es));
+ASSYM(UC_DS, offsetof(ucontext_t, uc_mcontext.mc_ds));
+ASSYM(UC_RIP, offsetof(ucontext_t, uc_mcontext.mc_rip));
+ASSYM(UC_CS, offsetof(ucontext_t, uc_mcontext.mc_cs));
+ASSYM(UC_RFLAGS, offsetof(ucontext_t, uc_mcontext.mc_rflags));
+ASSYM(UC_RSP, offsetof(ucontext_t, uc_mcontext.mc_rsp));
+ASSYM(UC_SS, offsetof(ucontext_t, uc_mcontext.mc_ss));
+ASSYM(UC_FSBASE, offsetof(ucontext_t, uc_mcontext.mc_fsbase));
+ASSYM(UC_GSBASE, offsetof(ucontext_t, uc_mcontext.mc_gsbase));
+
ASSYM(ENOENT, ENOENT);
ASSYM(EFAULT, EFAULT);
ASSYM(ENAMETOOLONG, ENAMETOOLONG);
diff --git a/sys/amd64/amd64/sigtramp.S b/sys/amd64/amd64/sigtramp.S
index 05bf30293a9a..6c2895a14a0a 100644
--- a/sys/amd64/amd64/sigtramp.S
+++ b/sys/amd64/amd64/sigtramp.S
@@ -2,6 +2,11 @@
* Copyright (c) 2003 Peter Wemm <peter@freeBSD.org>
* All rights reserved.
*
+ * Copyright (c) 2021 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * 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:
@@ -36,13 +41,58 @@
* Signal trampoline, mapped as vdso into shared page.
*/
ENTRY(__vdso_sigcode)
+ .cfi_startproc
+ .cfi_signal_frame
+ .cfi_def_cfa %rsp, 0
+ .cfi_offset %rdi, SIGF_UC + UC_RDI
+ .cfi_offset %rsi, SIGF_UC + UC_RSI
+ .cfi_offset %rdx, SIGF_UC + UC_RDX
+ .cfi_offset %rcx, SIGF_UC + UC_RCX
+ .cfi_offset %r8, SIGF_UC + UC_R8
+ .cfi_offset %r9, SIGF_UC + UC_R9
+ .cfi_offset %rax, SIGF_UC + UC_RAX
+ .cfi_offset %rbx, SIGF_UC + UC_RBX
+ .cfi_offset %rbp, SIGF_UC + UC_RBP
+ .cfi_offset %r10, SIGF_UC + UC_R10
+ .cfi_offset %r11, SIGF_UC + UC_R11
+ .cfi_offset %r12, SIGF_UC + UC_R12
+ .cfi_offset %r13, SIGF_UC + UC_R13
+ .cfi_offset %r14, SIGF_UC + UC_R14
+ .cfi_offset %r15, SIGF_UC + UC_R15
+#if 0
+/*
+ * Gnu as complains about %fs/%gs/%es/%ds registers offsets not being
+ * multiple of 8, but gas + ld.bfd work for %cs/%ss.
+ *
+ * Clang IAS + ld.lld combination cannot handle any of the segment
+ * registers. Also, clang IAS does not know %rflags/%fs.base/%gs.base
+ * registers names, use dwarf registers numbers from psABI directly.
+ */
+ .cfi_offset %fs, SIGF_UC + UC_FS
+ .cfi_offset %gs, SIGF_UC + UC_GS
+ .cfi_offset %es, SIGF_UC + UC_ES
+ .cfi_offset %ds, SIGF_UC + UC_DS
+#endif
+ .cfi_offset %rip, SIGF_UC + UC_RIP
+#if 0
+ .cfi_offset %cs, SIGF_UC + UC_CS
+#endif
+ .cfi_offset 49 /* %rflags */, SIGF_UC + UC_RFLAGS
+ .cfi_offset %rsp, SIGF_UC + UC_RSP
+#if 0
+ .cfi_offset %ss, SIGF_UC + UC_SS
+#endif
+ .cfi_offset 58 /* %fs.base */, SIGF_UC + UC_FSBASE
+ .cfi_offset 59 /* %gs.base */, SIGF_UC + UC_GSBASE
call *SIGF_HANDLER(%rsp) /* call signal handler */
lea SIGF_UC(%rsp),%rdi /* get ucontext_t */
pushq $0 /* junk to fake return addr. */
+ .cfi_def_cfa %rsp, 8
movq $SYS_sigreturn,%rax
syscall /* enter kernel with args */
0: hlt /* trap priviliged instruction */
jmp 0b
+ .cfi_endproc
END(__vdso_sigcode)
.section .note.GNU-stack,"",%progbits
diff --git a/sys/tools/amd64_vdso.sh b/sys/tools/amd64_vdso.sh
index 39406eccd2ef..6a4111ffabc8 100644
--- a/sys/tools/amd64_vdso.sh
+++ b/sys/tools/amd64_vdso.sh
@@ -55,5 +55,5 @@ ${CC} -x assembler-with-cpp -DLOCORE -fPIC -nostdinc -c \
"${S}"/tools/vdso_wrap.S
${NM} -D elf-vdso.so.1 | \
- awk '/__vdso_sigcode/{printf "#define VDSO_SIGCODE_OFFSET 0x%s\n",$1}' \
+ ${AWK} '/__vdso_sigcode/{printf "#define VDSO_SIGCODE_OFFSET 0x%s\n",$1}' \
>vdso_offsets.h