Subversion Repositories Kolibri OS

Rev

Rev 1066 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1066 Rev 2971
1
#include 
1
#include 
2
#include 
2
#include 
3
#include 
3
#include 
4
#include 
4
#include 
5
#include 
5
#include 
6
#include 
6
#include 
7
#include 
7
#include 
8
 
8
 
9
#pragma pack(push,4)
9
#pragma pack(push,4)
10
typedef struct
10
typedef struct
11
{
11
{
12
  char     app_name[16];
12
  char     app_name[16];
13
  addr_t   fpu_state;                       /*      +16       */
13
  addr_t   fpu_state;                       /*      +16       */
14
  count_t  ev_count;                        /*      +20       */
14
  count_t  ev_count;                        /*      +20       */
15
  addr_t   fpu_handler;                     /*      +24       */
15
  addr_t   fpu_handler;                     /*      +24       */
16
  addr_t   sse_handler;                     /*      +28       */
16
  addr_t   sse_handler;                     /*      +28       */
17
  addr_t   pl0_stack;                       /*      +32       */
17
  addr_t   pl0_stack;                       /*      +32       */
18
 
18
 
19
  addr_t   heap_base;                       /*      +36       */
19
  addr_t   heap_base;                       /*      +36       */
20
  addr_t   heap_top;                        /*      +40       */
20
  addr_t   heap_top;                        /*      +40       */
21
  addr_t   cursor;                          /*      +44       */
21
  addr_t   cursor;                          /*      +44       */
22
  addr_t   fd_ev;                           /*      +48       */
22
  addr_t   fd_ev;                           /*      +48       */
23
  addr_t   bk_ev;                           /*      +52       */
23
  addr_t   bk_ev;                           /*      +52       */
24
  addr_t   fd_obj;                          /*      +56       */
24
  addr_t   fd_obj;                          /*      +56       */
25
  addr_t   bk_obj;                          /*      +60       */
25
  addr_t   bk_obj;                          /*      +60       */
26
  addr_t   saved_esp;                       /*      +64       */
26
  addr_t   saved_esp;                       /*      +64       */
27
  addr_t   io_map[2];                       /*      +68       */
27
  addr_t   io_map[2];                       /*      +68       */
28
 
28
 
29
  u32_t    dbg_state;                       /*      +76       */
29
  u32_t    dbg_state;                       /*      +76       */
30
  char    *cur_dir;                         /*      +80       */
30
  char    *cur_dir;                         /*      +80       */
31
  count_t  wait_timeout;                    /*      +84       */
31
  count_t  wait_timeout;                    /*      +84       */
32
  addr_t   saved_esp0;                      /*      +88       */
32
  addr_t   saved_esp0;                      /*      +88       */
33
 
33
 
34
  link_t   dll_list;                        /*      +92       */
34
  link_t   dll_list;                        /*      +92       */
35
 
35
 
36
  u32_t    reserved0[7];                    /*      +100   db 28 dup(?)  */
36
  u32_t    reserved0[7];                    /*      +100   db 28 dup(?)  */
37
 
37
 
38
  addr_t   wnd_shape;                       /*      +128      */
38
  addr_t   wnd_shape;                       /*      +128      */
39
  u32_t    wnd_shape_scale;                 /*      +132      */
39
  u32_t    wnd_shape_scale;                 /*      +132      */
40
  u32_t    reserved1;                       /*      +136      */
40
  u32_t    reserved1;                       /*      +136      */
41
  size_t   mem_size;                        /*      +140      */
41
  size_t   mem_size;                        /*      +140      */
42
}appdata_t;
42
}appdata_t;
43
#pragma pack(pop)
43
#pragma pack(pop)
44
 
44
 
45
 
45
 
46
extern appdata_t *current_slot;
46
extern appdata_t *current_slot;
47
 
47
 
48
bool link_pe(addr_t img_base);
48
bool link_pe(addr_t img_base);
49
 
49
 
50
int __stdcall strncmp(const char *s1, const char *s2, size_t n);
50
int __stdcall strncmp(const char *s1, const char *s2, size_t n);
51
 
51
 
52
extern int __stdcall mnt_exec(void *raw, size_t raw_size, char *path,
52
extern int __stdcall mnt_exec(void *raw, size_t raw_size, char *path,
53
              char *cmdline, u32_t flags) asm ("mnt_exec");
53
              char *cmdline, u32_t flags) asm ("mnt_exec");
54
 
54
 
55
dll_t core_dll;
55
dll_t core_dll;
56
 
56
 
57
slab_cache_t *dll_slab;
57
slab_cache_t *dll_slab;
58
 
58
 
59
static char* strupr(char *str )
59
static char* strupr(char *str )
60
{
60
{
61
    char *p;
61
    char *p;
62
    unsigned char c;
62
    unsigned char c;
63
 
63
 
64
    p = str;
64
    p = str;
65
    while( (c = *p) )
65
    while( (c = *p) )
66
    {
66
    {
67
        if( c >= 'a' && c <= 'z' )
67
        if( c >= 'a' && c <= 'z' )
68
            *p = c - 'a' + 'A';
68
            *p = c - 'a' + 'A';
69
        ++p;
69
        ++p;
70
    }
70
    }
71
 
71
 
72
    return( str );
72
    return( str );
73
}
73
}
74
 
74
 
