xref: /haiku/src/system/libroot/posix/glibc/include/arch/x86_64/bp-asm.h (revision 0ce4c23d22fae64d10e5575687490fbdf8ee52b8)
1 /* Bounded-pointer definitions for x86-64 assembler.
2    Copyright (C) 2001 Free Software Foundation, Inc.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18 
19 #ifndef _bp_asm_h_
20 # define _bp_asm_h_ 1
21 
22 # if __ASSEMBLER__
23 
24 #  if __BOUNDED_POINTERS__
25 
26 /* Bounded pointers occupy three words.  */
27 #   define PTR_SIZE 24
28 /* Bounded pointer return values are passed back through a hidden
29    argument that points to caller-allocate space.  The hidden arg
30    occupies one word on the stack.  */
31 #   define RTN_SIZE 6
32 /* Although the caller pushes the hidden arg, the callee is
33    responsible for popping it.  */
34 #   define RET_PTR ret $RTN_SIZE
35 /* Maintain frame pointer chain in leaf assembler functions for the benefit
36    of debugging stack traces when bounds violations occur.  */
37 #   define ENTER pushq %rbp; movq %rsp, %rbp
38 #   define LEAVE movq %rbp, %rsp; popq %rbp
39 /* Stack space overhead of procedure-call linkage: return address and
40    frame pointer.  */
41 #   define LINKAGE 16
42 /* Stack offset of return address after calling ENTER.  */
43 #   define PCOFF 8
44 
45 /* Int 5 is the "bound range" exception also raised by the "bound"
46    instruction.  */
47 #   define BOUNDS_VIOLATED int $5
48 
49 #   define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM)	\
50 	cmpq 8+BP_MEM, VAL_REG;			\
51 	jae 0f; /* continue if value >= low */	\
52 	BOUNDS_VIOLATED;			\
53     0:
54 
55 #   define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc)	\
56 	cmpq 16+BP_MEM, VAL_REG;			\
57 	Jcc 0f; /* continue if value < high */		\
58 	BOUNDS_VIOLATED;				\
59     0:
60 
61 #   define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM)	\
62 	cmpq 8+BP_MEM, VAL_REG;			\
63 	jb 1f; /* die if value < low */		\
64 	cmpq 16+BP_MEM, VAL_REG;		\
65 	jb 0f; /* continue if value < high */	\
66     1:	BOUNDS_VIOLATED;			\
67     0:
68 
69 #   define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH)	\
70 	CHECK_BOUNDS_LOW(VAL_REG, BP_MEM);			\
71 	addl LENGTH, VAL_REG;					\
72 	cmpq 16+BP_MEM, VAL_REG;					\
73 	jbe 0f; /* continue if value <= high */			\
74 	BOUNDS_VIOLATED;					\
75     0:	subq LENGTH, VAL_REG /* restore value */
76 
77 /* Take bounds from BP_MEM and affix them to the pointer
78    value in %rax, stuffing all into memory at RTN(%esp).
79    Use %rdx as a scratch register.  */
80 
81 #   define RETURN_BOUNDED_POINTER(BP_MEM)	\
82 	movq RTN(%rsp), %rdx;			\
83 	movq %rax, 0(%rdx);			\
84 	movq 8+BP_MEM, %rax;			\
85 	movq %rax, 4(%rdx);			\
86 	movq 16+BP_MEM, %rax;			\
87 	movq %rax, 8(%rdx)
88 
89 #   define RETURN_NULL_BOUNDED_POINTER		\
90 	movl RTN(%rsp), %rdx;			\
91 	movl %rax, 0(%rdx);			\
92 	movl %rax, 4(%rdx);			\
93 	movl %rax, 8(%rdx)
94 
95 /* The caller of __errno_location is responsible for allocating space
96    for the three-word BP return-value and passing pushing its address
97    as an implicit first argument.  */
98 #   define PUSH_ERRNO_LOCATION_RETURN		\
99 	subl $16, %esp;				\
100 	subl $8, %esp;				\
101 	pushq %rsp
102 
103 /* __errno_location is responsible for popping the implicit first
104    argument, but we must pop the space for the BP itself.  We also
105    dereference the return value in order to dig out the pointer value.  */
106 #   define POP_ERRNO_LOCATION_RETURN		\
107 	popq %rax;				\
108 	addq $16, %rsp
109 
110 #  else /* !__BOUNDED_POINTERS__ */
111 
112 /* Unbounded pointers occupy one word.  */
113 #   define PTR_SIZE 8
114 /* Unbounded pointer return values are passed back in the register %rax.  */
115 #   define RTN_SIZE 0
116 /* Use simple return instruction for unbounded pointer values.  */
117 #   define RET_PTR ret
118 /* Don't maintain frame pointer chain for leaf assembler functions.  */
119 #   define ENTER
120 #   define LEAVE
121 /* Stack space overhead of procedure-call linkage: return address only.  */
122 #   define LINKAGE 8
123 /* Stack offset of return address after calling ENTER.  */
124 #   define PCOFF 0
125 
126 #   define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM)
127 #   define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc)
128 #   define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM)
129 #   define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH)
130 #   define RETURN_BOUNDED_POINTER(BP_MEM)
131 
132 #   define RETURN_NULL_BOUNDED_POINTER
133 
134 #   define PUSH_ERRNO_LOCATION_RETURN
135 #   define POP_ERRNO_LOCATION_RETURN
136 
137 #  endif /* !__BOUNDED_POINTERS__ */
138 
139 # endif /* __ASSEMBLER__ */
140 
141 #endif /* _bp_asm_h_ */
142