Back to index

glibc  2.9
bp-asm.h
Go to the documentation of this file.
00001 /* Bounded-pointer definitions for x86 assembler.
00002    Copyright (C) 2000 Free Software Foundation, Inc.
00003    Contributed by Greg McGary <greg@mcgary.org>
00004    This file is part of the GNU C Library.  Its master source is NOT part of
00005    the C library, however.  The master source lives in the GNU MP Library.
00006 
00007    The GNU C Library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public
00009    License as published by the Free Software Foundation; either
00010    version 2.1 of the License, or (at your option) any later version.
00011 
00012    The GNU C Library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License for more details.
00016 
00017    You should have received a copy of the GNU Lesser General Public
00018    License along with the GNU C Library; if not, write to the Free
00019    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00020    02111-1307 USA.  */
00021 
00022 #ifndef _bp_asm_h_
00023 # define _bp_asm_h_ 1
00024 
00025 # if __ASSEMBLER__
00026 
00027 #  if __BOUNDED_POINTERS__
00028 
00029 /* Bounded pointers occupy three words.  */
00030 #   define PTR_SIZE 12
00031 /* Bounded pointer return values are passed back through a hidden
00032    argument that points to caller-allocate space.  The hidden arg
00033    occupies one word on the stack.  */
00034 #   define RTN_SIZE 4
00035 /* Although the caller pushes the hidden arg, the callee is
00036    responsible for popping it.  */
00037 #   define RET_PTR ret $RTN_SIZE
00038 /* Maintain frame pointer chain in leaf assembler functions for the benefit
00039    of debugging stack traces when bounds violations occur.  */
00040 #   define ENTER pushl %ebp; movl %esp, %ebp
00041 #   define LEAVE movl %ebp, %esp; popl %ebp
00042 /* Stack space overhead of procedure-call linkage: return address and
00043    frame pointer.  */
00044 #   define LINKAGE 8
00045 /* Stack offset of return address after calling ENTER.  */
00046 #   define PCOFF 4
00047 
00048 /* Int 5 is the "bound range" exception also raised by the "bound"
00049    instruction.  */
00050 #   define BOUNDS_VIOLATED int $5
00051 
00052 #   define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM)     \
00053        cmpl 4+BP_MEM, VAL_REG;                   \
00054        jae 0f; /* continue if value >= low */    \
00055        BOUNDS_VIOLATED;                   \
00056     0:
00057 
00058 #   define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc)      \
00059        cmpl 8+BP_MEM, VAL_REG;                          \
00060        Jcc 0f; /* continue if value < high */           \
00061        BOUNDS_VIOLATED;                          \
00062     0:
00063 
00064 #   define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM)    \
00065        cmpl 4+BP_MEM, VAL_REG;                   \
00066        jb 1f; /* die if value < low */           \
00067        cmpl 8+BP_MEM, VAL_REG;                   \
00068        jb 0f; /* continue if value < high */     \
00069     1: BOUNDS_VIOLATED;                   \
00070     0:
00071 
00072 #   define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH)     \
00073        CHECK_BOUNDS_LOW(VAL_REG, BP_MEM);               \
00074        addl LENGTH, VAL_REG;                                   \
00075        cmpl 8+BP_MEM, VAL_REG;                                 \
00076        jbe 0f; /* continue if value <= high */                 \
00077        BOUNDS_VIOLATED;                                 \
00078     0: subl LENGTH, VAL_REG /* restore value */
00079 
00080 /* Take bounds from BP_MEM and affix them to the pointer
00081    value in %eax, stuffing all into memory at RTN(%esp).
00082    Use %edx as a scratch register.  */
00083 
00084 #   define RETURN_BOUNDED_POINTER(BP_MEM) \
00085        movl RTN(%esp), %edx;                     \
00086        movl %eax, 0(%edx);                \
00087        movl 4+BP_MEM, %eax;               \
00088        movl %eax, 4(%edx);                \
00089        movl 8+BP_MEM, %eax;               \
00090        movl %eax, 8(%edx)
00091 
00092 #   define RETURN_NULL_BOUNDED_POINTER           \
00093        movl RTN(%esp), %edx;                     \
00094        movl %eax, 0(%edx);                \
00095        movl %eax, 4(%edx);                \
00096        movl %eax, 8(%edx)
00097 
00098 /* The caller of __errno_location is responsible for allocating space
00099    for the three-word BP return-value and passing pushing its address
00100    as an implicit first argument.  */
00101 #   define PUSH_ERRNO_LOCATION_RETURN            \
00102        subl $8, %esp;                            \
00103        subl $4, %esp;                            \
00104        pushl %esp
00105 
00106 /* __errno_location is responsible for popping the implicit first
00107    argument, but we must pop the space for the BP itself.  We also
00108    dereference the return value in order to dig out the pointer value.  */
00109 #   define POP_ERRNO_LOCATION_RETURN             \
00110        popl %eax;                         \
00111        addl $8, %esp
00112 
00113 #  else /* !__BOUNDED_POINTERS__ */
00114 
00115 /* Unbounded pointers occupy one word.  */
00116 #   define PTR_SIZE 4
00117 /* Unbounded pointer return values are passed back in the register %eax.  */
00118 #   define RTN_SIZE 0
00119 /* Use simple return instruction for unbounded pointer values.  */
00120 #   define RET_PTR ret
00121 /* Don't maintain frame pointer chain for leaf assembler functions.  */
00122 #   define ENTER
00123 #   define LEAVE
00124 /* Stack space overhead of procedure-call linkage: return address only.  */
00125 #   define LINKAGE 4
00126 /* Stack offset of return address after calling ENTER.  */
00127 #   define PCOFF 0
00128 
00129 #   define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM)
00130 #   define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc)
00131 #   define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM)
00132 #   define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH)
00133 #   define RETURN_BOUNDED_POINTER(BP_MEM)
00134 
00135 #   define RETURN_NULL_BOUNDED_POINTER
00136 
00137 #   define PUSH_ERRNO_LOCATION_RETURN
00138 #   define POP_ERRNO_LOCATION_RETURN
00139 
00140 #  endif /* !__BOUNDED_POINTERS__ */
00141 
00142 # endif /* __ASSEMBLER__ */
00143 
00144 #endif /* _bp_asm_h_ */