Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1906 serge 1
 
2
#include 
3
#include 
4
#include 
5
#include 
6
#include 
7
#include 
8
9
 
3805 Serge 10
1906 serge 11
 
12
#include "pe.h"
13
14
 
15
16
 
17
18
 
19
20
 
21
 
3809 Serge 22
void*   create_image(void *raw);
23
int     link_image(void *img_base, PIMAGE_IMPORT_DESCRIPTOR imp);
24
1906 serge 25
 
26
extern int   __appenv_size;
27
28
 
29
30
 
31
{
32
    char  banner[8];
33
    int   version;
34
    int   start;
35
    int   iend;
36
    int   memsize;
37
    int   stacktop;
38
    char  *cmdline;
39
    char  *path;
40
    int    reserved;
3805 Serge 41
    void  *__idata_start;
42
    void  *__idata_end;
43
    void  (*main)(int argc, char **argv, char **envp);
44
};
1906 serge 45
46
 
47
{
48
    struct list_head list;
49
50
 
51
    char       *img_path;
52
53
 
54
55
 
56
    uint32_t    end;
57
58
 
59
60
 
61
    PIMAGE_SECTION_HEADER    img_sec;
62
    PIMAGE_EXPORT_DIRECTORY  img_exp;
63
};
64
65
 
66
{
67
    struct list_head list;
68
    char *path;
69
    int   path_len;
70
}dll_path_t;
71
72
 
73
74
 
75
76
 
77
static char libc_name[] = "libc.dll";
78
static char libc_path[] = "/KolibriOS/lib/libc.dll";
3805 Serge 79
1906 serge 80
 
81
{
82
    if(val == 0)
83
        return 0;
84
    return (val & (val - 1)) == 0;
85
}
86
87
 
88
 
89
{
90
    PIMAGE_DOS_HEADER     dos;
91
    PIMAGE_NT_HEADERS32   nt;
92
93
 
94
95
 
96
        return 0;
97
98
 
99
        return 0;
100
101
 
102
103
 
104
        return 0;
105
106
 
107
        return 0;
108
109
 
110
        return 0;
111
112
 
113
        return 0;
114
115
 
116
        return 0;
117
118
 
119
        return 0;
120
121
 
122
    {
123
        if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment)
124
            return 0;
125
    }
126
    else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment)
127
        return 0;
128
129
 
130
       !IsPowerOf2(nt->OptionalHeader.FileAlignment))
131
        return 0;
132
133
 
134
        return 0;
135
136
 
137
}
138
139
 
140
 
3805 Serge 141
{
1906 serge 142
143
 
144
    PIMAGE_NT_HEADERS32      nt;
145
    PIMAGE_EXPORT_DIRECTORY  exp;
146
147
 
3809 Serge 148
    dll_path_t              *path;
149
150
 
3805 Serge 151
    dll_path_t *path;
1906 serge 152
    int len;
153
    char *p;
154
155
 
156
    {
157
        char *env;
158
        env = envz_get(__appenv, __appenv_size, "PATH");
159
        if( env )
160
        {
161
            while( *env )
162
            {
163
                p = env;
164
                while(*p)
165
                {
166
                    if( *p == 0x0D)
167
                        break;
168
                    else if( *p == 0x0A)
169
                        break;
170
                    else if( *p == ':')
171
                        break;
172
                    p++;
173
                };
174
                len = p-env;
175
                if(len)
176
                {
177
                    char *p1;
178
179
 
180
                    memcpy(p1, env, len);
181
                    p1[len]=0;
182
183
 
184
                    INIT_LIST_HEAD(&path->list);
185
                    path->path = p1;
186
                    path->path_len = len;
187
                    DBG("add libraries path %s\n", path->path);
188
                    list_add_tail(&path->list, &path_list);
189
                };
190
                if(*p == ':')
191
                {
192
                    env = p+1;
193
                    continue;
194
                }
195
                else break;
196
            };
197
        };
198
    };
199
200
 
201
202
 
203
    p = (char*)malloc(len+1);
204
    memcpy(p, header->path, len);
205
    p[len]=0;
206
207
 
208
    INIT_LIST_HEAD(&path->list);
209
    path->path = p;
210
    path->path_len = len;
211
    DBG("add libraries path %s\n", path->path);
212
    list_add_tail(&path->list, &path_list);
213
214
 
3809 Serge 215
1906 serge 216
 
217
    INIT_LIST_HEAD(&path->list);
218
    path->path = "/kolibrios/lib/";
3809 Serge 219
    path->path_len = 15;                           /* FIXME */
220
    DBG("add libraries path %s\n", path->path);
1906 serge 221
    list_add_tail(&path->list, &path_list);
222
223
 
224
225
 
226
    libc_dll.img_path = libc_path;
227
228
 
229
230
 
231
    nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
232
    exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY, libc_image,
233
                   nt->OptionalHeader.DataDirectory[0].VirtualAddress);
