diff options
Diffstat (limited to 'sysdeps/i386/bp-asm.h')
-rw-r--r-- | sysdeps/i386/bp-asm.h | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/sysdeps/i386/bp-asm.h b/sysdeps/i386/bp-asm.h new file mode 100644 index 0000000000..197c6da88c --- /dev/null +++ b/sysdeps/i386/bp-asm.h @@ -0,0 +1,142 @@ +/* Bounded-pointer definitions for x86 assembler. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Greg McGary <greg@mcgary.org> + + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in the GNU MP Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _bp_asm_h_ +# define _bp_asm_h_ 1 + +# if __ASSEMBLER__ + +# if __BOUNDED_POINTERS__ + +/* Bounded pointers occupy three words. */ +# define PTR_SIZE 12 +/* Bounded pointer return values are passed back through a hidden + argument that points to caller-allocate space. The hidden arg + occupies one word on the stack. */ +# define RTN_SIZE 4 +/* Although the caller pushes the hidden arg, the callee is + responsible for popping it. */ +# define RET_PTR ret $RTN_SIZE +/* Maintain frame pointer chain in leaf assembler functions for the benefit + of debugging stack traces when bounds violations occur. */ +# define ENTER pushl %ebp; movl %esp, %ebp +# define LEAVE movl %ebp, %esp; popl %ebp +/* Stack space overhead of procedure-call linkage: return address and + frame pointer. */ +# define LINKAGE 8 + +/* Int 5 is the "bound range" exception also raised by the "bound" + instruction. */ +# define BOUNDS_VIOLATED int $5 + +# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM) \ + cmpl 4+BP_MEM, VAL_REG; \ + jae 0f; /* continue if value >= low */ \ + BOUNDS_VIOLATED; \ + 0: + +# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc) \ + cmpl 8+BP_MEM, VAL_REG; \ + Jcc 0f; /* continue if value < high */ \ + BOUNDS_VIOLATED; \ + 0: + +# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM) \ + cmpl 4+BP_MEM, VAL_REG; \ + jb 1f; /* die if value < low */ \ + cmpl 8+BP_MEM, VAL_REG; \ + jb 0f; /* continue if value < high */ \ + 1: BOUNDS_VIOLATED; \ + 0: + +# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) \ + CHECK_BOUNDS_LOW(VAL_REG, BP_MEM); \ + addl LENGTH, VAL_REG; \ + cmpl 8+BP_MEM, VAL_REG; \ + jbe 0f; /* continue if value <= high */ \ + BOUNDS_VIOLATED; \ + 0: subl LENGTH, VAL_REG /* restore value */ + +/* Take bounds from BP_MEM and affix them to the pointer + value in %eax, stuffing all into memory at RTN(%esp). + Use %ecx as a scratch register. */ + +# define RETURN_BOUNDED_POINTER(BP_MEM) \ + movl RTN(%esp), %ecx; \ + movl %eax, 0(%ecx); \ + movl 4+BP_MEM, %eax; \ + movl %eax, 4(%ecx); \ + movl 8+BP_MEM, %eax; \ + movl %eax, 8(%ecx) + +# define RETURN_NULL_BOUNDED_POINTER \ + movl RTN(%esp), %ecx; \ + movl %eax, 0(%ecx); \ + movl %eax, 4(%ecx); \ + movl %eax, 8(%ecx) + +/* The caller of __errno_location is responsible for allocating space + for the three-word BP return-value and passing pushing its address + as an implicit first argument. */ +# define PUSH_ERRNO_LOCATION_RETURN \ + subl $8, %esp; \ + subl $4, %esp; \ + pushl %esp + +/* __errno_location is responsible for popping the implicit first + argument, but we must pop the space for the BP itself. We also + dereference the return value in order to dig out the pointer value. */ +# define POP_ERRNO_LOCATION_RETURN \ + movl (%esp), %eax; \ + addl $4, %esp; \ + addl $8, %esp + +# else /* !__BOUNDED_POINTERS__ */ + +/* Unbounded pointers occupy one word. */ +# define PTR_SIZE 4 +/* Unbounded pointer return values are passed back in the register %eax. */ +# define RTN_SIZE 0 +/* Use simple return instruction for unbounded pointer values. */ +# define RET_PTR ret +/* Don't maintain frame pointer chain for leaf assembler functions. */ +# define ENTER +# define LEAVE +/* Stack space overhead of procedure-call linkage: return address only. */ +# define LINKAGE 4 + +# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM) +# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc) +# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM) +# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) +# define RETURN_BOUNDED_POINTER(BP_MEM) + +# define RETURN_NULL_BOUNDED_POINTER + +# define PUSH_ERRNO_LOCATION_RETURN +# define POP_ERRNO_LOCATION_RETURN + +# endif /* !__BOUNDED_POINTERS__ */ + +# endif /* __ASSEMBLER__ */ + +#endif /* _bp_asm_h_ */ |