Subversion Repositories Kolibri OS

Rev

Rev 3799 | 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
 
3805 Serge 22
void*     __fastcall create_image(void *raw);
1906 serge 23
int       __fastcall link_image(void *img_base);
24
int       __fastcall do_exec(uint32_t my_app, uint32_t *params);
25
26
 
27
 
28
extern int   __appenv_size;
29
30
 
31
32
 
33
{
34
    char  banner[8];
35
    int   version;
36
    int   start;
37
    int   iend;
38
    int   memsize;
39
    int   stacktop;
40
    char  *cmdline;
41
    char  *path;
42
    int    reserved;
3805 Serge 43
    void  *__idata_start;
44
    void  *__idata_end;
45
    void  (*main)(int argc, char **argv, char **envp);
46
};
1906 serge 47
48
 
49
{
50
    struct list_head list;
51
52
 
53
    char       *img_path;
54
55
 
56
57
 
58
    uint32_t    end;
59
60
 
61
62
 
63
    PIMAGE_SECTION_HEADER    img_sec;
64
    PIMAGE_EXPORT_DIRECTORY  img_exp;
65
};
66
67
 
68
{
69
    struct list_head list;
70
    char *path;
71
    int   path_len;
72
}dll_path_t;
73
74
 
75
76
 
77
78
 
79
static char libc_name[] = "libc.dll";
80
static char libc_path[] = "/KolibriOS/lib/libc.dll";
3805 Serge 81
1906 serge 82
 
83
{
84
    if(val == 0)
85
        return 0;
86
    return (val & (val - 1)) == 0;
87
}
88
89
 
90
 
91
{
92
    PIMAGE_DOS_HEADER     dos;
93
    PIMAGE_NT_HEADERS32   nt;
94
95
 
96
97
 
98
        return 0;
99
100
 
101
        return 0;
102
103
 
104
105
 
106
        return 0;
107
108
 
109
        return 0;
110
111
 
112
        return 0;
113
114
 
115
        return 0;
116
117
 
118
        return 0;
119
120
 
121
        return 0;
122
123
 
124
    {
125
        if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment)
126
            return 0;
127
    }
128
    else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment)
129
        return 0;
130
131
 
132
       !IsPowerOf2(nt->OptionalHeader.FileAlignment))
133
        return 0;
134
135
 
136
        return 0;
137
138
 
139
}
140
141
 
142
 
3805 Serge 143
{
1906 serge 144
145
 
146
    PIMAGE_NT_HEADERS32      nt;
147
    PIMAGE_EXPORT_DIRECTORY  exp;
148
149
 
150
#if 0
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
 
215
 
216
    path = (dll_path_t*)malloc(sizeof(dll_path_t));
217
    INIT_LIST_HEAD(&path->list);
218
    path->path = "/sys/lib/";
219
    path->path_len = 9;                           /* FIXME */
220
    DBG("add libraries path %s\n", path->path);
221
    list_add_tail(&path->list, &path_list);
222
#endif
223
#endif
3805 Serge 224
1906 serge 225
 
226
227
 
228
    libc_dll.img_path = libc_path;
229
230
 
231
232
 
233
    nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
234
    exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY, libc_image,
235
                   nt->OptionalHeader.DataDirectory[0].VirtualAddress);
236
237
 
238
    libc_dll.end   = MakePtr(uint32_t,libc_image, nt->OptionalHeader.SizeOfImage);
239
240
 
241
    libc_dll.img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
242
    libc_dll.img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY,libc_image,
243
                        nt->OptionalHeader.DataDirectory[0].VirtualAddress);
244
245
 
246
247
 
248
{
249
    module_t* mod = &libc_dll;
3805 Serge 250
1906 serge 251
 
3805 Serge 252
    {
1906 serge 253
        if( !strncmp(name, mod->img_name, 16))
254
            return mod;
255
        mod = (module_t*)mod->list.next;
3805 Serge 256
    }while(mod != &libc_dll);
257
1906 serge 258
 
259
};
260
261
 