234
235
 
236
    libc_dll.end   = MakePtr(uint32_t,libc_image, nt->OptionalHeader.SizeOfImage);
237
238
 
239
    libc_dll.img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
240
    libc_dll.img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY,libc_image,
241
                        nt->OptionalHeader.DataDirectory[0].VirtualAddress);
242
243
 
244
245
 
246
{
247
    module_t* mod = &libc_dll;
3805 Serge 248
1906 serge 249
 
3805 Serge 250
    {
1906 serge 251
        if( !strncmp(name, mod->img_name, 16))
252
            return mod;
253
        mod = (module_t*)mod->list.next;
3805 Serge 254
    }while(mod != &libc_dll);
255
1906 serge 256
 
257
};
258
259
 
260
{
261
    __asm__ __volatile__ (
262
    "shrl $2, %%ecx         \n\t"
263
    "rep movsl"
264
    :
265
    :"c"(len),"S"(src),"D"(dst)
266
    :"cc");
267
    __asm__ __volatile__ (
268
    ""
269
    :::"ecx","esi","edi");
270
};
271
272
 
273
 
3809 Serge 274
{
1906 serge 275
    PIMAGE_DOS_HEADER     dos;
276
    PIMAGE_NT_HEADERS32   nt;
277
    PIMAGE_SECTION_HEADER img_sec;
278
279
 
280
    uint32_t  sec_align;
281
    int    i;
282
283
 
284
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
285
286
 
287
288
 
289
        return 0;
290
291
 
292
293
 
294
295
 
296
297
 
298
    {
299
        void *src_ptr;
300
        void *dest_ptr;
301
        size_t   sec_size;
302
303
 
304
        {
305
            src_ptr  = MakePtr(void*, raw, img_sec->PointerToRawData);
306
            dest_ptr = MakePtr(void*, img_base, img_sec->VirtualAddress);
307
            sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData);
308
        };
309
310
 
311
    };
312
313
 
314
    {
315
        PIMAGE_BASE_RELOCATION reloc;
316
317
 
318
319
 
320
                        nt->OptionalHeader.DataDirectory[5].VirtualAddress);
321
322
 
323
        {
324
            uint32_t  cnt;
325
            uint16_t *entry;
326
            uint16_t  reltype;
327
            uint32_t  offs;
328
329
 
330
            entry = MakePtr( uint16_t*, reloc, sizeof(*reloc) );
331
332
 
333
            {
334
                uint16_t *p16;
335
                uint32_t *p32;
336
337
 
338
                offs = (*entry & 0x0FFF) + reloc->VirtualAddress;
339
                switch(reltype)
340
                {
341
                    case 1:
342
                        p16 = MakePtr(uint16_t*, img_base, offs);
343
                        *p16+= (uint16_t)(delta>>16);
344
                        break;
345
                    case 2:
346
                        p16 = MakePtr(uint16_t*, img_base, offs);
347
                        *p16+= (uint16_t)delta;
348
                        break;
349
                    case 3:
350
                        p32 = MakePtr(uint32_t*, img_base, offs);
351
                        *p32+= delta;
352
                }
353
                entry++;
354
            }
355
            reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock);
356
        }
357
    };
358
    return img_base;
359
};
360
361
 
3809 Serge 362
//static loader_recursion;
363
3805 Serge 364
 
