Skip to content

Commit

Permalink
#silifuzz Make x86 GPR offsets in ucontext_offsets.h relative to GReg…
Browse files Browse the repository at this point in the history
…Set.

This will make splitting of GRegSet from UContext easier.

PiperOrigin-RevId: 616181742
  • Loading branch information
dougkwan authored and copybara-github committed Mar 15, 2024
1 parent 9ae7f8d commit 36757d5
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 194 deletions.
67 changes: 34 additions & 33 deletions third_party/silifuzz_libunwind/restore_ucontext_body.inc
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
pushq %rbp
movq %rsp, %rbp

/* Save ucontext (%RDI) ptr in %R15 to allow later code use %RDI for
syscalls without the need to push/pop every time. */
mov %rdi, %r15
/* Load GRegSet and FPRegSet pointers into callee save registers so that
they are preserved across calls and syscalls below. These will be restored
at the exit of this function */
leaq UCONTEXT_FPREGS_OFFSET(%rdi), %r14
leaq UCONTEXT_GREGS_OFFSET(%rdi), %r15

/*
if (HasAVX512Registers()) {
Expand All @@ -57,21 +59,20 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */

/* Restore fp state. */
vzeroupper
leaq UCONTEXT_FPREGS_OFFSET(%r15), %r8
fxrstor64 (%r8) /* Value of r8 must be 16-aligned.
UContext type ensures that. */

movw UCONTEXT_GREGS_ES_OFFSET(%r15), %es
movw UCONTEXT_GREGS_DS_OFFSET(%r15), %ds
movw UCONTEXT_GREGS_FS_OFFSET(%r15), %fs
movw UCONTEXT_GREGS_GS_OFFSET(%r15), %gs
fxrstor64 (%r14) /* Value of r14 must be 16-aligned.
UContext type ensures that. */

movw GREGS_ES_OFFSET(%r15), %es
movw GREGS_DS_OFFSET(%r15), %ds
movw GREGS_FS_OFFSET(%r15), %fs
movw GREGS_GS_OFFSET(%r15), %gs
/* We do not restore CS and SS - see comments for SaveUContext()
and RestoreUContext() in ucontext.h. */
/* Changing %ss is fraught with danger
(https://www.felixcloutier.com/x86/mov#operation)
movw UCONTEXT_GREGS_SS_OFFSET(%r15), %ss */
movw GREGS_SS_OFFSET(%r15), %ss */
/* %cs cannot be changed with a MOV (causes #UD) https://stackoverflow.com/questions/57314216
movw UCONTEXT_GREGS_SS_OFFSET(%r15), %cs */
movw GREGS_SS_OFFSET(%r15), %cs */

/* Skip this if we are not allowed to make syscalls */
#if !defined(UCONTEXT_NO_SYSCALLS)
Expand All @@ -83,42 +84,42 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
later. */
mov $__NR_arch_prctl, %rax
mov $ARCH_SET_FS, %rdi
movq UCONTEXT_GREGS_FS_BASE_OFFSET(%r15), %rsi
movq GREGS_FS_BASE_OFFSET(%r15), %rsi
syscall
mov $__NR_arch_prctl, %rax
mov $ARCH_SET_GS, %rdi
movq UCONTEXT_GREGS_GS_BASE_OFFSET(%r15), %rsi
movq GREGS_GS_BASE_OFFSET(%r15), %rsi
syscall
#endif /* UCONTEXT_NO_SYSCALLS */

/* Restore bulk of the registers. */
movq UCONTEXT_GREGS_R8_OFFSET(%r15),%r8
movq UCONTEXT_GREGS_R9_OFFSET(%r15),%r9
movq UCONTEXT_GREGS_R10_OFFSET(%r15),%r10
movq UCONTEXT_GREGS_R11_OFFSET(%r15),%r11
movq UCONTEXT_GREGS_RBX_OFFSET(%r15),%rbx
movq UCONTEXT_GREGS_RBP_OFFSET(%r15),%rbp
movq UCONTEXT_GREGS_R12_OFFSET(%r15),%r12
movq UCONTEXT_GREGS_R13_OFFSET(%r15),%r13
movq UCONTEXT_GREGS_R14_OFFSET(%r15),%r14
movq UCONTEXT_GREGS_RSI_OFFSET(%r15),%rsi
movq UCONTEXT_GREGS_RDI_OFFSET(%r15),%rdi
movq UCONTEXT_GREGS_RDX_OFFSET(%r15),%rdx
movq UCONTEXT_GREGS_RAX_OFFSET(%r15),%rax
movq UCONTEXT_GREGS_RSP_OFFSET(%r15),%rsp
movq GREGS_R8_OFFSET(%r15),%r8
movq GREGS_R9_OFFSET(%r15),%r9
movq GREGS_R10_OFFSET(%r15),%r10
movq GREGS_R11_OFFSET(%r15),%r11
movq GREGS_RBX_OFFSET(%r15),%rbx
movq GREGS_RBP_OFFSET(%r15),%rbp
movq GREGS_R12_OFFSET(%r15),%r12
movq GREGS_R13_OFFSET(%r15),%r13
movq GREGS_R14_OFFSET(%r15),%r14
movq GREGS_RSI_OFFSET(%r15),%rsi
movq GREGS_RDI_OFFSET(%r15),%rdi
movq GREGS_RDX_OFFSET(%r15),%rdx
movq GREGS_RAX_OFFSET(%r15),%rax
movq GREGS_RSP_OFFSET(%r15),%rsp