262
{
263
    __asm__ __volatile__ (
264
    "shrl $2, %%ecx         \n\t"
265
    "rep movsl"
266
    :
267
    :"c"(len),"S"(src),"D"(dst)
268
    :"cc");
269
    __asm__ __volatile__ (
270
    ""
271
    :::"ecx","esi","edi");
272
};
273
274
 
275
 
276
{
277
    PIMAGE_DOS_HEADER     dos;
278
    PIMAGE_NT_HEADERS32   nt;
279
    PIMAGE_SECTION_HEADER img_sec;
280
281
 
282
    uint32_t  sec_align;
283
    int    i;
284
285
 
286
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
287
288
 
289
290
 
291
        return 0;
292
293
 
294
295
 
296
297
 
298
299
 
300
    {
301
        void *src_ptr;
302
        void *dest_ptr;
303
        size_t   sec_size;
304
305
 
306
        {
307
            src_ptr  = MakePtr(void*, raw, img_sec->PointerToRawData);
308
            dest_ptr = MakePtr(void*, img_base, img_sec->VirtualAddress);
309
            sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData);
310
        };
311
312
 
313
    };
314
315
 
316
    {
317
        PIMAGE_BASE_RELOCATION reloc;
318
319
 
320
321
 
322
                        nt->OptionalHeader.DataDirectory[5].VirtualAddress);
323
324
 
325
        {
326
            uint32_t  cnt;
327
            uint16_t *entry;
328
            uint16_t  reltype;
329
            uint32_t  offs;
330
331
 
332
            entry = MakePtr( uint16_t*, reloc, sizeof(*reloc) );
333
334
 
335
            {
336
                uint16_t *p16;
337
                uint32_t *p32;
338
339
 
340
                offs = (*entry & 0x0FFF) + reloc->VirtualAddress;
341
                switch(reltype)
342
                {
343
                    case 1:
344
                        p16 = MakePtr(uint16_t*, img_base, offs);
345
                        *p16+= (uint16_t)(delta>>16);
346
                        break;
347
                    case 2:
348
                        p16 = MakePtr(uint16_t*, img_base, offs);
349
                        *p16+= (uint16_t)delta;
350
                        break;
351
                    case 3:
352
                        p32 = MakePtr(uint32_t*, img_base, offs);
353
                        *p32+= delta;
354
                }
355
                entry++;
356
            }
357
            reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock);
358
        }
359
    };
360
    return img_base;
361
};
362
363
 
3805 Serge 364
static loader_recursion;
365
366
 
1906 serge 367
{
368
    static jmp_buf loader_env;
369
    static recursion = -1;
370
371
 
372
    PIMAGE_NT_HEADERS32   nt;
373
    int warn = 0;
374
375
 
376
    if( !recursion )
377
    {
378
        if( unlikely(setjmp(loader_env) != 0))
379
        {
380
            recursion = -1;
381
            return 0;
382
        };
383
    };
384
385
 
386
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
387
388
 
389
    {
390
        PIMAGE_IMPORT_DESCRIPTOR imp;
391
392
 
393
                      nt->OptionalHeader.DataDirectory[1].VirtualAddress);
394
395
 
396
        {
397
            PIMAGE_DOS_HEADER        expdos;
398
            PIMAGE_NT_HEADERS32      expnt;
399
            PIMAGE_EXPORT_DIRECTORY  exp;
400
            PIMAGE_THUNK_DATA32      thunk;
401
402
 
403
            char       *libname;
404
            uint32_t   *exp_functions;
405
            uint16_t   *exp_ordinals;
406
            char      **exp_names;
407
408
 
409
410
 
411
412
 
413
414
 
415
            if(unlikely(api == NULL))
416
            {
417
                printf("library %s not found\n", libname);
418
                longjmp(loader_env, 1);
419
            }
420
421
 
422
423
 
424
            {
425
                thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->OriginalFirstThunk, img_base);
426
            }
427
            else
428
            {
429
                thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->FirstThunk, img_base);
430
            };