3809 Serge 365
{
1906 serge 366
    static jmp_buf loader_env;
367
    static recursion = -1;
368
    int warn = 0;
369
370
 
371
    if( !recursion )
372
    {
373
        if( unlikely(setjmp(loader_env) != 0))
374
        {
375
            recursion = -1;
376
            return 0;
377
        };
378
    };
379
380
 
3805 Serge 381
    {
382
        PIMAGE_DOS_HEADER        expdos;
383
        PIMAGE_NT_HEADERS32      expnt;
384
        PIMAGE_EXPORT_DIRECTORY  exp;
385
        PIMAGE_THUNK_DATA32      thunk;
386
387
 
388
        char       *libname;
389
        uint32_t   *exp_functions;
390
        uint16_t   *exp_ordinals;
391
        char      **exp_names;
392
393
 
394
395
 
3809 Serge 396
3805 Serge 397
 
398
399
 
400
        if(unlikely(api == NULL))
401
        {
402
            printf("library %s not found\n", libname);
403
            longjmp(loader_env, 1);
404
        }
405
406
 
3809 Serge 407
3805 Serge 408
 
409
        {
410
            thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->OriginalFirstThunk, img_base);
3809 Serge 411
        }
3805 Serge 412
        else
413
        {
414
            thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->FirstThunk, img_base);
3809 Serge 415
        };
3805 Serge 416
417
 
418
419
 
420
        exp_ordinals = MakePtr(uint16_t*,  exp->AddressOfNameOrdinals,api->start);
421
        exp_names = MakePtr(char**, exp->AddressOfNames,api->start);
422
423
 
424
        {
425
            PIMAGE_IMPORT_BY_NAME imp_name;
426
427
 
428
            {
429
//                ordinal = (*func_list) & 0x7fffffff;
430
//               *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->DllBase, Ordinal);
431
//                if ((*ImportAddressList) == NULL)
432
//                {
433
//                    DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
434
//                    RtlpRaiseImportNotFound(NULL, Ordinal, &ImportedModule->FullDllName);
435
//                    return STATUS_ENTRYPOINT_NOT_FOUND;
436
//                }
437
            }
438
            else
439
            {
440
                char *export_name;
441
                uint16_t   ordinal;
442
                void      *function;
443
                uint32_t   minn;
444
                uint32_t   maxn;
445
446
 
447
                              thunk->u1.AddressOfData, img_base);
3809 Serge 448
                *iat = NULL;
3805 Serge 449
450
 
451
452
 
453
                {
454
                    export_name = MakePtr(char*,exp_names[imp_name->Hint],
455
                                          api->start);
456
                    if(strcmp(imp_name->Name, export_name) == 0)
457
                    {
458
                        ordinal = exp_ordinals[imp_name->Hint];
459
                        function = MakePtr(void*,exp_functions[ordinal], api->start);
460
                        if((uint32_t)function >= (uint32_t)exp)
461
                        {
462
                            printf("forward %s\n", function);
463
                            warn=1;
464
                        }
465
                        else
466
                        {
467
                            DBG(" \t\tat %x\n", function);
468
                            *iat = function;
469
                        };
470
                        thunk++;  // Advance to next thunk
471
                        iat++;
472
                        continue;
473
                    };
474
                };
475
476
 
477
 
478
                maxn = exp->NumberOfNames - 1;
479
                while (minn <= maxn)
480
                {
481
                    int mid;
482
                    int res;
483
484
 
485
486
 
487
488
 
489
                    if (res == 0)
490
                    {
491
                        ordinal  = exp_ordinals[mid];
492
                        function = MakePtr(void*,exp_functions[ordinal], api->start);
493
494
 
495
                        {
496
                            printf("forward %s\n", function);
3809 Serge 497
                            warn=1;
3805 Serge 498
                        }
499
                        else
500
                        {
501
                            DBG(" \t\tat %x\n", function);
502
                            *iat = function;
503
                        };
504
                        break;
505
                    }
506
                    else if (minn == maxn)
507
                    {
508
                        printf(" unresolved %s\n",imp_name->Name);
509
                        warn=1;
510
                        break;
511
                    }
512
                    else if (res > 0)
513
                    {
514
                        maxn = mid - 1;
515
                    }
516
                    else
517
                    {
518
                        minn = mid + 1;
519
                    }
520
                };
521
            };
522
            thunk++;            // Advance to next thunk
523
            iat++;
524
        }
525
        imp++;  // advance to next IMAGE_IMPORT_DESCRIPTOR
526
    };
527
528
 
3809 Serge 529
530
 
3805 Serge 531
        return 1;
532
    else
533
        return 0;
534
}
535
536
 