75
void * memcpy(void * _dest, const void *_src, size_t _n)
75
void * memcpy(void * _dest, const void *_src, size_t _n)
76
{
76
{
77
int d0, d1, d2;
77
int d0, d1, d2;
78
 __asm__ __volatile__(
78
 __asm__ __volatile__(
79
	"rep ; movsl\n\t"
79
	"rep ; movsl\n\t"
80
	"testb $2,%b4\n\t"
80
	"testb $2,%b4\n\t"
81
	"je 1f\n\t"
81
	"je 1f\n\t"
82
	"movsw\n"
82
	"movsw\n"
83
	"1:\ttestb $1,%b4\n\t"
83
	"1:\ttestb $1,%b4\n\t"
84
	"je 2f\n\t"
84
	"je 2f\n\t"
85
	"movsb\n"
85
	"movsb\n"
86
	"2:"
86
	"2:"
87
	: "=&c" (d0), "=&D" (d1), "=&S" (d2)
87
	: "=&c" (d0), "=&D" (d1), "=&S" (d2)
88
	:"0" (_n/4), "q" (_n),"1" ((long)_dest),"2" ((long)_src)
88
	:"0" (_n/4), "q" (_n),"1" ((long)_dest),"2" ((long)_src)
89
	: "memory");
89
	: "memory");
90
 return (_dest);
90
 return (_dest);
91
}
91
}
92
 
92
 
93
size_t strlen(const char *str)
93
size_t strlen(const char *str)
94
{
94
{
95
int d0;
95
int d0;
96
register int __res;
96
register int __res;
97
__asm__ __volatile__(
97
__asm__ __volatile__(
98
	"repne\n\t"
98
	"repne\n\t"
99
	"scasb\n\t"
99
	"scasb\n\t"
100
	"notl %0\n\t"
100
	"notl %0\n\t"
101
	"decl %0"
101
	"decl %0"
102
	:"=c" (__res), "=&D" (d0) :"1" (str),"a" (0), "0" (0xffffffff));
102
	:"=c" (__res), "=&D" (d0) :"1" (str),"a" (0), "0" (0xffffffff));
103
return __res;
103
return __res;
104
}
104
}
105
 
105
 
106
void init_core_dll()
106
void init_core_dll()
107
{
107
{
108
    PIMAGE_DOS_HEADER        dos;
108
    PIMAGE_DOS_HEADER        dos;
109
    PIMAGE_NT_HEADERS32      nt;
109
    PIMAGE_NT_HEADERS32      nt;
110
    PIMAGE_EXPORT_DIRECTORY  exp;
110
    PIMAGE_EXPORT_DIRECTORY  exp;
111
 
111
 
112
    dos =  (PIMAGE_DOS_HEADER)LOAD_BASE;
112
    dos =  (PIMAGE_DOS_HEADER)LOAD_BASE;
113
    nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
113
    nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
114
    exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
114
    exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
115
                   nt->OptionalHeader.DataDirectory[0].VirtualAddress);
115
                   nt->OptionalHeader.DataDirectory[0].VirtualAddress);
116
 
116
 
117
    list_initialize(&core_dll.link);
117
    list_initialize(&core_dll.link);
118
 
118
 
119
    core_dll.img_base = LOAD_BASE;
119
    core_dll.img_base = LOAD_BASE;
120
    core_dll.img_size = nt->OptionalHeader.SizeOfImage;
120
    core_dll.img_size = nt->OptionalHeader.SizeOfImage;
121
    core_dll.img_md   = NULL;
121
    core_dll.img_md   = NULL;
122
 
122
 
123
    core_dll.img_hdr  = nt;
123
    core_dll.img_hdr  = nt;
124
    core_dll.img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
124
    core_dll.img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
125
    core_dll.img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
125
    core_dll.img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY,LOAD_BASE,
126
                        nt->OptionalHeader.DataDirectory[0].VirtualAddress);
126
                        nt->OptionalHeader.DataDirectory[0].VirtualAddress);
127
    core_dll.img_name = strupr(MakePtr(char*, LOAD_BASE, exp->Name));
127
    core_dll.img_name = strupr(MakePtr(char*, LOAD_BASE, exp->Name));
128
 
128
 
129
    dll_slab = slab_cache_create(sizeof(dll_t), 16,NULL,NULL,SLAB_CACHE_MAGDEFERRED);
129
    dll_slab = slab_cache_create(sizeof(dll_t), 16,NULL,NULL,SLAB_CACHE_MAGDEFERRED);
130
 
130
 
131
    DBG("%s base %x size %x sections %d exports %x\n",
131
    DBG("%s base %x size %x sections %d exports %x\n",
132
        core_dll.img_name, core_dll.img_base,
132
        core_dll.img_name, core_dll.img_base,
133
        core_dll.img_size, nt->FileHeader.NumberOfSections,
133
        core_dll.img_size, nt->FileHeader.NumberOfSections,
134
        core_dll.img_exp );
134
        core_dll.img_exp );
135
};
135
};
136
 
136
 
137
 
137
 
138
dll_t * find_dll(link_t *list, const char *name)
138
dll_t * find_dll(link_t *list, const char *name)
139
{
139
{
140
    dll_t* dll = (dll_t*)list;
140
    dll_t* dll = (dll_t*)list;
141
 
141
 
142
    do
142
    do
143
    {
143
    {
144
        if( !strncmp(name,dll->img_name,16))
144
        if( !strncmp(name,dll->img_name,16))
145
            return dll;
145
            return dll;
146
 
146
 
147
        dll = (dll_t*)dll->link.next;
147
        dll = (dll_t*)dll->link.next;
148
 
148
 
149
    }while(&dll->link !=  list);
149
    }while(&dll->link !=  list);
150
 
150
 
151
    return NULL;
151
    return NULL;
152
};
152
};
153
 
153
 
154
 
154
 
155
typedef struct
155
typedef struct
156
{
156
{
157
  char         srv_name[16];  //        ASCIIZ string
157
  char         srv_name[16];  //        ASCIIZ string
158
  u32_t        magic;         // +0x10  'SRV '
158
  u32_t        magic;         // +0x10  'SRV '
159
  size_t       size;          // +0x14  size of structure SRV
159
  size_t       size;          // +0x14  size of structure SRV
160
  void        *fd;            // +0x18  next SRV descriptor
160
  void        *fd;            // +0x18  next SRV descriptor
161
  void        *bk;            // +0x1C  prev SRV descriptor
161
  void        *bk;            // +0x1C  prev SRV descriptor
162
  addr_t       base;          // +0x20  service base address
162
  addr_t       base;          // +0x20  service base address
163
  addr_t       entry;         // +0x24  service START function
163
  addr_t       entry;         // +0x24  service START function
164
  void        *srv_proc;      // +0x28  main service handler
164
  void        *srv_proc;      // +0x28  main service handler
165
}srv_t;
165
}srv_t;
166
 
