Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4349 Serge 1
 
2
#include 
3
#include 
4
#include 
5
#include 
6
#include 
7
#include 
8
9
 
10
11
 
12
#include "pe.h"
13
14
 
15
16
 
17
18
 
19
20
 
21
 
22
void*   create_image(void *raw);
23
int     link_image(void *img_base, PIMAGE_IMPORT_DESCRIPTOR imp);
24
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;
41
    void  *__idata_start;
42
    void  *__idata_end;
43
    void  (*main)(int argc, char **argv, char **envp);
44
};
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";
79
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
 
141
{
142
143
 
144
    PIMAGE_NT_HEADERS32      nt;
145
    PIMAGE_EXPORT_DIRECTORY  exp;
146
147
 
148
    dll_path_t      *path;
149
    int             len;
150
    char            *p;
151
152
 
153
154
 
155
    {
156
        char *env;
157
        env = envz_get(__appenv, __appenv_size, "PATH");
158
        if( env )
159
        {
160
            while( *env )
161
            {
162
                p = env;
163
                while(*p)
164
                {
165
                    if( *p == 0x0D)
166
                        break;
167
                    else if( *p == 0x0A)
168
                        break;
169
                    else if( *p == ':')
170
                        break;
171
                    p++;
172
                };
173
                len = p-env;
174
                if(len)
175
                {
176
                    char *p1;
177
178
 
179
                    memcpy(p1, env, len);
180
                    p1[len]=0;
181
182
 
183
                    INIT_LIST_HEAD(&path->list);
184
                    path->path = p1;
185
                    path->path_len = len;
186
                    DBG("add libraries path %s\n", path->path);
187
                    list_add_tail(&path->list, &path_list);
188
                };
189
                if(*p == ':')
190
                {
191
                    env = p+1;
192
                    continue;
193
                }
194
                else break;
195
            };
196
        };
197
    };
198
#endif
199
200
 
201
    p = (char*)malloc(len+1);
202
    memcpy(p, header->path, len);
203
    p[len]=0;
204
205
 
206
    INIT_LIST_HEAD(&path->list);
207
    path->path = p;
208
    path->path_len = len;
209
    DBG("add libraries path %s\n", path->path);
210
    list_add_tail(&path->list, &path_list);
211
212
 
213
 
214
    INIT_LIST_HEAD(&path->list);
215
    path->path = "/kolibrios/lib/";
216
    path->path_len = 15;                           /* FIXME */
217
    DBG("add libraries path %s\n", path->path);
218
    list_add_tail(&path->list, &path_list);
219
220
 
221
222
 
223
    libc_dll.img_path = libc_path;
224
225
 
226
227
 
228
    nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
229
    exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY, libc_image,
230
                   nt->OptionalHeader.DataDirectory[0].VirtualAddress);
231
232
 
233
    libc_dll.end   = MakePtr(uint32_t,libc_image, nt->OptionalHeader.SizeOfImage);
234
235
 
236
    libc_dll.img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
237
    libc_dll.img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY,libc_image,
238
                        nt->OptionalHeader.DataDirectory[0].VirtualAddress);
239
240
 
241
242
 
243
{
244
    __asm__ __volatile__ (
245
    "shrl $2, %%ecx         \n\t"
246
    "rep movsl"
247
    :
248
    :"c"(len),"S"(src),"D"(dst)
249
    :"cc");
250
    __asm__ __volatile__ (
251
    ""
252
    :::"ecx","esi","edi");
253
};
254
255
 
256
 
257
{
258
    PIMAGE_DOS_HEADER     dos;
259
    PIMAGE_NT_HEADERS32   nt;
260
    PIMAGE_SECTION_HEADER img_sec;
261
262
 
263
    uint32_t  sec_align;
264
    int    i;
265
266
 
267
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
268
269
 
270
271
 
272
        return 0;
273
274
 
275
276
 
277
278
 
279
280
 
281
    {
282
        void *src_ptr;
283
        void *dest_ptr;
284
        size_t   sec_size;
285
286
 
287
        {
288
            src_ptr  = MakePtr(void*, raw, img_sec->PointerToRawData);
289
            dest_ptr = MakePtr(void*, img_base, img_sec->VirtualAddress);
290
            sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData);
291
        };
292
293
 
294
    };
