#ifndef _MACHINE_ASM_H_
#define _MACHINE_ASM_H_
#ifdef __PIC__
#define PIC_PLT(x) x@PLT
#define PIC_GOT(x) x@GOTPCREL(%rip)
#else
#define PIC_PLT(x) x
#define PIC_GOT(x) x
#endif
# define _C_LABEL(x) x
#define _ASM_LABEL(x) x
#define CVAROFF(x,y) (x+y)(%rip)
#ifdef __STDC__
# define __CONCAT(x,y) x ## y
# define __STRING(x) #x
#else
# define __CONCAT(x,y) xy
# define __STRING(x) "x"
#endif
#ifndef _ALIGN_TEXT
#define _ALIGN_TEXT .align 16, 0x90
#endif
#define _ALIGN_TRAPS .align 16, 0xcc
#define _FENTRY(x) .type x,@function; x:
#define NENTRY_NB(x) \
.text; _ALIGN_TEXT; _FENTRY(x)
#define _ENTRY_NB(x) \
.text; _ALIGN_TRAPS; _FENTRY(x)
#define _ENTRY(x) .globl x; _ENTRY_NB(x)
#define _NENTRY(x) .globl x; NENTRY_NB(x)
#ifdef _KERNEL
#define KUTEXT .section .kutext, "ax", @progbits
#define KUTEXT_PAGE_START .pushsection .kutext.page, "a", @progbits
#define KTEXT_PAGE_START .pushsection .ktext.page, "ax", @progbits
#define KUTEXT_PAGE_END .popsection
#define KTEXT_PAGE_END .popsection
#define IDTVEC(name) \
KUTEXT; _ALIGN_TRAPS; IDTVEC_NOALIGN(name); endbr64
#define GENTRY(x) .globl x; _FENTRY(x)
#define IDTVEC_NOALIGN(name) GENTRY(X ## name)
#define IDTVEC_ALIAS(alias,sym) \
.global X ## alias; \
X ## alias = X ## sym;
#define KIDTVEC(name) \
.text; _ALIGN_TRAPS; IDTVEC_NOALIGN(name); endbr64
#define KIDTVEC_FALLTHROUGH(name) \
_ALIGN_TEXT; IDTVEC_NOALIGN(name)
#define KUENTRY(x) \
KUTEXT; _ALIGN_TRAPS; GENTRY(x)
#define RET_STACK_REFILL_WITH_RCX \
mov $8,%rcx ; \
_ALIGN_TEXT ; \
3: call 5f ; \
4: pause ; \
lfence ; \
call 4b ; \
_ALIGN_TRAPS ; \
5: call 7f ; \
6: pause ; \
lfence ; \
call 6b ; \
_ALIGN_TRAPS ; \
7: loop 3b ; \
add $(16*8),%rsp
#endif
#ifdef __STDC__
#define CPUVAR(off) %gs:CPU_INFO_ ## off
#else
#define CPUVAR(off) %gs:CPU_INFO_off
#endif
#if defined(PROF) || defined(GPROF)
# define _PROF_PROLOGUE \
pushq %rbp; leaq (%rsp),%rbp; call PIC_PLT(__mcount); popq %rbp
#else
# define _PROF_PROLOGUE
#endif
#if defined(_RET_PROTECTOR)
# define RETGUARD_SETUP_OFF(x, reg, off) \
RETGUARD_SYMBOL(x); \
movq (__retguard_ ## x)(%rip), %reg; \
xorq off(%rsp), %reg
# define RETGUARD_SETUP(x, reg) \
RETGUARD_SETUP_OFF(x, reg, 0)
# define RETGUARD_CHECK(x, reg) \
xorq (%rsp), %reg; \
cmpq (__retguard_ ## x)(%rip), %reg; \
je 66f; \
int3; int3; \
.zero (0xf - ((. + 3 - x) & 0xf)), 0xcc; \
66:
# define RETGUARD_PUSH(reg) \
pushq %reg
# define RETGUARD_POP(reg) \
popq %reg
# define RETGUARD_SYMBOL(x) \
.ifndef __retguard_ ## x; \
.hidden __retguard_ ## x; \
.type __retguard_ ## x,@object; \
.pushsection .openbsd.randomdata.retguard,"aw",@progbits; \
.weak __retguard_ ## x; \
.p2align 3; \
__retguard_ ## x: ; \
.quad 0; \
.size __retguard_ ## x, 8; \
.popsection; \
.endif
#else
# define RETGUARD_SETUP_OFF(x, reg, off)
# define RETGUARD_SETUP(x, reg)
# define RETGUARD_CHECK(x, reg)
# define RETGUARD_PUSH(reg)
# define RETGUARD_POP(reg)
# define RETGUARD_SYMBOL(x)
#endif
#define ENTRY(y) _ENTRY(y); endbr64; _PROF_PROLOGUE
#define NENTRY(y) _NENTRY(y)
#define ASENTRY(y) _NENTRY(y); endbr64; _PROF_PROLOGUE
#define ENTRY_NB(y) _ENTRY_NB(y); endbr64; _PROF_PROLOGUE
#define END(y) .size y, . - y
#define STRONG_ALIAS(alias,sym) \
.global alias; \
alias = sym
#define WEAK_ALIAS(alias,sym) \
.weak alias; \
alias = sym
#define JMP_RETPOLINE(reg) \
call 69f ; \
68: pause ; \
lfence ; \
jmp 68b ; \
_ALIGN_TRAPS ; \
69: mov %reg,(%rsp) ; \
ret ; \
lfence
#endif