166
 
167
typedef srv_t* __stdcall  drv_entry_t(int);
167
typedef srv_t* __stdcall  drv_entry_t(int);
168
 
168
 
169
srv_t* __fastcall load_pe_driver(const char *path)
169
srv_t* __fastcall load_pe_driver(const char *path)
170
{
170
{
171
    PIMAGE_DOS_HEADER     dos;
171
    PIMAGE_DOS_HEADER     dos;
172
    PIMAGE_NT_HEADERS32   nt;
172
    PIMAGE_NT_HEADERS32   nt;
173
 
173
 
174
    drv_entry_t   *drv_entry;
174
    drv_entry_t   *drv_entry;
175
    addr_t        *img_base ;
175
    addr_t        *img_base ;
176
    srv_t         *srv;
176
    srv_t         *srv;
177
 
177
 
178
    img_base = load_image(path);
178
    img_base = load_image(path);
179
 
179
 
180
    if( ! img_base )
180
    if( ! img_base )
181
        return 0;
181
        return 0;
182
 
182
 
183
    if( link_image( img_base ) )
183
    if( link_image( img_base ) )
184
    {
184
    {
185
        dos = (PIMAGE_DOS_HEADER)img_base;
185
        dos = (PIMAGE_DOS_HEADER)img_base;
186
        nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
186
        nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
187
 
187
 
188
        drv_entry = MakePtr(drv_entry_t*, img_base,
188
        drv_entry = MakePtr(drv_entry_t*, img_base,
189
                            nt->OptionalHeader.AddressOfEntryPoint);
189
                            nt->OptionalHeader.AddressOfEntryPoint);
190
 
190
 
191
        srv = drv_entry(1);
191
        srv = drv_entry(1);
192
 
192
 
193
        if(srv != NULL)
193
        if(srv != NULL)
194
            srv->entry = nt->OptionalHeader.AddressOfEntryPoint + img_base;
194
            srv->entry = nt->OptionalHeader.AddressOfEntryPoint + img_base;
195
 
195
 
196
        return srv;
196
        return srv;
197
    }
197
    }
198
    else
198
    else
199
    {
199
    {
200
        mem_free( img_base );
200
        mem_free( img_base );
201
        return NULL;
201
        return NULL;
202
    }
202
    }
203
}
203
}
204
 
204
 
205
typedef struct
205
typedef struct
206
{
206
{
207
    int a_type;
207
    int a_type;
208
    union
208
    union
209
    {
209
    {
210
        long  a_val;
210
        long  a_val;
211
        void *a_ptr;
211
        void *a_ptr;
212
        void  (*a_fcn)( ) ;
212
        void  (*a_fcn)( ) ;
213
    }a_un;
213
    }a_un;
214
}auxv_t;
214
}auxv_t;
215
 
215
 
216
#define AUX_COUNT       0
216
#define AUX_COUNT       0
217
 
217
 
218
typedef struct
218
typedef struct
219
{
219
{
220
    int     argc;       /*  always 2                                */
220
    int     argc;       /*  always 2                                */
221
    char   *path;       /*  argv[0]   program path                  */
221
    char   *path;       /*  argv[0]   program path                  */
222
    char   *cmdline;    /*  argv[1]   command  line. May be null    */
222
    char   *cmdline;    /*  argv[1]   command  line. May be null    */
223
    u32_t   sep1;       /*  separator.  must be zero                */
223
    u32_t   sep1;       /*  separator.  must be zero                */
224
    char   *env;        /*  single environment string               */
224
    char   *env;        /*  single environment string               */
225
    u32_t   sep2;       /*  separator.  must be zero                */
225
    u32_t   sep2;       /*  separator.  must be zero                */
226
    auxv_t  aux[1];     /*  aux. AT_NULL for now                    */
226
    auxv_t  aux[1];     /*  aux. AT_NULL for now                    */
227
}exec_stack_t;
227
}exec_stack_t;
228
 
228
 
229
 
229
 
230
addr_t __fastcall pe_app_space(size_t size);
230
addr_t __fastcall pe_app_space(size_t size);
231
 
231
 
232
int __stdcall pe_app_param(char *path, void *raw, addr_t ex_pg_dir,
232
int __stdcall pe_app_param(char *path, void *raw, addr_t ex_pg_dir,
233
                          exec_stack_t *ex_stack) asm ("pe_app_param");
233
                          exec_stack_t *ex_stack) asm ("pe_app_param");
234
 
234
 