431
432
 
433
434
 
435
            exp_ordinals = MakePtr(uint16_t*,  exp->AddressOfNameOrdinals,api->start);
436
            exp_names = MakePtr(char**, exp->AddressOfNames,api->start);
437
438
 
439
            {
440
                PIMAGE_IMPORT_BY_NAME imp_name;
441
442
 
443
                {
444
//                    ordinal = (*func_list) & 0x7fffffff;
445
//                   *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->DllBase, Ordinal);
446
//                    if ((*ImportAddressList) == NULL)
447
//                    {
448
//                        DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
449
//                        RtlpRaiseImportNotFound(NULL, Ordinal, &ImportedModule->FullDllName);
450
//                        return STATUS_ENTRYPOINT_NOT_FOUND;
451
//                    }
452
                }
453
                else
454
                {
455
                    char *export_name;
456
                    uint16_t   ordinal;
457
                    void      *function;
458
                    uint32_t   minn;
459
                    uint32_t   maxn;
460
461
 
462
                                  thunk->u1.AddressOfData, img_base);
463
                    *iat = NULL;
464
465
 
466
467
 
468
                    {
469
                        export_name = MakePtr(char*,exp_names[imp_name->Hint],
470
                                              api->start);
471
                        if(strcmp(imp_name->Name, export_name) == 0)
472
                        {
473
                            ordinal = exp_ordinals[imp_name->Hint];
474
                            function = MakePtr(void*,exp_functions[ordinal], api->start);
475
                            if((uint32_t)function >= (uint32_t)exp)
476
                            {
477
                                printf("forward %s\n", function);
478
                                warn=1;
479
                            }
480
                            else
481
                            {
482
                                DBG(" \t\tat %x\n", function);
483
                                *iat = function;
484
                            };
485
                            thunk++;  // Advance to next thunk
486
                            iat++;
487
                            continue;
488
                        };
489
                    };
490
491
 
492
 
493
                    maxn = exp->NumberOfNames - 1;
494
                    while (minn <= maxn)
495
                    {
496
                        int mid;
497
                        int res;
498
499
 
500
501
 
502
503
 
504
                        if (res == 0)
505
                        {
506
                            ordinal  = exp_ordinals[mid];
507
                            function = MakePtr(void*,exp_functions[ordinal], api->start);
508
509
 
510
                            {
511
                                printf("forward %s\n", function);
512
                                warn=1;
513
                            }
514
                            else
515
                            {
516
                                DBG(" \t\tat %x\n", function);
517
                                *iat = function;
518
                            };
519
                            break;
520
                        }
521
                        else if (minn == maxn)
522
                        {
523
                            printf(" unresolved %s\n",imp_name->Name);
1907 serge 524
                            warn=1;
1906 serge 525
                            break;
526
                        }
527
                        else if (res > 0)
528
                        {
529
                            maxn = mid - 1;
530
                        }
531
                        else
532
                        {
533
                            minn = mid + 1;
534
                        }
535
                    };
536
                };
537
                thunk++;            // Advance to next thunk
538
                iat++;
539
            }
540
            imp++;  // advance to next IMAGE_IMPORT_DESCRIPTOR
541
        };
542
    };
543
544
 
545
546
 
547
        return 1;
548
    else
549
        return 0;
550
}
551
552
 
