Subversion Repositories Kolibri OS

Rev

Rev 5198 | Rev 6074 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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