(root)/
gcc-13.2.0/
libgcc/
config/
vms/
vms-ucrt0.c
       1  /* VMS crt0 returning Unix style condition codes.
       2     Copyright (C) 2001-2023 Free Software Foundation, Inc.
       3     Contributed by Douglas B. Rupp (rupp@gnat.com).
       4  
       5     This file is part of GCC.
       6  
       7     GCC is free software; you can redistribute it and/or modify
       8     it under the terms of the GNU General Public License as published by
       9     the Free Software Foundation; either version 3, or (at your option)
      10     any later version.
      11  
      12     GCC is distributed in the hope that it will be useful,
      13     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15     GNU General Public License for more details.
      16  
      17     Under Section 7 of GPL version 3, you are granted additional
      18     permissions described in the GCC Runtime Library Exception, version
      19     3.1, as published by the Free Software Foundation.
      20  
      21     You should have received a copy of the GNU General Public License and
      22     a copy of the GCC Runtime Library Exception along with this program;
      23     see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      24     <http://www.gnu.org/licenses/>.  */
      25  
      26  #include <stdlib.h>
      27  
      28  /* Sanity check.  */
      29  #if __INITIAL_POINTER_SIZE != 64
      30  #error "vms-ucrt0.c must be compiled with -mpointer-size=64"
      31  #endif
      32  
      33  /* Lots of cheat to handle 32bits/64bits pointer conversions.
      34     We use 'long long' for 64 bits pointers and 'int' for 32 bits pointers.  */
      35  
      36  extern void decc$main (void *, void *, void *, void *, unsigned int,
      37  		       unsigned int, int *, int *, int *);
      38  extern int main (int, char **, char **);
      39  extern int _malloc32 (int);
      40  
      41  #ifdef __ia64__
      42  #define MAIN_ASM_NAME asm ("ELF$TFRADR")
      43  #else
      44  #define MAIN_ASM_NAME
      45  #endif
      46  
      47  int __main (void *, void *, void *, void *,
      48  	    unsigned int, unsigned int) MAIN_ASM_NAME;
      49  
      50  /* From errnodef.h, but we need to emulate the globalval.  */
      51  extern int C$_EXIT1;
      52  
      53  /* From stsdef.h  */
      54  #define STS$V_MSG_NO 0x03
      55  #define STS$M_INHIB_MSG 0x10000000
      56  /* Symbol defined while main() is compiled to record the flags used.
      57     (Note that the symbol defines the value, ie extract the bits from the
      58      address).
      59     bit 0 set for 64 bit pointers
      60     bit 1 set for posix return value.  */
      61  extern char __gcc_main_flags;
      62  
      63  /* From ssdef.h  */
      64  #define SS$_NORMAL 1
      65  #define MAIN_FLAG_64BIT (1 << 0)
      66  #define MAIN_FLAG_POSIX (1 << 1)
      67  
      68  int
      69  __main (void *progxfer, void *cli_util, void *imghdr, void *image_file_desc,
      70  	unsigned int linkflag, unsigned int cliflag)
      71  {
      72    int argc;
      73    int argv;
      74    int envp;
      75    int status;
      76    char **argv64;
      77    char **envp64;
      78    unsigned int flags = (unsigned __int64)&__gcc_main_flags;
      79  
      80    /* The argv and envp arrays are 32 bits pointers to 32 bits pointers.  */
      81    decc$main (progxfer, cli_util, imghdr, image_file_desc,
      82  	     linkflag, cliflag, &argc, &argv, &envp);
      83  
      84    if (flags & MAIN_FLAG_64BIT)
      85      {
      86        int i;
      87  
      88        /* Reallocate argv and envp with 64 bit pointers.  */
      89        argv64 = (char **) _malloc32 (sizeof (char *) * (argc + 1));
      90  
      91        for (i = 0; i < argc; i++)
      92          argv64[i] = (char *) (__int64)(((int *) (__int64) argv)[i]);
      93  
      94        argv64[argc] = NULL;
      95  
      96        for (i = 0; ((int *) (__int64) envp)[i]; i++)
      97          ;
      98        envp64 = (char **) _malloc32 (sizeof (char *) * (i + 1));
      99  
     100        for (i = 0; ((int *) (__int64) envp)[i]; i++)
     101          envp64[i] = (char *)(__int64)(((int *) (__int64) envp)[i]);
     102  
     103        envp64[i] = NULL;
     104      }
     105    else
     106      {
     107        argv64 = (char **)(__int64)argv;
     108        envp64 = (char **)(__int64)envp;
     109      }
     110  
     111    status = main (argc, argv64, envp64);
     112  
     113    if (flags & MAIN_FLAG_POSIX)
     114      {
     115        /* Map into a range of 0 - 255.  */
     116        status &= 255;
     117  
     118        if (status != 0)
     119  	{
     120  	  int save_status = status;
     121  
     122  	  status = (__int64) &C$_EXIT1 + ((status - 1) << STS$V_MSG_NO);
     123  
     124  	  /* An exit failure status requires a "severe" error.  All
     125  	     status values are defined in errno with a successful (1)
     126  	     severity but can be changed to an error (2) severity by
     127  	     adding 1.  In addition for compatibility with UNIX exit()
     128  	     routines we inhibit a run-time error message from being
     129  	     generated on exit(1).  */
     130  
     131  	  if (save_status == 1)
     132  	    {
     133  	      status++;
     134  	      status |= STS$M_INHIB_MSG;
     135  	    }
     136  	}
     137        else
     138  	status = SS$_NORMAL;
     139      }
     140  
     141    return status;
     142  }