235
int sys_exec(char *path, char *cmdline, u32_t flags)
235
int sys_exec(char *path, char *cmdline, u32_t flags)
236
{
236
{
237
    PIMAGE_DOS_HEADER     dos;
237
 
-
 
238
    PIMAGE_DOS_HEADER     dos;
238
    PIMAGE_NT_HEADERS32   nt;
239
    PIMAGE_NT_HEADERS32   nt;
239
 
240
 
240
    size_t   img_size;
241
    size_t   img_size;
241
    count_t  img_pages;
242
    count_t  img_pages;
242
    count_t  img_tabs;
243
    count_t  img_tabs;
243
    addr_t        ex_pg_dir;
244
 
-
 
245
    addr_t        ex_pg_dir;
244
    addr_t        ex_stack_page;
246
    addr_t        ex_stack_page;
245
    addr_t        ex_pl0_stack;
247
    addr_t        ex_pl0_stack;
246
 
248
 
247
    exec_stack_t *ex_stack;
249
    exec_stack_t *ex_stack;
248
    int           stack_size;
250
    int           stack_size;
249
    char         *ex_path;
251
    char         *ex_path;
250
    char         *ex_cmdline = NULL;
252
    char         *ex_cmdline = NULL;
251
 
253
 
252
    size_t        raw_size;
254
    size_t        raw_size;
253
    u32_t        *raw;
255
    u32_t        *raw;
254
 
256
 
255
    int pathsize = 0;
257
    int pathsize = 0;
256
    int cmdsize  = 0;
258
    int cmdsize  = 0;
257
    int envsize  = 0;
259
    int envsize  = 0;
258
 
260
 
259
    u32_t tmp;
261
    u32_t tmp;
260
 
262
 
261
    DBG("\nexec %s cmd %s flags %x\n", path, cmdline, flags);
263
    DBG("\nexec %s cmd %s flags %x\n", path, cmdline, flags);
262
 
264
 
263
    if( ! path)
265
    if( ! path)
264
    {
266
    {
265
        DBG("invalid path\n");
267
        DBG("invalid path\n");
266
        return;
268
        return;
267
    };
269
    };
268
 
270
 
269
    raw = load_file(path, &raw_size);
271
    raw = load_file(path, &raw_size);
270
 
272
 
271
    if( ! raw )
273
    if( ! raw )
272
        return -5;                                      /* FIXME */
274
        return -5;                                      /* FIXME */
273
 
275
 
274
    if( (raw[0] == 0x554E454D) &&
276
    if( (raw[0] == 0x554E454D) &&
275
        ( ( raw[1] == 0x31305445) ||
277
        ( ( raw[1] == 0x31305445) ||
276
          ( raw[1] == 0x30305445) ) )
278
          ( raw[1] == 0x30305445) ) )
277
 
279
 
278
    {
280
    {
279
        DBG("leagacy Kolibri application\n");
281
        DBG("leagacy Kolibri application\n");
280
        int tmp =  mnt_exec(raw, raw_size, path, cmdline, flags);
282
        int tmp =  mnt_exec(raw, raw_size, path, cmdline, flags);
281
        DBG("pid %x\n",tmp);
283
        DBG("pid %x\n",tmp);
282
        return tmp;
284
        return tmp;
283
    }
285
    }
284
 
286
 
285
    if( ! validate_pe(raw, raw_size, true) )
287
    if( ! validate_pe(raw, raw_size, true) )
286
    {
288
    {
287
        DBG("invalid executable file %s\n", path);
289
        DBG("invalid executable file %s\n", path);
288
        mem_free(raw);
290
        mem_free(raw);
289
        return -31;
291
        return -31;
290
    }
292
    }
291
 
293
 
292
    dos = (PIMAGE_DOS_HEADER)raw;
294
    dos = (PIMAGE_DOS_HEADER)raw;
293
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
295
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
294
 
296
 
295
    pathsize = strlen(path)+1;
297
    pathsize = strlen(path)+1;
296
 
298
 
297
    if( cmdline )
299
    if( cmdline )
298
        cmdsize = strlen(cmdline)+1;
300
        cmdsize = strlen(cmdline)+1;
299
 
301
 
300
    stack_size = sizeof(exec_stack_t) + pathsize +
302
    stack_size = sizeof(exec_stack_t) + pathsize +
301
                 cmdsize + envsize + AUX_COUNT*sizeof(auxv_t);
303
                 cmdsize + envsize + AUX_COUNT*sizeof(auxv_t);
302
 
304
 
303
    stack_size = (stack_size + 15) & ~15;               /* keep stack aligned */
305
    stack_size = (stack_size + 15) & ~15;               /* keep stack aligned */
304
 
306
 
305
    DBG("stacksize %d\n", stack_size);
307
    DBG("stacksize %d\n", stack_size);
306
 
308
 
307
    if( stack_size > 4096 )
309
    if( stack_size > 4096 )
308
    {
310
    {
309
        DBG("command line too long\n");
311
        DBG("command line too long\n");
310
        return -30;
312
        return -30;
311
    }
313
    }
312
 
314
 
313
    ex_stack_page  = alloc_page();                   /* 2^0 = 1 page   */
315
    ex_stack_page  = alloc_page();                   /* 2^0 = 1 page   */
314
    if( ! ex_stack_page )
316
    if( ! ex_stack_page )
315
    {
317
    {
316
        mem_free(raw);
318
        mem_free(raw);
317
        return -30;                                    /* FIXME          */
319
        return -30;                                    /* FIXME          */
318
    };
320
    };
319
 
321
 
320
    dos = (PIMAGE_DOS_HEADER)raw;
322
    dos = (PIMAGE_DOS_HEADER)raw;
321
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
323
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
322
 
324
 
323
    img_size  =  nt->OptionalHeader.SizeOfImage;
325
    img_size  =  nt->OptionalHeader.SizeOfImage;
324
 
326
 
325
    ex_pg_dir      = pe_app_space(img_size);
327
    ex_pg_dir      = pe_app_space(img_size);
326
 
328
 
327
    if( !ex_pg_dir )
329
    if( !ex_pg_dir )
328
    {
330
    {
329
        frame_free(ex_stack_page);
331
        frame_free(ex_stack_page);
330
        mem_free(raw);
332
        mem_free(raw);
331
        return -30;                                    /* FIXME          */
333
        return -30;                                    /* FIXME          */
332
    };
334
    };
333
 
335
 
334
    __asm__ __volatile__ (
336
    __asm__ __volatile__ (
335
    "xorl %%eax, %%eax      \n\t"
337
    "xorl %%eax, %%eax      \n\t"
336
    "rep stosl"
338
    "rep stosl"
337
    :"=c"(tmp),"=D"(tmp)
339
    :"=c"(tmp),"=D"(tmp)
338
    :"c"(1024),"D"(ex_stack_page + OS_BASE)
340
    :"c"(1024),"D"(ex_stack_page + OS_BASE)
339
    :"eax","cc");
341
    :"eax","cc");
340
 
342
 
341
    ex_stack = (exec_stack_t*)(ex_stack_page + OS_BASE
343
    ex_stack = (exec_stack_t*)(ex_stack_page + OS_BASE
342
                               + PAGE_SIZE - stack_size);
344
                               + PAGE_SIZE - stack_size);
343
    ex_stack->argc = 2;
345
    ex_stack->argc = 2;
344
 
346
 
345
    ex_path = MakePtr(char*, ex_stack, sizeof(exec_stack_t)+AUX_COUNT*sizeof(auxv_t));
347
    ex_path = MakePtr(char*, ex_stack, sizeof(exec_stack_t)+AUX_COUNT*sizeof(auxv_t));
346
 
348
 
347
    memcpy(ex_path, path, pathsize);
349
    memcpy(ex_path, path, pathsize);
348
    ex_stack->path = (char*)(((addr_t)ex_path & 0xFFF) + 0x7FFFF000);  /* top of stack */
350
    ex_stack->path = (char*)(((addr_t)ex_path & 0xFFF) + 0x7FFFF000);  /* top of stack */
349
 
351
 
350
    if( cmdline )
352
    if( cmdline )
351
    {
353
    {
352
        ex_cmdline = ex_path + pathsize;
354
        ex_cmdline = ex_path + pathsize;
353
        memcpy(ex_cmdline, cmdline, cmdsize);
355
        memcpy(ex_cmdline, cmdline, cmdsize);
354
        ex_stack->cmdline = ex_stack->path + pathsize;
356
        ex_stack->cmdline = ex_stack->path + pathsize;
355
    };
357
    };
356
 
358
 
357
/*
359
/*
358
    ex_stack.env = null
360
    ex_stack.env = null
359
    ex_stack.aux[0] = AT_NULL
361
    ex_stack.aux[0] = AT_NULL
360
 */
362
 */
361
 
363
 
362
    DBG("create stack at %x\n\tpath %x\n\tcmdline %x\n",
364
    DBG("create stack at %x\n\tpath %x\n\tcmdline %x\n",
363
         ex_stack, ex_stack->path, ex_stack->cmdline);
365
         ex_stack, ex_stack->path, ex_stack->cmdline);
364
 
366
 
365
    return pe_app_param(path, raw, ex_pg_dir, ex_stack);
367
    return pe_app_param(path, raw, ex_pg_dir, ex_stack);
366
};
368
};
367
 
