1 /* @(#)getfp.c 1.14 03/07/13 Copyright 1988-2003 J. Schilling */ 2 /* 3 * Get frame pointer 4 * 5 * Copyright (c) 1988-2003 J. Schilling 6 */ 7 /* 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along with 19 * this program; see the file COPYING. If not, write to the Free Software 20 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 */ 22 23 #include <mconfig.h> 24 #include <standard.h> 25 #include <schily.h> 26 27 #ifndef IS_AVOFFSET 28 /* 29 * We usually don't like to compile a getfp() that returns junk data in case 30 * we cannot scan the stack. 31 * The only way to find this out is by including avoffset.h. Unfortunately, we 32 * need to be able to use getfp() from avoffset.c in order to check if the 33 * return value is usable or junk. To be able to do this, we include getfp.c 34 * from avoffset.c and define IS_AVOFFSET before. 35 */ 36 #include <avoffset.h> 37 38 #if !defined(AV_OFFSET) || !defined(FP_INDIR) 39 # ifdef HAVE_SCANSTACK 40 # undef HAVE_SCANSTACK 41 # endif 42 #endif 43 #endif 44 45 #ifdef HAVE_SCANSTACK 46 #include <stkframe.h> 47 48 #define MAXWINDOWS 32 49 #define NWINDOWS 7 50 51 #if defined(sparc) && defined(__GNUC__) 52 # define FP_OFF 0x10 /* some strange things on sparc gcc */ 53 #else 54 # define FP_OFF 0 55 #endif 56 57 EXPORT void **___fpoff __PR((char *cp)); 58 59 EXPORT __noinline void ** getfp()60getfp() 61 { 62 long **dummy[1]; 63 64 #ifdef sparc 65 flush_reg_windows(MAXWINDOWS-2); 66 #endif 67 return ((void **)((struct frame *)___fpoff((char *)&dummy[0]))->fr_savfp); 68 } 69 70 /* 71 * Don't make it static to avoid inline optimization. 72 * 73 * We need this function to fool GCCs check for returning addresses 74 * from outside the functions local address space. 75 */ 76 EXPORT __noinline void ** ___fpoff(cp)77___fpoff(cp) 78 char *cp; 79 { 80 long ***lp; 81 82 lp = (long ***)(cp + FP_OFF); 83 lp++; 84 return ((void **)lp); 85 } 86 87 #ifdef sparc 88 EXPORT int flush_reg_windows(n)89flush_reg_windows(n) 90 int n; 91 { 92 if (--n > 0) 93 flush_reg_windows(n); 94 return (0); 95 } 96 #endif 97 98 #endif /* HAVE_SCANSTACK */ 99