1/* $OpenBSD: asm.h,v 1.24 2023/04/17 00:02:14 deraadt Exp $ */
2/* $NetBSD: asm.h,v 1.2 2003/05/02 18:05:47 yamt Exp $ */
3
4/*-
5 * Copyright (c) 1990 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * William Jolitz.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * @(#)asm.h 5.5 (Berkeley) 5/7/91
36 */
37
38#ifndef _MACHINE_ASM_H_
39#define _MACHINE_ASM_H_
40
41#ifdef __PIC__
42#define PIC_PLT(x) x@PLT
43#define PIC_GOT(x) x@GOTPCREL(%rip)
44#else
45#define PIC_PLT(x) x
46#define PIC_GOT(x) x
47#endif
48
49# define _C_LABEL(x) x
50#define _ASM_LABEL(x) x
51
52#define CVAROFF(x,y) (x+y)(%rip)
53
54#ifdef __STDC__
55# define __CONCAT(x,y) x ## y
56# define __STRING(x) #x
57#else
58# define __CONCAT(x,y) x/**/y
59# define __STRING(x) "x"
60#endif
61
62/* let kernels and others override entrypoint alignment */
63#ifndef _ALIGN_TEXT
64#define _ALIGN_TEXT .align 16, 0x90
65#endif
66#define _ALIGN_TRAPS .align 16, 0xcc
67
68#define _FENTRY(x) .type x,@function; x:
69
70/* NB == No Binding: use .globl or .weak as necessary */
71#define NENTRY_NB(x) \
72 .text; _ALIGN_TEXT; _FENTRY(x)
73#define _ENTRY_NB(x) \
74 .text; _ALIGN_TRAPS; _FENTRY(x)
75#define _ENTRY(x) .globl x; _ENTRY_NB(x)
76#define _NENTRY(x) .globl x; NENTRY_NB(x)
77
78#ifdef _KERNEL
79#define KUTEXT .section .kutext, "ax", @progbits
80
81#define KUTEXT_PAGE_START .pushsection .kutext.page, "a", @progbits
82#define KTEXT_PAGE_START .pushsection .ktext.page, "ax", @progbits
83#define KUTEXT_PAGE_END .popsection
84#define KTEXT_PAGE_END .popsection
85
86#define IDTVEC(name) \
87 KUTEXT; _ALIGN_TRAPS; IDTVEC_NOALIGN(name); endbr64
88#define GENTRY(x) .globl x; _FENTRY(x)
89#define IDTVEC_NOALIGN(name) GENTRY(X ## name)
90#define IDTVEC_ALIAS(alias,sym) \
91 .global X ## alias; \
92 X ## alias = X ## sym;
93#define KIDTVEC(name) \
94 .text; _ALIGN_TRAPS; IDTVEC_NOALIGN(name); endbr64
95#define KIDTVEC_FALLTHROUGH(name) \
96 _ALIGN_TEXT; IDTVEC_NOALIGN(name)
97#define KUENTRY(x) \
98 KUTEXT; _ALIGN_TRAPS; GENTRY(x)
99
100/* Return stack refill, to prevent speculation attacks on natural returns */
101#define RET_STACK_REFILL_WITH_RCX \
102 mov $8,%rcx ; \
103 _ALIGN_TEXT ; \
104 3: call 5f ; \
105 4: pause ; \
106 lfence ; \
107 call 4b ; \
108 _ALIGN_TRAPS ; \
109 5: call 7f ; \
110 6: pause ; \
111 lfence ; \
112 call 6b ; \
113 _ALIGN_TRAPS ; \
114 7: loop 3b ; \
115 add $(16*8),%rsp
116
117#endif /* _KERNEL */
118
119#ifdef __STDC__
120#define CPUVAR(off) %gs:CPU_INFO_ ## off
121#else
122#define CPUVAR(off) %gs:CPU_INFO_/**/off
123#endif
124
125
126#if defined(PROF) || defined(GPROF)
127# define _PROF_PROLOGUE \
128 pushq %rbp; leaq (%rsp),%rbp; call PIC_PLT(__mcount); popq %rbp
129#else
130# define _PROF_PROLOGUE
131#endif
132
133#if defined(_RET_PROTECTOR)
134# define RETGUARD_SETUP_OFF(x, reg, off) \
135 RETGUARD_SYMBOL(x); \
136 movq (__retguard_ ## x)(%rip), %reg; \
137 xorq off(%rsp), %reg
138# define RETGUARD_SETUP(x, reg) \
139 RETGUARD_SETUP_OFF(x, reg, 0)
140# define RETGUARD_CHECK(x, reg) \
141 xorq (%rsp), %reg; \
142 cmpq (__retguard_ ## x)(%rip), %reg; \
143 je 66f; \
144 int3; int3; \
145 .zero (0xf - ((. + 3 - x) & 0xf)), 0xcc; \
14666:
147# define RETGUARD_PUSH(reg) \
148 pushq %reg
149# define RETGUARD_POP(reg) \
150 popq %reg
151# define RETGUARD_SYMBOL(x) \
152 .ifndef __retguard_ ## x; \
153 .hidden __retguard_ ## x; \
154 .type __retguard_ ## x,@object; \
155 .pushsection .openbsd.randomdata.retguard,"aw",@progbits; \
156 .weak __retguard_ ## x; \
157 .p2align 3; \
158 __retguard_ ## x: ; \
159 .quad 0; \
160 .size __retguard_ ## x, 8; \
161 .popsection; \
162 .endif
163#else
164# define RETGUARD_SETUP_OFF(x, reg, off)
165# define RETGUARD_SETUP(x, reg)
166# define RETGUARD_CHECK(x, reg)
167# define RETGUARD_PUSH(reg)
168# define RETGUARD_POP(reg)
169# define RETGUARD_SYMBOL(x)
170#endif
171
172#define ENTRY(y) _ENTRY(y); endbr64; _PROF_PROLOGUE
173#define NENTRY(y) _NENTRY(y)
174#define ASENTRY(y) _NENTRY(y); endbr64; _PROF_PROLOGUE
175#define ENTRY_NB(y) _ENTRY_NB(y); endbr64; _PROF_PROLOGUE
176#define END(y) .size y, . - y
177
178#define STRONG_ALIAS(alias,sym) \
179 .global alias; \
180 alias = sym
181#define WEAK_ALIAS(alias,sym) \
182 .weak alias; \
183 alias = sym
184
185/* generic retpoline ("return trampoline") generator */
186#define JMP_RETPOLINE(reg) \
187 call 69f ; \
188 68: pause ; \
189 lfence ; \
190 jmp 68b ; \
191 _ALIGN_TRAPS ; \
192 69: mov %reg,(%rsp) ; \
193 ret ; \
194 lfence
195
196#endif /* !_MACHINE_ASM_H_ */