369
 
368
 
370
 
369
typedef struct
371
typedef struct
370
{
372
{
371
    u32_t edi;
373
    u32_t edi;
372
    u32_t esi;
374
    u32_t esi;
373
    u32_t ebp;
375
    u32_t ebp;
374
    u32_t esp;
376
    u32_t esp;
375
    u32_t ebx;
377
    u32_t ebx;
376
    u32_t edx;
378
    u32_t edx;
377
    u32_t ecx;
379
    u32_t ecx;
378
    u32_t eax;
380
    u32_t eax;
379
    u32_t eip;
381
    u32_t eip;
380
    u32_t cs;
382
    u32_t cs;
381
    u32_t eflags;
383
    u32_t eflags;
382
    u32_t pe_sp;
384
    u32_t pe_sp;
383
    u32_t pe_ss;
385
    u32_t pe_ss;
384
}thr_stack_t;
386
}thr_stack_t;
385
 
387
 
386
void sys_app_entry(addr_t raw, thr_stack_t *thr_stack, exec_stack_t *ex_stack)
388
void sys_app_entry(addr_t raw, thr_stack_t *thr_stack, exec_stack_t *ex_stack)
387
{
389
{
388
    PIMAGE_DOS_HEADER     dos;
390
    PIMAGE_DOS_HEADER     dos;
389
    PIMAGE_NT_HEADERS32   nt;
391
    PIMAGE_NT_HEADERS32   nt;
390
 
392
 
391
    size_t   img_size;
393
    size_t   img_size;
392
    count_t  img_pages;
394
    count_t  img_pages;
393
    size_t   stack_size;
395
    size_t   stack_size;
394
    addr_t   img_stack;
396
    addr_t   img_stack;
395
    addr_t  *pte;
397
    addr_t  *pte;
396
 
398
 
397
    count_t  i;
399
    count_t  i;
398
    u32_t    tmp;
400
    u32_t    tmp;
399
 
401
 
400
    __asm__ __volatile__ ("sti");
402
    __asm__ __volatile__ ("sti");
401
 
403
 
402
    dos = (PIMAGE_DOS_HEADER)raw;
404
    dos = (PIMAGE_DOS_HEADER)raw;
403
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
405
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
404
 
406
 
405
    img_size  =  nt->OptionalHeader.SizeOfImage;
407
    img_size  =  nt->OptionalHeader.SizeOfImage;
406
 
408
 
407
    current_slot->mem_size  = img_size;
409
    current_slot->mem_size  = img_size;
408
 
410
 
409
    list_initialize(¤t_slot->dll_list);
411
    list_initialize(¤t_slot->dll_list);
410
 
412
 
411
    pte = (addr_t*)page_tabs;
413
    pte = (addr_t*)page_tabs;
412
    img_pages = img_size >> 12;
414
    img_pages = img_size >> 12;
413
 
415
 
414
    stack_size = (nt->OptionalHeader.SizeOfStackReserve + 4095) & ~4095;
416
    stack_size = (nt->OptionalHeader.SizeOfStackReserve + 4095) & ~4095;
415
    img_stack = 0x7FFFF000 - stack_size;
417
    img_stack = 0x7FFFF000 - stack_size;
416
    stack_size>>= 12;
418
    stack_size>>= 12;
417
 
419
 
418
    while (img_pages--)
420
    while (img_pages--)
419
        *pte++ = 2;
421
        *pte++ = 2;
420
 
422
 
421
    pte = &((addr_t*)page_tabs)[img_stack>>12];
423
    pte = &((addr_t*)page_tabs)[img_stack>>12];
422
 
424
 
423
    while(stack_size--)
425
    while(stack_size--)
424
        *pte++ = 0x02;
426
        *pte++ = 0x02;
425
 
427
 
426
    addr_t stack_page = ((addr_t)ex_stack-OS_BASE) & ~4095;
428
    addr_t stack_page = ((addr_t)ex_stack-OS_BASE) & ~4095;
427
 
429
 
428
    *pte = stack_page | 7;
430
    *pte = stack_page | 7;
429
 
431
 
430
    create_image(0, raw, false);
432
    create_image(0, raw, false);
431
 
433
 
432
    init_user_heap();
434
    init_user_heap();
433
 
435
 
434
    if (! link_pe(0))
436
    if (! link_pe(0))
435
    {
437
    {
436
        DBG("\nunresolved imports\nexit\n");
438
        DBG("\nunresolved imports\nexit\n");
437
        __asm__ __volatile__ (
439
        __asm__ __volatile__ (
438
        "int $0x40"::"a"(-1));
440
        "int $0x40"::"a"(-1));
439
    };
441
    };
440
 
442
 
441
 
443
 
442
 //   __asm__ __volatile__ (
444
 //   __asm__ __volatile__ (
443
 //   "xchgw %bx, %bx");
445
 //   "xchgw %bx, %bx");
444
 
446
 
445
    addr_t entry = nt->OptionalHeader.AddressOfEntryPoint +
447
    addr_t entry = nt->OptionalHeader.AddressOfEntryPoint +
446
                   nt->OptionalHeader.ImageBase;
448
                   nt->OptionalHeader.ImageBase;
447
 
449
 
448
    thr_stack->edi = 0;
450
    thr_stack->edi = 0;
449
    thr_stack->esi = 0;
451
    thr_stack->esi = 0;
450
    thr_stack->ebp = 0;
452
    thr_stack->ebp = 0;
451
    thr_stack->ebx = 0;
453
    thr_stack->ebx = 0;
452
    thr_stack->edx = 0;
454
    thr_stack->edx = 0;
453
    thr_stack->ecx = 0;
455
    thr_stack->ecx = 0;
454
    thr_stack->eax = 0;
456
    thr_stack->eax = 0;
455
    thr_stack->eip = entry;
457
    thr_stack->eip = entry;
456
    thr_stack->cs  = sel_app_code;
458
    thr_stack->cs  = sel_app_code;
457
    thr_stack->eflags = EFL_IOPL3 | EFL_IF;
459
    thr_stack->eflags = EFL_IOPL3 | EFL_IF;
458
    thr_stack->pe_sp = 0x7FFFF000 + ((u32_t)ex_stack & 0xFFF);
460
    thr_stack->pe_sp = 0x7FFFF000 + ((u32_t)ex_stack & 0xFFF);
459
    thr_stack->pe_ss = sel_app_data;
461
    thr_stack->pe_ss = sel_app_data;
460
 
462
 
461
};
463
};
462
 