295
296
 
297
    {
298
        PIMAGE_BASE_RELOCATION reloc;
299
300
 
301
302
 
303
                        nt->OptionalHeader.DataDirectory[5].VirtualAddress);
304
305
 
306
        {
307
            uint32_t  cnt;
308
            uint16_t *entry;
309
            uint16_t  reltype;
310
            uint32_t  offs;
311
312
 
313
            entry = MakePtr( uint16_t*, reloc, sizeof(*reloc) );
314
315
 
316
            {
317
                uint16_t *p16;
318
                uint32_t *p32;
319
320
 
321
                offs = (*entry & 0x0FFF) + reloc->VirtualAddress;
322
                switch(reltype)
323
                {
324
                    case 1:
325
                        p16 = MakePtr(uint16_t*, img_base, offs);
326
                        *p16+= (uint16_t)(delta>>16);
327
                        break;
328
                    case 2:
329
                        p16 = MakePtr(uint16_t*, img_base, offs);
330
                        *p16+= (uint16_t)delta;
331
                        break;
332
                    case 3:
333
                        p32 = MakePtr(uint32_t*, img_base, offs);
334
                        *p32+= delta;
335
                }
336
                entry++;
337
            }
338
            reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock);
339
        }
340
    };
341
    return img_base;
342
};
343
344
 
345
//static loader_recursion;
346
347
 
348
{
349
    static jmp_buf loader_env;
350
    static recursion = -1;
351
    int warn = 0;
352
353
 
354
    if( !recursion )
355
    {
356
        if( unlikely(setjmp(loader_env) != 0))
357
        {
358
            recursion = -1;
359
            return 0;
360
        };
361
    };
362
363
 
364
    {
365
        PIMAGE_DOS_HEADER        expdos;
366
        PIMAGE_NT_HEADERS32      expnt;
367
        PIMAGE_EXPORT_DIRECTORY  exp;
368
        PIMAGE_THUNK_DATA32      thunk;
369
370
 
371
        char       *libname;
372
        uint32_t   *exp_functions;
373
        uint16_t   *exp_ordinals;
374
        char      **exp_names;
375
376
 
377
378
 
379
380
 
381
382
 
383
        if(unlikely(api == NULL))
384
        {
385
            printf("library %s not found\n", libname);
386
            longjmp(loader_env, 1);
387
        }
388
389
 
390
391
 
392
        {
393
            thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->OriginalFirstThunk, img_base);
394
        }
395
        else
396
        {
397
            thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->FirstThunk, img_base);
398
        };
399
400
 
401
402
 
403
        exp_ordinals = MakePtr(uint16_t*,  exp->AddressOfNameOrdinals,api->start);
404
        exp_names = MakePtr(char**, exp->AddressOfNames,api->start);
405
406
 
