Subversion Repositories Kolibri OS

Rev

Rev 6068 | Rev 6536 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.  * crtdll.c
  3.  * This file has no copyright assigned and is placed in the Public Domain.
  4.  * This file is a part of the mingw-runtime package.
  5.  * No warranty is given; refer to the file DISCLAIMER within the package.
  6.  *
  7.  * Source code for the shared libc startup proceedures. This code is compiled
  8.  * to make libc.dll, which should be located in the library path.
  9.  *
  10.  */
  11.  
  12. #include <_ansi.h>
  13. #include <reent.h>
  14. #include <stdint.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <stdio.h>
  18. #include <unistd.h>
  19. #include <setjmp.h>
  20. #include <sys/kos_io.h>
  21.  
  22. struct app_hdr
  23. {
  24.     char  banner[8];
  25.     int   version;
  26.     int   start;
  27.     int   iend;
  28.     int   memsize;
  29.     int   stacktop;
  30.     char  *cmdline;
  31.     char  *path;
  32.     int    __subsystem__;
  33.     void  *__idata_start;
  34.     void  *__idata_end;
  35.     int  (*main)(int argc, char **argv, char **envp);
  36. };
  37.  
  38. void _pei386_runtime_relocator (void);
  39. void init_loader(void *libc_image);
  40. void init_reent();
  41. void __init_conio();
  42. void __fini_conio();
  43. int link_app();
  44. void* get_entry_point(void *raw);
  45. int (*entry)(int, char **, char **);
  46.  
  47. char* __appenv;
  48. int   __appenv_size;
  49.  
  50. extern char _tls_map[128];
  51.  
  52. char * __libc_getenv(const char *name)
  53. {
  54.     return NULL;
  55. }
  56.  
  57. static int split_cmdline(char *cmdline, char **argv)
  58. {
  59.     enum quote_state
  60.     {
  61.         QUOTE_NONE,         /* no " active in current parm       */
  62.         QUOTE_DELIMITER,    /* " was first char and must be last */
  63.         QUOTE_STARTED       /* " was seen, look for a match      */
  64.     };
  65.  
  66.     enum quote_state state;
  67.     unsigned int argc;
  68.     char *p = cmdline;
  69.     char *new_arg, *start;
  70.  
  71.     argc = 0;
  72.  
  73.     for(;;)
  74.     {
  75.         /* skip over spaces and tabs */
  76.         if ( *p )
  77.         {
  78.             while (*p == ' ' || *p == '\t')
  79.                 ++p;
  80.         }
  81.  
  82.         if (*p == '\0')
  83.             break;
  84.  
  85.         state = QUOTE_NONE;
  86.         if( *p == '\"' )
  87.         {
  88.             p++;
  89.             state = QUOTE_DELIMITER;
  90.         }
  91.         new_arg = start = p;
  92.         for (;;)
  93.         {
  94.             if( *p == '\"' )
  95.             {
  96.                 p++;
  97.                 if( state == QUOTE_NONE )
  98.                 {
  99.                     state = QUOTE_STARTED;
  100.                 }
  101.                 else
  102.                 {
  103.                     state = QUOTE_NONE;
  104.                 }
  105.                 continue;
  106.             }
  107.  
  108.             if( *p == ' ' || *p == '\t' )
  109.             {
  110.                 if( state == QUOTE_NONE )
  111.                 {
  112.                     break;
  113.                 }
  114.             }
  115.  
  116.             if( *p == '\0' )
  117.                 break;
  118.  
  119.             if( *p == '\\' )
  120.             {
  121.                 if( p[1] == '\"' )
  122.                 {
  123.                     ++p;
  124.                     if( p[-2] == '\\' )
  125.                     {
  126.                         continue;
  127.                     }
  128.                 }
  129.             }
  130.             if( argv )
  131.             {
  132.                 *(new_arg++) = *p;
  133.             }
  134.             ++p;
  135.         };
  136.  
  137.         if( argv )
  138.         {
  139.             argv[ argc ] = start;
  140.             ++argc;
  141.  
  142.             /*
  143.               The *new = '\0' is req'd in case there was a \" to "
  144.               translation. It must be after the *p check against
  145.               '\0' because new and p could point to the same char
  146.               in which case the scan would be terminated too soon.
  147.             */
  148.  
  149.             if( *p == '\0' )
  150.             {
  151.                 *new_arg = '\0';
  152.                 break;
  153.             }
  154.             *new_arg = '\0';
  155.             ++p;
  156.         }
  157.         else
  158.         {
  159.             ++argc;
  160.             if( *p == '\0' )
  161.             {
  162.                 break;
  163.             }
  164.             ++p;
  165.         }
  166.     }
  167.  
  168.     return argc;
  169. };
  170.  
  171. void  __attribute__((noreturn))
  172. libc_crt_startup (void *libc_base)
  173. {
  174.     struct   app_hdr *header = NULL;
  175.     int retval = 0;
  176.  
  177.     char **argv;
  178.     int    argc;
  179.  
  180.     _pei386_runtime_relocator();
  181.  
  182.     memset(_tls_map, 0xFF, 32*4);
  183.     _tls_map[0] = 0xE0;
  184.     init_reent();
  185.     init_stdio();
  186.  
  187.     if(header->__subsystem__ == 3)
  188.         __init_conio();
  189.  
  190.     __do_global_ctors();
  191.  
  192.  //   __appenv = load_file("/sys/system.env", &__appenv_size);
  193.  
  194.     init_loader(libc_base);
  195.  
  196.     if( link_app() == 0)
  197.         goto done;
  198.  
  199.     if( header->cmdline[0] != 0)
  200.     {
  201.         argc = split_cmdline(header->cmdline, NULL) + 1;
  202.         argv = alloca((argc+1)*sizeof(char*));
  203.         argv[0] = header->path;
  204.  
  205.         split_cmdline(header->cmdline, argv + 1);
  206.     }
  207.     else
  208.     {
  209.         argc = 1;
  210.         argv = alloca((argc+1)*sizeof(char*));
  211.         argv[0] = header->path;
  212.     }
  213.     argv[argc] = NULL;
  214.  
  215.     retval = header->main(argc, argv, NULL);
  216. done:
  217.     if(header->__subsystem__ == 3)
  218.         __fini_conio();
  219.  
  220.     exit (retval);
  221. }
  222.  
  223.