Subversion Repositories Kolibri OS

Rev

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

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