464
 
463
void* __stdcall user_alloc(size_t size) asm("user_alloc");
465
void* __stdcall user_alloc(size_t size) asm("user_alloc");
464
void  __stdcall user_free(void *mem) asm("user_free");
466
void  __stdcall user_free(void *mem) asm("user_free");
465
 
467
 
466
dll_t* __fastcall load_dll(const char *path)
468
dll_t* __fastcall load_dll(const char *path)
467
{
469
{
468
    PIMAGE_DOS_HEADER        dos;
470
    PIMAGE_DOS_HEADER        dos;
469
    PIMAGE_NT_HEADERS32      nt;
471
    PIMAGE_NT_HEADERS32      nt;
470
    PIMAGE_EXPORT_DIRECTORY  exp;
472
    PIMAGE_EXPORT_DIRECTORY  exp;
471
 
473
 
472
    md_t    *img_md;
474
    md_t    *img_md;
473
 
475
 
474
    size_t   img_size;
476
    size_t   img_size;
475
    addr_t   img_base;
477
    addr_t   img_base;
476
    count_t  img_pages;
478
    count_t  img_pages;
477
 
479
 
478
    size_t   raw_size = 0;
480
    size_t   raw_size = 0;
479
    void    *raw;
481
    void    *raw;
480
 
482
 
481
    DBG("\nload dll %s", path);
483
    DBG("\nload dll %s", path);
482
 
484
 
483
    raw = load_file(path, &raw_size);
485
    raw = load_file(path, &raw_size);
484
 
486
 
485
    DBG("  raw = %x\n", raw);
487
    DBG("  raw = %x\n", raw);
486
 
488
 
487
    if( ! raw)
489
    if( ! raw)
488
    {
490
    {
489
        DBG("file not found: %s\n", path);
491
        DBG("file not found: %s\n", path);
490
        return NULL;
492
        return NULL;
491
    };
493
    };
492
 
494
 
493
    if( ! validate_pe(raw, raw_size, false) )
495
    if( ! validate_pe(raw, raw_size, false) )
494
    {
496
    {
495
        DBG("invalid pe file %s\n", path);
497
        DBG("invalid pe file %s\n", path);
496
        mem_free(raw);
498
        mem_free(raw);
497
        return NULL;
499
        return NULL;
498
    }
500
    }
499
 
501
 
500
    dos = (PIMAGE_DOS_HEADER)raw;
502
    dos = (PIMAGE_DOS_HEADER)raw;
501
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
503
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
502
 
504
 
503
    img_size  =  nt->OptionalHeader.SizeOfImage;
505
    img_size  =  nt->OptionalHeader.SizeOfImage;
504
 
506
 
505
    img_base = (addr_t)user_alloc(img_size);
507
    img_base = (addr_t)user_alloc(img_size);
506
    if( !img_base)
508
    if( !img_base)
507
    {
509
    {
508
        mem_free(raw);
510
        mem_free(raw);
509
        return NULL;
511
        return NULL;
510
    };
512
    };
511
 
513
 
512
    dll_t *dll = (dll_t*)slab_alloc(dll_slab,0);         /* FIXME check */
514
    dll_t *dll = (dll_t*)slab_alloc(dll_slab,0);         /* FIXME check */
513
    if( !dll)
515
    if( !dll)
514
    {
516
    {
515
        mem_free(raw);
517
        mem_free(raw);
516
        user_free((void*)img_base);
518
        user_free((void*)img_base);
517
        return NULL;
519
        return NULL;
518
    };
520
    };
519
 
521
 
520
    create_image(img_base, (addr_t)raw, false);
522
    create_image(img_base, (addr_t)raw, false);
521
 
523
 
522
    mem_free(raw);
524
    mem_free(raw);
523
 
525
 
524
    dos = (PIMAGE_DOS_HEADER)img_base;
526
    dos = (PIMAGE_DOS_HEADER)img_base;
525
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
527
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
526
    exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY,img_base,
528
    exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY,img_base,
527
                   nt->OptionalHeader.DataDirectory[0].VirtualAddress);
529
                   nt->OptionalHeader.DataDirectory[0].VirtualAddress);