3805 Serge 553
{
554
    PIMAGE_IMPORT_DESCRIPTOR imp;
555
556
 
557
558
 
559
560
 
561
    {
562
        loader_recursion = 0;
563
        return 0;
564
    };
565
566
 
567
568
 
569
    {
570
        PIMAGE_DOS_HEADER        expdos;
571
        PIMAGE_NT_HEADERS32      expnt;
572
        PIMAGE_EXPORT_DIRECTORY  exp;
573
        PIMAGE_THUNK_DATA32      thunk;
574
575
 
576
        char       *libname;
577
        uint32_t   *exp_functions;
578
        uint16_t   *exp_ordinals;
579
        char      **exp_names;
580
581
 
582
583
 
584
585
 
586
587
 
588
        if(unlikely(api == NULL))
589
        {
590
            printf("library %s not found\n", libname);
591
            longjmp(loader_env, 1);
592
        }
593
594
 
595
596
 
597
        {
598
            thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->OriginalFirstThunk, NULL);
599
        }
600
        else
601
        {
602
            thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->FirstThunk, NULL);
603
        };
604
605
 
606
607
 
608
        exp_ordinals = MakePtr(uint16_t*,  exp->AddressOfNameOrdinals,api->start);
609
        exp_names = MakePtr(char**, exp->AddressOfNames,api->start);
610
611
 
612
        {
613
            PIMAGE_IMPORT_BY_NAME imp_name;
614
615
 
616
            {
617
//                ordinal = (*func_list) & 0x7fffffff;
618
//               *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->DllBase, Ordinal);
619
//                if ((*ImportAddressList) == NULL)
620
//                {
621
//                    DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
622
//                    RtlpRaiseImportNotFound(NULL, Ordinal, &ImportedModule->FullDllName);
623
//                    return STATUS_ENTRYPOINT_NOT_FOUND;
624
//                }
625
            }
626
            else
627
            {
628
                char *export_name;
629
                uint16_t   ordinal;
630
                void      *function;
631
                uint32_t   minn;
632
                uint32_t   maxn;
633
634
 
635
                              thunk->u1.AddressOfData, NULL);
636
                *iat = NULL;
637
638
 
639
640
 
641
                {
642
                    export_name = MakePtr(char*,exp_names[imp_name->Hint],
643
                                          api->start);
644
                    if(strcmp(imp_name->Name, export_name) == 0)
645
                    {
646
                        ordinal = exp_ordinals[imp_name->Hint];
647
                        function = MakePtr(void*,exp_functions[ordinal], api->start);
648
                        if((uint32_t)function >= (uint32_t)exp)
649
                        {
650
                            printf("forward %s\n", function);
651
                            warn=1;
652
                        }
653
                        else
654
                        {
655
                            DBG(" \t\tat %x\n", function);
656
                            *iat = function;
657
                        };
658
                        thunk++;  // Advance to next thunk
659
                        iat++;
660
                        continue;
661
                    };
662
                };
663
664
 
665
 
666
                maxn = exp->NumberOfNames - 1;
667
                while (minn <= maxn)
668
                {
669
                    int mid;
670
                    int res;
671
672
 
673
674
 
675
676
 
677
                    if (res == 0)
678
                    {
679
                        ordinal  = exp_ordinals[mid];
680
                        function = MakePtr(void*,exp_functions[ordinal], api->start);
681
682
 
683
                        {
684
                            DBG("forward %s\n", function);
685
                            warn=1;
686
                        }
687
                        else
688
                        {
689
                            DBG(" \t\tat %x\n", function);
690
                            *iat = function;
691
                        };
692
                        break;
693
                    }
694
                    else if (minn == maxn)
695
                    {
696
                        printf(" unresolved %s\n",imp_name->Name);
697
                        warn=1;
698
                        break;
699
                    }
700
                    else if (res > 0)
701
                    {
702
                        maxn = mid - 1;
703
                    }
704
                    else
705
                    {
706
                        minn = mid + 1;
707
                    }
708
                };
709
            };
710
            thunk++;            // Advance to next thunk
711
            iat++;
712
        }
713
        imp++;  // advance to next IMAGE_IMPORT_DESCRIPTOR
714
    };
715
716
 
717
        return 1;
718
    else
719
        return 0;
