"Fossies" - the Fresh Open Source Software Archive

Member "schily-2021-09-18/inc/avoffset.c" (28 Apr 2021, 5669 Bytes) of package /linux/privat/schily-2021-09-18.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "avoffset.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2021-08-14_vs_2021-09-18.

    1 /* @(#)avoffset.c   1.39 21/04/28 Copyright 1987, 1995-2021 J. Schilling */
    2 #include <schily/mconfig.h>
    3 #ifndef lint
    4 static  UConst char sccsid[] =
    5     "@(#)avoffset.c 1.39 21/04/28 Copyright 1987, 1995-2021 J. Schilling";
    6 #endif
    7 /*
    8  * This program is a tool to generate the file "avoffset.h".
    9  * It is used by functions that trace the stack to get to the top of the stack.
   10  *
   11  * It generates two defines:
   12  *  AV_OFFSET   - offset of argv relative to the main() frame pointer
   13  *  FP_INDIR    - number of stack frames above main()
   14  *            before encountering a NULL pointer.
   15  *
   16  *  Copyright (c) 1987, 1995-2021 J. Schilling
   17  */
   18 /*
   19  * The contents of this file are subject to the terms of the
   20  * Common Development and Distribution License, Version 1.0 only
   21  * (the "License").  You may not use this file except in compliance
   22  * with the License.
   23  *
   24  * See the file CDDL.Schily.txt in this distribution for details.
   25  * A copy of the CDDL is also available via the Internet at
   26  * http://www.opensource.org/licenses/cddl1.txt
   27  *
   28  * When distributing Covered Code, include this CDDL HEADER in each
   29  * file and include the License file CDDL.Schily.txt from this distribution.
   30  */
   31 
   32 #include <schily/stdio.h>
   33 #include <schily/standard.h>
   34 #include <schily/schily.h>
   35 #include <schily/stdlib.h>
   36 #include <schily/signal.h>
   37 
   38 #ifdef  HAVE_SCANSTACK
   39 #   include <schily/stkframe.h>
   40 #endif
   41 
   42 LOCAL   RETSIGTYPE  handler     __PR((int signo));
   43 EXPORT  int     main        __PR((int ac, char **av));
   44 LOCAL   int     stack_direction __PR((long *lp));
   45 
   46 LOCAL   RETSIGTYPE
   47 handler(signo)
   48     int signo;
   49 {
   50     fprintf(stderr, "Warning: Cannot scan stack on this environment.\n");
   51     fprintf(stderr, "This is not an error, we just disable stack scannig.\n");
   52 
   53     printf("\n#endif    /* __AVOFFSET_H */\n");
   54     fflush(stdout);
   55     exit(0);
   56 }
   57 
   58 
   59 int
   60 main(ac, av)
   61     int ac;
   62     char    **av;
   63 {
   64     int     stdir;
   65 #ifdef  HAVE_SCANSTACK
   66     volatile struct frame *fp;
   67     register int    i = 0;
   68     register int    o = 0;
   69 
   70     /*
   71      * As the SCO OpenServer C-Compiler has a bug that may cause
   72      * the first function call to getfp() been done before the
   73      * new stack frame is created, we call getfp() twice.
   74      */
   75     (void) getfp();
   76     fp = (struct frame *)getfp();
   77 #endif
   78 
   79 #ifdef  SIGBUS
   80     signal(SIGBUS, handler);
   81 #endif
   82     signal(SIGSEGV, handler);
   83 #ifdef  SIGILL
   84     signal(SIGILL, handler);    /* For gcc -m64/sparc on FreeBSD */
   85 #endif
   86 
   87     printf("/*\n");
   88     printf(" * This file has been generated automatically\n");
   89     printf(" * by %s\n", sccsid);
   90     printf(" * do not edit by hand.\n");
   91     printf(" *\n");
   92     printf(" * This file includes definitions for AV_OFFSET and FP_INDIR.\n");
   93     printf(" * FP_INDIR is the number of fp chain elements above 'main'.\n");
   94     printf(" * AV_OFFSET is the offset of &av[0] relative to the frame pointer in 'main'.\n");
   95     printf(" *\n");
   96     printf(" * If getav0() does not work on a specific architecture\n");
   97     printf(" * the program which generated this include file may dump core.\n");
   98     printf(" * In this case, the generated include file does not include\n");
   99     printf(" * definitions for AV_OFFSET and FP_INDIR but ends after this comment.\n");
  100     printf(" * If AV_OFFSET or FP_INDIR are missing in this file, all programs\n");
  101     printf(" * which use the definitions are automatically disabled.\n");
  102     printf(" */\n");
  103     printf("#ifndef __AVOFFSET_H\n");
  104     printf("#define __AVOFFSET_H\n\n");
  105 
  106     stdir = stack_direction(0);
  107     printf("#define STACK_DIRECTION %d\n", stdir);
  108     fflush(stdout);
  109 
  110 #ifdef  HAVE_SCANSTACK
  111     /*
  112      * Note: Scanning the stack to look for argc/argv
  113      *   works only in the main thread.
  114      *
  115      * llvm-gcc-4.2 has a bug and creates an endless loop if we call:
  116      *  while (fp->fr_savfp) {
  117      * We now try to limit this to 1000 loops in hope that the bug
  118      * does not affect the new code extended as well.
  119      */
  120     while (i <= 1000 && fp->fr_savfp) {
  121         /*
  122          * Workaround for the still buggy clang...
  123          * clang version 4.0.0 on ARM64 FreeBSD has become worse.
  124          * If we do not have the strange write() call, this loop
  125          * becomes an endless loop and the last line in the loop
  126          * is never touched.
  127          */
  128         write(-1, "", 0);
  129         if (fp->fr_savpc == 0)
  130             break;
  131 
  132         fp = (struct frame *)fp->fr_savfp;
  133 
  134         i++;
  135     }
  136     /*
  137      * Do not add any printf()'s before this line to allow avoffset
  138      * to abort without printing more than the comment above.
  139      */
  140     fp = (struct frame *)getfp();
  141     o = ((char *)av) - ((char *)fp);
  142     if ((o % sizeof (char *)) != 0) {
  143         fprintf(stderr, "AV_OFFSET value (%d) not a multiple of pointer size.\n", o);
  144         fprintf(stderr, "Disabling scanning the stack.\n");
  145 
  146         printf("\n#endif    /* __AVOFFSET_H */\n");
  147         exit(0);
  148     }
  149     if (o < -1000 || o > 1000) {
  150         fprintf(stderr, "AV_OFFSET value (%d) does not look reasonable.\n", o);
  151         fprintf(stderr, "Disabling scanning the stack.\n");
  152 
  153         printf("\n#endif    /* __AVOFFSET_H */\n");
  154         exit(0);
  155     }
  156     if (i > 1000) {
  157         fprintf(stderr, "FP_INDIR value (%d) does not look reasonable.\n", i);
  158         fprintf(stderr, "Disabling scanning the stack.\n");
  159 
  160         printf("\n#endif    /* __AVOFFSET_H */\n");
  161         exit(0);
  162     }
  163     printf("#define AV_OFFSET   %d\n", o);
  164     printf("#define FP_INDIR    %d\n", i);
  165 #endif
  166     printf("\n#endif    /* __AVOFFSET_H */\n");
  167     fflush(stdout);
  168     exit(0);
  169     return (0); /* keep lint happy */
  170 }
  171 
  172 #ifndef __NO_INL__
  173 #if __clang__ || (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 2)
  174 #define __NO_INL__  __attribute__((noinline))
  175 #else
  176 #define __NO_INL__
  177 #endif
  178 #endif
  179 
  180 LOCAL __NO_INL__ int
  181 stack_direction(lp)
  182     long    *lp;
  183 {
  184     auto long   *dummy[4];
  185     int     i;
  186 
  187     for (i = 0; i < 4; i++)
  188         dummy[i] = lp;
  189 
  190     if (lp == 0) {
  191         return (stack_direction((long *)dummy));
  192     } else {
  193         if ((long *)dummy == lp)
  194             return (0);
  195         return (((long *)dummy > lp) ? 1 : -1);
  196     }
  197 }
  198 
  199 #ifdef  HAVE_SCANSTACK
  200 #define IS_AVOFFSET
  201 #include "getfp.c"
  202 #endif