528
 
530
 
529
    dll->img_base = img_base;
531
    dll->img_base = img_base;
530
    dll->img_size = nt->OptionalHeader.SizeOfImage;
532
    dll->img_size = nt->OptionalHeader.SizeOfImage;
531
    dll->img_md   = NULL;
533
    dll->img_md   = NULL;
532
 
534
 
533
    dll->img_hdr  = nt;
535
    dll->img_hdr  = nt;
534
    dll->img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
536
    dll->img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
535
    dll->img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY,img_base,
537
    dll->img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY,img_base,
536
                            nt->OptionalHeader.DataDirectory[0].VirtualAddress);
538
                            nt->OptionalHeader.DataDirectory[0].VirtualAddress);
537
    dll->img_name = strupr(MakePtr(char*, img_base, exp->Name));
539
    dll->img_name = strupr(MakePtr(char*, img_base, exp->Name));
538
 
540
 
539
    list_insert(¤t_slot->dll_list, &dll->link);
541
    list_insert(¤t_slot->dll_list, &dll->link);
540
 
542
 
541
    return dll;
543
    return dll;
542
};
544
};
543
 
545
 
544
bool link_pe(addr_t img_base)
546
bool link_pe(addr_t img_base)
545
{
547
{
546
    PIMAGE_DOS_HEADER     dos;
548
    PIMAGE_DOS_HEADER     dos;
547
    PIMAGE_NT_HEADERS32   nt;
549
    PIMAGE_NT_HEADERS32   nt;
548
    char path[128];
550
    char path[128];
549
 
551
 
550
    int warn = 0;
552
    int warn = 0;
551
 
553
 
552
/* assumed that image is valid */
554
/* assumed that image is valid */
553
 
555
 
554
    dos = (PIMAGE_DOS_HEADER)img_base;
556
    dos = (PIMAGE_DOS_HEADER)img_base;
555
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
557
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
556
 
558
 
557
    if(nt->OptionalHeader.DataDirectory[1].Size)
559
    if(nt->OptionalHeader.DataDirectory[1].Size)
558
    {
560
    {
559
        PIMAGE_IMPORT_DESCRIPTOR imp;
561
        PIMAGE_IMPORT_DESCRIPTOR imp;
560
 
562
 
561
        imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base,
563
        imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base,
562
                      nt->OptionalHeader.DataDirectory[1].VirtualAddress);
564
                      nt->OptionalHeader.DataDirectory[1].VirtualAddress);
563
 
565
 
564
        while ( 1 )
566
        while ( 1 )
565
        {
567
        {
566
            PIMAGE_THUNK_DATA32     thunk;
568
            PIMAGE_THUNK_DATA32     thunk;
567
 
569
 
568
            PIMAGE_DOS_HEADER       expdos;
570
            PIMAGE_DOS_HEADER       expdos;
569
            PIMAGE_NT_HEADERS32     expnt;
571
            PIMAGE_NT_HEADERS32     expnt;
570
            PIMAGE_EXPORT_DIRECTORY exp;
572
            PIMAGE_EXPORT_DIRECTORY exp;
571
 
573
 
572
            u32_t   *iat;
574
            u32_t   *iat;
573
            char    *libname;
575
            char    *libname;
574
            addr_t  *functions;
576
            addr_t  *functions;
575
            u16_t   *ordinals;
577
            u16_t   *ordinals;
576
            char   **funcname;
578
            char   **funcname;
577
 
579
 
578
            dll_t   *exp_dll;
580
            dll_t   *exp_dll;
579
 
581
 
580
            if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) )
582
            if ( (imp->TimeDateStamp==0 ) && (imp->Name==0) )
581
                break;
583
                break;
582
 
584
 
583
            libname=MakePtr(char*,imp->Name, img_base);
585
            libname=MakePtr(char*,imp->Name, img_base);
584
 
586
 
585
            DBG("import from %s\n",libname);
587
            DBG("import from %s\n",libname);
586
 
588
 
587
            exp_dll = find_dll(&core_dll.link, libname);
589
            exp_dll = find_dll(&core_dll.link, libname);
588
            if(exp_dll == NULL)
590
            if(exp_dll == NULL)
589
            {
591
            {
590
            exp_dll = find_dll(¤t_slot->dll_list, libname);
592
 
-
 
593
            exp_dll = find_dll(¤t_slot->dll_list, libname);
591
                if(exp_dll == NULL)
594
                if(exp_dll == NULL)
592
            {
595
            {
593
                int len = strlen(libname)+1;
596
                int len = strlen(libname)+1;
594
 
597
 
595
                memcpy(path, "/sys/lib/",9);
598
                memcpy(path, "/sys/lib/",9);
596
                memcpy(&path[9],libname,len);
599
                memcpy(&path[9],libname,len);
597
 
600
 
598
                exp_dll = load_dll(path);
601
                exp_dll = load_dll(path);
599
                if( !exp_dll)
602
                if( !exp_dll)
600
                {
603
                {
601
                    DBG("can't load %s\n", path);
604
                    DBG("can't load %s\n", path);
602
                    return false;
605
                    return false;
603
                };
606
                };
604
            }
607
            }
605
            };
608
            };
606
            DBG("find %s\n", exp_dll->img_name);
609
            DBG("find %s\n", exp_dll->img_name);
607
 
610
 
608
            exp = exp_dll->img_exp;
611
            exp = exp_dll->img_exp;
609
 
612
 
610
            functions = MakePtr(DWORD*,exp->AddressOfFunctions,exp_dll->img_base);
613
            functions = MakePtr(DWORD*,exp->AddressOfFunctions,exp_dll->img_base);
611
            ordinals = MakePtr(WORD*,  exp->AddressOfNameOrdinals,exp_dll->img_base);
614
            ordinals = MakePtr(WORD*,  exp->AddressOfNameOrdinals,exp_dll->img_base);
612
            funcname = MakePtr(char**, exp->AddressOfNames,exp_dll->img_base);
615
            funcname = MakePtr(char**, exp->AddressOfNames,exp_dll->img_base);
613
 
616
 
614
            thunk = MakePtr(PIMAGE_THUNK_DATA32,
617
            thunk = MakePtr(PIMAGE_THUNK_DATA32,
615
                            imp->Characteristics, img_base);
618
                            imp->Characteristics, img_base);
616
            iat= MakePtr(DWORD*,imp->FirstThunk, img_base);
619
            iat= MakePtr(DWORD*,imp->FirstThunk, img_base);
617
 
620
 
618
            while ( 1 ) // Loop forever (or until we break out)
621
            while ( 1 ) // Loop forever (or until we break out)
619
            {
622
            {
620
                PIMAGE_IMPORT_BY_NAME ord;
623
                PIMAGE_IMPORT_BY_NAME ord;
621
                addr_t addr;
624
                addr_t addr;
622
                *iat=0;
625
                *iat=0;
623
 
626
 
624
                if ( thunk->u1.AddressOfData == 0 )
627
                if ( thunk->u1.AddressOfData == 0 )
625
                    break;
628
                    break;
626
 
629
 
627
                if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
630
                if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
628
                {
631
                {
629
                   u16_t ordinal;
632
                   u16_t ordinal;
630
                   ordinal = thunk->u1.Ordinal & 0xFFFF;
633
                   ordinal = thunk->u1.Ordinal & 0xFFFF;
631
                   *iat = functions[ordinal-exp->Base] + exp_dll->img_base;
634
                   *iat = functions[ordinal-exp->Base] + exp_dll->img_base;
632
                    break;
635
                    break;
633
                }
636
                }
634
                else
637
                else
635
                {
638
                {
636
                    ord = MakePtr(PIMAGE_IMPORT_BY_NAME,
639
                    ord = MakePtr(PIMAGE_IMPORT_BY_NAME,
637
                                  thunk->u1.AddressOfData, img_base);
640
                                  thunk->u1.AddressOfData, img_base);
638
 
641
 
639
                    DBG("import %s ", ord->Name);
642
                    DBG("import %s ", ord->Name);
640
 
643
 
641
                    if(strncmp(ord->Name,
644
                    if(strncmp(ord->Name,
642
                       MakePtr(char*,funcname[ord->Hint],exp_dll->img_base),32))
645
                       MakePtr(char*,funcname[ord->Hint],exp_dll->img_base),32))
643
                    {
646
                    {
644
                        int ind;
647
                        int ind;
645
                        char **names=funcname;
648
                        char **names=funcname;
646
 
649
 
647
                        for(names = funcname,ind = 0;
650
                        for(names = funcname,ind = 0;
648
                            ind < exp->NumberOfNames; names++,ind++)
651
                            ind < exp->NumberOfNames; names++,ind++)
649
                        {
652
                        {
650
                            if(!strncmp(ord->Name,MakePtr(char*,*names,exp_dll->img_base),32))
653
                            if(!strncmp(ord->Name,MakePtr(char*,*names,exp_dll->img_base),32))
651
                            {
654
                            {
652
                                u16_t ordinal;
655
                                u16_t ordinal;
653
                                ordinal = ordinals[ind];
656
                                ordinal = ordinals[ind];
654
                                DBG("ordinal %d\t\tat %x\n", ordinal, functions[ordinal] + exp_dll->img_base);
657
                                DBG("ordinal %d\t\tat %x\n", ordinal, functions[ordinal] + exp_dll->img_base);
655
                                *iat = functions[ordinal] + exp_dll->img_base;
658
                                *iat = functions[ordinal] + exp_dll->img_base;
656
                                break;
659
                                break;
657
                            };
660
                            };
658
                        };
661
                        };
659
                        if(ind == exp->NumberOfNames)
662
                        if(ind == exp->NumberOfNames)
660
                        {
663
                        {
661
                            DBG(" unresolved import %s\n",ord->Name);
664
                            DBG(" unresolved import %s\n",ord->Name);
662
                            warn=1;
665
                            warn=1;
663
                        };
666
                        };
664
                    }
667
                    }
665
                    else
668
                    else
666
                    {
669
                    {
667
                        DBG(" \tat %x\n", functions[ord->Hint] + exp_dll->img_base);
670
                        DBG(" \tat %x\n", functions[ord->Hint] + exp_dll->img_base);
668
                        *iat = functions[ord->Hint] + exp_dll->img_base;
671
                        *iat = functions[ord->Hint] + exp_dll->img_base;
669
                    };
672
                    };
670
                };
673
                };
671
                thunk++;            // Advance to next thunk
674
                thunk++;            // Advance to next thunk
672
                iat++;
675
                iat++;
673
            }
676
            }
674
            imp++;  // advance to next IMAGE_IMPORT_DESCRIPTOR
677
            imp++;  // advance to next IMAGE_IMPORT_DESCRIPTOR
675
        };
678
        };
676
    };
679
    };
677
 
680
 
678
    if ( !warn )
681
    if ( !warn )
679
        return true;
682
        return true;
680
    else
683
    else
681
        return false;
684
        return false;
682
}
685
}