407
        {
408
            PIMAGE_IMPORT_BY_NAME imp_name;
409
410
 
411
            {
412
//                ordinal = (*func_list) & 0x7fffffff;
413
//               *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->DllBase, Ordinal);
414
//                if ((*ImportAddressList) == NULL)
415
//                {
416
//                    DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
417
//                    RtlpRaiseImportNotFound(NULL, Ordinal, &ImportedModule->FullDllName);
418
//                    return STATUS_ENTRYPOINT_NOT_FOUND;
419
//                }
420
            }
421
            else
422
            {
423
                char *export_name;
424
                uint16_t   ordinal;
425
                void      *function;
426
                uint32_t   minn;
427
                uint32_t   maxn;
428
429
 
430
                              thunk->u1.AddressOfData, img_base);
431
                *iat = NULL;
432
433
 
434
435
 
436
                {
437
                    export_name = MakePtr(char*,exp_names[imp_name->Hint],
438
                                          api->start);
439
                    if(strcmp(imp_name->Name, export_name) == 0)
440
                    {
441
                        ordinal = exp_ordinals[imp_name->Hint];
442
                        function = MakePtr(void*,exp_functions[ordinal], api->start);
443
                        if((uint32_t)function >= (uint32_t)exp)
444
                        {
445
                            printf("forward %s\n", function);
446
                            warn=1;
447
                        }
448
                        else
449
                        {
450
                            DBG(" \t\tat %x\n", function);
451
                            *iat = function;
452
                        };
453
                        thunk++;  // Advance to next thunk
454
                        iat++;
455
                        continue;
456
                    };
457
                };
458
459
 
460
 
461
                maxn = exp->NumberOfNames - 1;
462
                while (minn <= maxn)
463
                {
464
                    int mid;
465
                    int res;
466
467
 
468
469
 
470
471
 
472
                    if (res == 0)
473
                    {
474
                        ordinal  = exp_ordinals[mid];
475
                        function = MakePtr(void*,exp_functions[ordinal], api->start);
476
477
 
478
                        {
479
                            printf("forward %s\n", function);
480
                            warn=1;
481
                        }
482
                        else
483
                        {
484
                            DBG(" \t\tat %x\n", function);
485
                            *iat = function;
486
                        };
487
                        break;
488
                    }
489
                    else if (minn == maxn)
490
                    {
491
                        printf(" unresolved %s\n",imp_name->Name);
492
                        warn=1;
493
                        break;
494
                    }
495
                    else if (res > 0)
496
                    {
497
                        maxn = mid - 1;
498
                    }
499
                    else
500
                    {
501
                        minn = mid + 1;
502
                    }
503
                };
504
            };
505
            thunk++;            // Advance to next thunk
506
            iat++;
507
        }
508
        imp++;  // advance to next IMAGE_IMPORT_DESCRIPTOR
509
    };
510
511
 
512
513
 
514
        return 1;
515
    else
516
        return 0;
517
}
518
519
 
5022 Serge 520
{
521
    __asm__ __volatile__(
522
    "int $0x40"
523
    ::"a"(69),
524
      "b"(10),
525
      "S"(msg));
526
};
527
528
 
529
 
4349 Serge 530
{
531
    struct app_hdr *header = NULL;
532
    PIMAGE_IMPORT_DESCRIPTOR imp;
533
534
 
535
536
 
5022 Serge 537
    {
538
4349 Serge 539
 
5022 Serge 540
        struct
541
        {
542
            void     *start;
543
            uint32_t  end;
544
            char      name[24];
545
        } dbg_msg;
546
547
 
548
549
 
550
        {
551
            printf("%s %x - %x\n",
552
                   mod->img_name, mod->start, mod->end);
553
554
 
555
556
 
557
            dbg_msg.end   = mod->end;
558
            strcpy(dbg_msg.name, mod->img_name);
559
            send_dbg_msg(&dbg_msg);
560
            mod = (module_t*)mod->list.next;
561
        }while(mod != &libc_dll);
562
#endif
563
564
 
565
    };
566
567
 
568
}
4349 Serge 569
570
 
571
 
572
{
573
    PIMAGE_DOS_HEADER     dos;
574
    PIMAGE_NT_HEADERS32   nt;
575
576
 
577
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
578
579
 
580
};
581
582
 
583
 
584
{
585
586
 
587
    PIMAGE_NT_HEADERS32      expnt;
588
    PIMAGE_EXPORT_DIRECTORY  exp;
589
590
 
591
    uint16_t   *exp_ordinals;
592
    char      **exp_names;
593
594
 
595
    char *export_name;
596
    uint16_t   ordinal;
597
    void *function=NULL;
598
599
 
600
601
 
602
    exp_ordinals = MakePtr(uint16_t*,  exp->AddressOfNameOrdinals,module->start);
603
    exp_names = MakePtr(char**, exp->AddressOfNames,module->start);
604
605
 
606
    maxn = exp->NumberOfNames - 1;
607
    while (minn <= maxn)
608
    {
609
        int mid;
610
        int res;
611
612
 
613
614
 
615
616
 
617
        if (res == 0)
618
        {
619
            ordinal  = exp_ordinals[mid];
620
            function = MakePtr(void*,exp_functions[ordinal], module->start);
621
622
 
623
            {
624
                printf("forward %s\n", function);
625
            }
626
            else
627
            {
628
                DBG(" \t\tat %x\n", function);
629
            };
630
            break;
631
        }
632
        else if (minn == maxn)
633
        {
634
            DBG(" unresolved %s\n",proc_name);
635
            break;
636
        }
637
        else if (res > 0)
638
        {
639
            maxn = mid - 1;
640
        }
641
        else
642
        {
643
            minn = mid + 1;
644
        }
645
    };
646
647
 
648
};
649
650
 