/* Push the return address on the restored stack for below retq to use. */
movq UCONTEXT_GREGS_RIP_OFFSET(%r15),%rcx
movq GREGS_RIP_OFFSET(%r15),%rcx
pushq %rcx

/* Restore rcx. */
movq UCONTEXT_GREGS_RCX_OFFSET(%r15),%rcx
movq GREGS_RCX_OFFSET(%r15),%rcx

/* Push eflags on the restored stack for popfq below to use. */
pushq UCONTEXT_GREGS_EFLAGS_OFFSET(%r15)
pushq GREGS_EFLAGS_OFFSET(%r15)

/* Restore r15. */
movq UCONTEXT_GREGS_R15_OFFSET(%r15),%r15
movq GREGS_R15_OFFSET(%r15),%r15

/* Restore eflags. */
popfq
Expand Down
99 changes: 48 additions & 51 deletions third_party/silifuzz_libunwind/save_ucontext_body.inc
Original file line number Diff line number Diff line change
Expand Up @@ -36,48 +36,47 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
pushq %rbp
movq %rsp, %rbp

/* Save eflags. */
/* Save eflags and %r15 and also load GRegSet base to callee-saved register
%r15 so that it is preserved across calls and syscalls below. */
pushfq
popq UCONTEXT_GREGS_EFLAGS_OFFSET(%rdi)

/* Save %R15 in ucontext. Then copy ucontext (%RDI) ptr in %R15 to allow
later code use %RDI for syscalls without the need to push/pop every time. */
movq %r15, UCONTEXT_GREGS_R15_OFFSET(%rdi)
mov %rdi, %r15
pushq %r15
leaq UCONTEXT_GREGS_OFFSET(%rdi), %r15
popq GREGS_R15_OFFSET(%r15)
popq GREGS_EFLAGS_OFFSET(%r15)

/* Callee saved registers %rbx, %r12-%14. */
movq %r12, UCONTEXT_GREGS_R12_OFFSET(%r15)
movq %r13, UCONTEXT_GREGS_R13_OFFSET(%r15)
movq %r14, UCONTEXT_GREGS_R14_OFFSET(%r15)
movq %rbx, UCONTEXT_GREGS_RBX_OFFSET(%r15)
movq %r12, GREGS_R12_OFFSET(%r15)
movq %r13, GREGS_R13_OFFSET(%r15)
movq %r14, GREGS_R14_OFFSET(%r15)
movq %rbx, GREGS_RBX_OFFSET(%r15)

/* Save argument registers. */
movq %r8, UCONTEXT_GREGS_R8_OFFSET(%r15)
movq %r9, UCONTEXT_GREGS_R9_OFFSET(%r15)
movq %r10, UCONTEXT_GREGS_R10_OFFSET(%r15)
movq %r11, UCONTEXT_GREGS_R11_OFFSET(%r15)
movq %rdi, UCONTEXT_GREGS_RDI_OFFSET(%r15)
movq %rsi, UCONTEXT_GREGS_RSI_OFFSET(%r15)
movq %rdx, UCONTEXT_GREGS_RDX_OFFSET(%r15)
movq %rax, UCONTEXT_GREGS_RAX_OFFSET(%r15)
movq %rcx, UCONTEXT_GREGS_RCX_OFFSET(%r15)

/* We want to save %rsp of the caller before the call instead of the current
movq %r8, GREGS_R8_OFFSET(%r15)
movq %r9, GREGS_R9_OFFSET(%r15)
movq %r10, GREGS_R10_OFFSET(%r15)
movq %r11, GREGS_R11_OFFSET(%r15)
movq %rdi, GREGS_RDI_OFFSET(%r15)
movq %rsi, GREGS_RSI_OFFSET(%r15)
movq %rdx, GREGS_RDX_OFFSET(%r15)
movq %rax, GREGS_RAX_OFFSET(%r15)
movq %rcx, GREGS_RCX_OFFSET(%r15)

/* We want to save %rsp of the caller before the call instead of the current
value. We can derived it from the frame pointer. */
leaq 0x10(%rbp), %rax
movq %rax, UCONTEXT_GREGS_RSP_OFFSET(%r15)
movq %rax, GREGS_RSP_OFFSET(%r15)

