"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.

    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