1 /* @(#)getfp.c 1.21 21/04/28 Copyright 1988-2021 J. Schilling */ 2 /* 3 * Get frame pointer 4 * 5 * Copyright (c) 1988-2021 J. Schilling 6 */ 7 /* 8 * The contents of this file are subject to the terms of the 9 * Common Development and Distribution License, Version 1.0 only 10 * (the "License"). You may not use this file except in compliance 11 * with the License. 12 * 13 * See the file CDDL.Schily.txt in this distribution for details. 14 * A copy of the CDDL is also available via the Internet at 15 * http://www.opensource.org/licenses/cddl1.txt 16 * 17 * When distributing Covered Code, include this CDDL HEADER in each 18 * file and include the License file CDDL.Schily.txt from this distribution. 19 */ 20 21 #include <schily/mconfig.h> 22 #include <schily/standard.h> 23 #include <schily/schily.h> 24 25 #ifndef IS_AVOFFSET 26 /* 27 * We usually don't like to compile a getfp() that returns junk data in case 28 * we cannot scan the stack. 29 * The only way to find this out is by including avoffset.h. Unfortunately, we 30 * need to be able to use getfp() from avoffset.c in order to check if the 31 * return value is usable or junk. To be able to do this, we include getfp.c 32 * from avoffset.c and define IS_AVOFFSET before. 33 */ 34 #include <schily/avoffset.h> 35 36 #if !defined(AV_OFFSET) || !defined(FP_INDIR) 37 # ifdef HAVE_SCANSTACK 38 # undef HAVE_SCANSTACK 39 # endif 40 #endif 41 #endif 42 43 #ifdef HAVE_SCANSTACK 44 #include <schily/stkframe.h> 45 46 #define MAXWINDOWS 32 47 #define NWINDOWS 7 48 49 #if defined(sparc) && defined(__GNUC__) 50 # define FP_OFF 0x10 /* some strange things on sparc gcc */ 51 #else 52 # define FP_OFF 0 53 #endif 54 55 #if defined(__clang__) || \ 56 (defined(__GNUC__) && \ 57 ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ > 7))) 58 #define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) 59 #else 60 #define ATTRIBUTE_NO_SANITIZE_ADDRESS 61 #endif 62 63 EXPORT void **___fpoff __PR((char *cp)); 64 65 ATTRIBUTE_NO_SANITIZE_ADDRESS 66 __NO_INL__ 67 EXPORT void ** getfp()68getfp() 69 { 70 long **dummy[1]; 71 72 #ifdef sparc 73 flush_reg_windows(MAXWINDOWS-2); 74 #endif 75 return ((void **)((struct frame *)___fpoff((char *)&dummy[0]))->fr_savfp); 76 } 77 78 #ifdef sparc 79 __NO_INL__ 80 EXPORT int flush_reg_windows(n)81flush_reg_windows(n) 82 int n; 83 { 84 if (--n > 0) 85 flush_reg_windows(n); 86 return (0); 87 } 88 #endif 89 90 #else /* HAVE_SCANSTACK */ 91 92 EXPORT void ** getfp()93getfp() 94 { 95 raisecond("getfp", 0); 96 return ((void **)0); 97 } 98 99 #endif /* HAVE_SCANSTACK */ 100