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