/* Similarly, save %rbp of the caller. */
movq (%rbp), %rax
movq %rax, UCONTEXT_GREGS_RBP_OFFSET(%r15)
movq %rax, GREGS_RBP_OFFSET(%r15)

/* Save segment registers. */
movw %cs, UCONTEXT_GREGS_CS_OFFSET(%r15)
movw %gs, UCONTEXT_GREGS_GS_OFFSET(%r15)
movw %fs, UCONTEXT_GREGS_FS_OFFSET(%r15)
movw %ss, UCONTEXT_GREGS_SS_OFFSET(%r15)
movw %ds, UCONTEXT_GREGS_DS_OFFSET(%r15)
movw %es, UCONTEXT_GREGS_ES_OFFSET(%r15)
movw %cs, GREGS_CS_OFFSET(%r15)
movw %gs, GREGS_GS_OFFSET(%r15)
movw %fs, GREGS_FS_OFFSET(%r15)
movw %ss, GREGS_SS_OFFSET(%r15)
movw %ds, GREGS_DS_OFFSET(%r15)
movw %es, GREGS_ES_OFFSET(%r15)

/* Skip this if we are not allowed to make syscalls */
#if !defined(UCONTEXT_NO_SYSCALLS)
Expand All @@ -89,26 +88,26 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
get restored later. */
mov $__NR_arch_prctl, %rax
mov $ARCH_GET_FS, %rdi
leaq UCONTEXT_GREGS_FS_BASE_OFFSET(%r15), %rsi
leaq GREGS_FS_BASE_OFFSET(%r15), %rsi
syscall
mov $__NR_arch_prctl, %rax
mov $ARCH_GET_GS, %rdi
leaq UCONTEXT_GREGS_GS_BASE_OFFSET(%r15), %rsi
leaq GREGS_GS_BASE_OFFSET(%r15), %rsi
syscall
#else
/* Make sure fs_base and gs_base are initialized. */
movq $0, UCONTEXT_GREGS_FS_BASE_OFFSET(%r15)
movq $0, UCONTEXT_GREGS_GS_BASE_OFFSET(%r15)
movq $0, GREGS_FS_BASE_OFFSET(%r15)
movq $0, GREGS_GS_BASE_OFFSET(%r15)
#endif

/* Save fp state. */
leaq UCONTEXT_FPREGS_OFFSET(%r15), %r8
fxsave64 (%r8) /* Value of r8 must be 16-aligned.
UContext type ensures that */
movq GREGS_RDI_OFFSET(%r15), %rdi
fxsave64 UCONTEXT_FPREGS_OFFSET(%rdi) /* Address must be 16-aligned.
UContext type ensures that */

/* Save %rip. It is the PC value after call instruction in caller. */
movq 8(%rbp), %rax
movq %rax, UCONTEXT_GREGS_RIP_OFFSET(%r15)
movq %rax, GREGS_RIP_OFFSET(%r15)

/* Restore all argument registers.
Some we have clobbered above; some might have been clobbered in syscall.
Expand All @@ -117,19 +116,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
registers do not change), but doing the restore makes the definition,
behavior, and testing of SaveUContext() and RestoreUContext() simpler
and more aligned. */
movq UCONTEXT_GREGS_R8_OFFSET(%r15), %r8
movq UCONTEXT_GREGS_R9_OFFSET(%r15), %r9
movq UCONTEXT_GREGS_R10_OFFSET(%r15), %r10
movq UCONTEXT_GREGS_R11_OFFSET(%r15), %r11
movq UCONTEXT_GREGS_RSI_OFFSET(%r15), %rsi
movq UCONTEXT_GREGS_RDX_OFFSET(%r15), %rdx
movq UCONTEXT_GREGS_RAX_OFFSET(%r15), %rax
movq UCONTEXT_GREGS_RCX_OFFSET(%r15), %rcx
mov %r15, %rdi
movq UCONTEXT_GREGS_R15_OFFSET(%r15), %r15

/* Restore eflags. */
pushq UCONTEXT_GREGS_EFLAGS_OFFSET(%rdi)
movq GREGS_R8_OFFSET(%r15), %r8
movq GREGS_R9_OFFSET(%r15), %r9
movq GREGS_R10_OFFSET(%r15), %r10
movq GREGS_R11_OFFSET(%r15), %r11
movq GREGS_RSI_OFFSET(%r15), %rsi
movq GREGS_RDX_OFFSET(%r15), %rdx
movq GREGS_RAX_OFFSET(%r15), %rax
movq GREGS_RCX_OFFSET(%r15), %rcx
movq GREGS_RDI_OFFSET(%r15), %rdi
pushq GREGS_EFLAGS_OFFSET(%r15)
movq GREGS_R15_OFFSET(%r15), %r15
popfq