720
}
721
722
 
723
 
724
 
1906 serge 725
{
726
    PIMAGE_DOS_HEADER     dos;
727
    PIMAGE_NT_HEADERS32   nt;
728
729
 
730
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
731
732
 
733
};
2040 serge 734
1906 serge 735
 
736
 
2040 serge 737
{
738
739
 
740
    PIMAGE_NT_HEADERS32      expnt;
741
    PIMAGE_EXPORT_DIRECTORY  exp;
742
743
 
744
    uint16_t   *exp_ordinals;
745
    char      **exp_names;
746
747
 
748
    char *export_name;
749
    uint16_t   ordinal;
750
    void *function=NULL;
751
752
 
753
754
 
755
    exp_ordinals = MakePtr(uint16_t*,  exp->AddressOfNameOrdinals,module->start);
756
    exp_names = MakePtr(char**, exp->AddressOfNames,module->start);
757
758
 
759
    maxn = exp->NumberOfNames - 1;
760
    while (minn <= maxn)
761
    {
762
        int mid;
763
        int res;
764
765
 
766
767
 
768
769
 
770
        if (res == 0)
771
        {
772
            ordinal  = exp_ordinals[mid];
773
            function = MakePtr(void*,exp_functions[ordinal], module->start);
774
775
 
776
            {
777
                printf("forward %s\n", function);
778
            }
779
            else
780
            {
781
                DBG(" \t\tat %x\n", function);
782
            };
783
            break;
784
        }
785
        else if (minn == maxn)
786
        {
787
            DBG(" unresolved %s\n",proc_name);
788
            break;
789
        }
790
        else if (res > 0)
791
        {
792
            maxn = mid - 1;
793
        }
794
        else
795
        {
796
            minn = mid + 1;
797
        }
798
    };
799
800
 
801
};
802
803
 
804
 
1906 serge 805
{
806
    char *path;
807
    int   len;
808
809
 
810
811
 
812
813
 
814
    {
815
        PIMAGE_DOS_HEADER        dos;
816
        PIMAGE_NT_HEADERS32      nt;
817
        PIMAGE_EXPORT_DIRECTORY  exp;
818
819
 
820
        void     *raw_img;
821
        size_t    raw_size;
822
        void     *img_base;
823
824
 
825
        memcpy(path, dllpath->path, dllpath->path_len);
826
827
 
828
        path[len+dllpath->path_len]=0;
829
830
 
3799 Serge 831
        if(raw_img == NULL)
1906 serge 832
            continue;
833
834
 
835
        {
836
            printf("invalide module %s\n", path);
837
            user_free(raw_img);
838
            continue;
839
        };
840
841
 
842
        user_free(raw_img);
843
844
 
845
        {
846
            printf("cannot create image %s\n",path);
847
            continue;
848
        };
849
850
 
851
852
 
853
        {
854
            printf("%s epic fail: no enough memory\n",__FUNCTION__);
855
            user_free(img_base);
856
            return 0;
857
        }
858
859
 
860
861
 
862
        module->img_path = strdup(path);
863
        module->start    = img_base;
864
        module->entry    = get_entry_point(img_base);
865
        module->refcount = 1;
866
867
 
868
        nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
869
        exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
870
                   nt->OptionalHeader.DataDirectory[0].VirtualAddress);
871
872
 
873
874
 
875
        module->img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
876
        module->img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
877
                           nt->OptionalHeader.DataDirectory[0].VirtualAddress);
878
879
 
3805 Serge 880
1906 serge 881
 
882
        {
2040 serge 883
            int (*dll_startup)(module_t *mod, uint32_t reason);
884
885
 
886
            if( dll_startup )
887
            {
888
                if( 0 == dll_startup(module, 1))
889
                    return 0;
890
            }
891
            return module;
1906 serge 892
        };
2040 serge 893
894
 
1906 serge 895
    };
896
897
 
898
};
899