651
{
652
    PIMAGE_DOS_HEADER        dos;
653
    PIMAGE_NT_HEADERS32      nt;
654
    PIMAGE_EXPORT_DIRECTORY  exp;
655
656
 
657
    void     *raw_img;
658
    size_t    raw_size;
659
    void     *img_base = NULL;
660
661
 
662
    raw_img  = uf.data;
663
    raw_size = uf.size;
664
665
 
666
        return NULL;
667
668
 
669
    {
670
        printf("invalide module %s\n", path);
671
        user_free(raw_img);
672
        return NULL;
673
    };
674
675
 
676
    user_free(raw_img);
677
678
 
679
        printf("cannot create image %s\n",path);
680
681
 
682
}
683
684
 
685
{
686
    PIMAGE_DOS_HEADER        dos;
687
    PIMAGE_NT_HEADERS32      nt;
688
    PIMAGE_EXPORT_DIRECTORY  exp;
689
690
 
691
    dll_path_t  *dllpath;
692
    char        *path;
693
    int          len;
694
    char        *libname, *tmp;
695
    void        *img_base;
696
697
 
698
 
699
700
 
701
    libname = path = tmp != NULL ? tmp+1 : (char*)name;
702
703
 
704
705
 
706
    {
707
        if( !strncmp(path, mod->img_name, 16))
708
            return mod;
709
        mod = (module_t*)mod->list.next;
710
    }while(mod != &libc_dll);
711
712
 
713
    {
714
        path = (char*)name;
715
        img_base = load_lib_internal(path);
716
    }
717
    else
718
    {
719
        len = strlen(libname);
720
        list_for_each_entry(dllpath, &path_list, list)
721
        {
722
            path = alloca(len+dllpath->path_len+1);
723
            memcpy(path, dllpath->path, dllpath->path_len);
724
725
 
726
            path[len+dllpath->path_len]=0;
727
728
 
729
730
 
731
732
 
733
                continue;
734
        };
735
    }
736
737
 
738
    {
739
        printf("unable to load %s\n", name);
740
        return NULL;
741
    };
742
743
 
744
745
 
746
    {
747
        printf("%s epic fail: no enough memory\n",__FUNCTION__);
748
        goto err1;
749
    }
750
751
 
752
753
 
754
    module->img_path = strdup(path);
755
    module->start    = img_base;
756
    module->entry    = get_entry_point(img_base);
757
    module->refcount = 1;
758
759
 
760
    nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
761
    exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
762
               nt->OptionalHeader.DataDirectory[0].VirtualAddress);
763
764
 
765
766
 
767
    module->img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
768
    module->img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
769
                       nt->OptionalHeader.DataDirectory[0].VirtualAddress);
770
771
 
772
773
 
774
    {
775
        PIMAGE_IMPORT_DESCRIPTOR imp;
776
        int (*dll_startup)(module_t *mod, uint32_t reason);
777
778
 
779
                    nt->OptionalHeader.DataDirectory[1].VirtualAddress);
780
781
 
782
            goto err2;
783
784
 
785
        if( dll_startup )
786
        {
787
            if( 0 == dll_startup(module, 1))
788
                goto err2;
789
        }
790
    };
791
792
 
4382 Serge 793
794
 
4349 Serge 795
796
 
797
    list_del(&module->list);
798
    free(module->img_name);
799
    free(module->img_path);
800
    free(module);
801
err1:
802
    user_free(img_base);
803
    return NULL;
804
805
 
806