/* Instructions in the epilogue must not change %rflags. */
Expand Down
5 changes: 4 additions & 1 deletion util/ucontext/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -328,5 +328,8 @@ cc_test(
cc_binary(
name = "ucontext_offsets_gen",
srcs = ["x86_64/ucontext_offsets_gen.cc"],
deps = [":ucontext_types"],
deps = [
":ucontext_types",
"@silifuzz//util:arch",
],
)
55 changes: 28 additions & 27 deletions util/ucontext/x86_64/ucontext_offsets.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The SiliFuzz Authors.
// Copyright 2024 The SiliFuzz Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -16,30 +16,31 @@
#ifndef THIRD_PARTY_SILIFUZZ_UTIL_UCONTEXT_X86_64_UCONTEXT_OFFSETS_H_
#define THIRD_PARTY_SILIFUZZ_UTIL_UCONTEXT_X86_64_UCONTEXT_OFFSETS_H_
#define UCONTEXT_FPREGS_OFFSET 0x0
#define UCONTEXT_GREGS_R8_OFFSET 0x200
#define UCONTEXT_GREGS_R9_OFFSET 0x208
#define UCONTEXT_GREGS_R10_OFFSET 0x210
#define UCONTEXT_GREGS_R11_OFFSET 0x218
#define UCONTEXT_GREGS_R12_OFFSET 0x220
#define UCONTEXT_GREGS_R13_OFFSET 0x228
#define UCONTEXT_GREGS_R14_OFFSET 0x230
#define UCONTEXT_GREGS_R15_OFFSET 0x238
#define UCONTEXT_GREGS_RAX_OFFSET 0x268
#define UCONTEXT_GREGS_RBX_OFFSET 0x258
#define UCONTEXT_GREGS_RCX_OFFSET 0x270
#define UCONTEXT_GREGS_RDX_OFFSET 0x260
#define UCONTEXT_GREGS_RBP_OFFSET 0x250
#define UCONTEXT_GREGS_RSP_OFFSET 0x278
#define UCONTEXT_GREGS_RSI_OFFSET 0x248
#define UCONTEXT_GREGS_RDI_OFFSET 0x240
#define UCONTEXT_GREGS_RIP_OFFSET 0x280
#define UCONTEXT_GREGS_EFLAGS_OFFSET 0x288
#define UCONTEXT_GREGS_FS_BASE_OFFSET 0x2a0
#define UCONTEXT_GREGS_GS_BASE_OFFSET 0x2a8
#define UCONTEXT_GREGS_CS_OFFSET 0x290
#define UCONTEXT_GREGS_SS_OFFSET 0x296
#define UCONTEXT_GREGS_FS_OFFSET 0x294
#define UCONTEXT_GREGS_GS_OFFSET 0x292
#define UCONTEXT_GREGS_ES_OFFSET 0x29a
#define UCONTEXT_GREGS_DS_OFFSET 0x298
#define UCONTEXT_GREGS_OFFSET 0x200
#define GREGS_R8_OFFSET 0x0
#define GREGS_R9_OFFSET 0x8
#define GREGS_R10_OFFSET 0x10
#define GREGS_R11_OFFSET 0x18
#define GREGS_R12_OFFSET 0x20
#define GREGS_R13_OFFSET 0x28
#define GREGS_R14_OFFSET 0x30
#define GREGS_R15_OFFSET 0x38
#define GREGS_RAX_OFFSET 0x68
#define GREGS_RBX_OFFSET 0x58
#define GREGS_RCX_OFFSET 0x70
#define GREGS_RDX_OFFSET 0x60
#define GREGS_RBP_OFFSET 0x50
#define GREGS_RSP_OFFSET 0x78
#define GREGS_RSI_OFFSET 0x48
#define GREGS_RDI_OFFSET 0x40
#define GREGS_RIP_OFFSET 0x80
#define GREGS_EFLAGS_OFFSET 0x88
#define GREGS_FS_BASE_OFFSET 0xa0
#define GREGS_GS_BASE_OFFSET 0xa8
#define GREGS_CS_OFFSET 0x90
#define GREGS_SS_OFFSET 0x96
#define GREGS_FS_OFFSET 0x94
#define GREGS_GS_OFFSET 0x92
#define GREGS_ES_OFFSET 0x9a
#define GREGS_DS_OFFSET 0x98
#endif // THIRD_PARTY_SILIFUZZ_UTIL_UCONTEXT_X86_64_UCONTEXT_OFFSETS_H_
Loading

0 comments on commit 36757d5

Please sign in to comment.