3809 Serge 537
{
538
    struct app_hdr *header = NULL;
539
    PIMAGE_IMPORT_DESCRIPTOR imp;
540
3805 Serge 541
 
3809 Serge 542
3805 Serge 543
 
3809 Serge 544
545
 
546
547
 
548
 
1906 serge 549
{
550
    PIMAGE_DOS_HEADER     dos;
551
    PIMAGE_NT_HEADERS32   nt;
552
553
 
554
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
555
556
 
557
};
2040 serge 558
1906 serge 559
 
560
 
2040 serge 561
{
562
563
 
564
    PIMAGE_NT_HEADERS32      expnt;
565
    PIMAGE_EXPORT_DIRECTORY  exp;
566
567
 
568
    uint16_t   *exp_ordinals;
569
    char      **exp_names;
570
571
 
572
    char *export_name;
573
    uint16_t   ordinal;
574
    void *function=NULL;
575
576
 
577
578
 
579
    exp_ordinals = MakePtr(uint16_t*,  exp->AddressOfNameOrdinals,module->start);
580
    exp_names = MakePtr(char**, exp->AddressOfNames,module->start);
581
582
 
583
    maxn = exp->NumberOfNames - 1;
584
    while (minn <= maxn)
585
    {
586
        int mid;
587
        int res;
588
589
 
590
591
 
592
593
 
594
        if (res == 0)
595
        {
596
            ordinal  = exp_ordinals[mid];
597
            function = MakePtr(void*,exp_functions[ordinal], module->start);
598
599
 
600
            {
601
                printf("forward %s\n", function);
602
            }
603
            else
604
            {
605
                DBG(" \t\tat %x\n", function);
606
            };
607
            break;
608
        }
609
        else if (minn == maxn)
610
        {
611
            DBG(" unresolved %s\n",proc_name);
612
            break;
613
        }
614
        else if (res > 0)
615
        {
616
            maxn = mid - 1;
617
        }
618
        else
619
        {
620
            minn = mid + 1;
621
        }
622
    };
623
624
 
625
};
626
627
 
628
 
1906 serge 629
{
630
    dll_path_t *dllpath;
3809 Serge 631
1906 serge 632
 
3809 Serge 633
    int         len;
634
635
 
1906 serge 636
637
 
638
    {
639
        PIMAGE_DOS_HEADER        dos;
640
        PIMAGE_NT_HEADERS32      nt;
641
        PIMAGE_EXPORT_DIRECTORY  exp;
642
643
 
644
        ufile_t   uf;
3809 Serge 645
        void     *raw_img;
1906 serge 646
        size_t    raw_size;
647
        void     *img_base;
648
649
 
650
        memcpy(path, dllpath->path, dllpath->path_len);
651
652
 
653
        path[len+dllpath->path_len]=0;
654
655
 
3809 Serge 656
657
 
658
        raw_img  = uf.data;
659
        raw_size = uf.size;
660
661
 
1906 serge 662
            continue;
663
664
 
3809 Serge 665
 
1906 serge 666
        {
667
            printf("invalide module %s\n", path);
668
            user_free(raw_img);
669
            continue;
670
        };
671
672
 
673
        user_free(raw_img);
674
675
 
676
        {
677
            printf("cannot create image %s\n",path);
678
            continue;
679
        };
680
681
 
682
683
 
684
        {
685
            printf("%s epic fail: no enough memory\n",__FUNCTION__);
686
            user_free(img_base);
687
            return NULL;
3809 Serge 688
        }
1906 serge 689
690
 
691
692
 
693
        module->img_path = strdup(path);
694
        module->start    = img_base;
695
        module->entry    = get_entry_point(img_base);
696
        module->refcount = 1;
697
698
 
699
        nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
700
        exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
701
                   nt->OptionalHeader.DataDirectory[0].VirtualAddress);
702
703
 
704
705
 
706
        module->img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
707
        module->img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
708
                           nt->OptionalHeader.DataDirectory[0].VirtualAddress);
709
710
 
3805 Serge 711
1906 serge 712
 
3809 Serge 713
        {
2040 serge 714
            PIMAGE_IMPORT_DESCRIPTOR imp;
3809 Serge 715
            int (*dll_startup)(module_t *mod, uint32_t reason);
2040 serge 716
717
 
3809 Serge 718
                        nt->OptionalHeader.DataDirectory[1].VirtualAddress);
719
720
 
721
                return NULL;
722
723
 
2040 serge 724
            if( dll_startup )
725
                if( 0 == dll_startup(module, 1))
726
                    return NULL;
3809 Serge 727
        };
2040 serge 728
        return module;
3809 Serge 729
    };
1906 serge 730
    return NULL;
731
};
732