Subversion Repositories Kolibri OS

Rev

Rev 3900 | 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
 
3900 Serge 73
1906 serge 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
 
3900 Serge 148
    dll_path_t      *path;
149
    int             len;
150
    char            *p;
151
3809 Serge 152
 
3805 Serge 153
1906 serge 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
3900 Serge 199
1906 serge 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/";
3809 Serge 216
    path->path_len = 15;                           /* FIXME */
217
    DBG("add libraries path %s\n", path->path);
1906 serge 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
 
3809 Serge 257
{
1906 serge 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
 
3809 Serge 345
//static loader_recursion;
346
3805 Serge 347
 
3809 Serge 348
{
1906 serge 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
 
3805 Serge 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
 
3809 Serge 379
3805 Serge 380
 
381
382
 
3900 Serge 383
        if(unlikely(api == NULL))
3805 Serge 384
        {
385
            printf("library %s not found\n", libname);
386
            longjmp(loader_env, 1);
387
        }
388
389
 
3809 Serge 390
3805 Serge 391
 
392
        {
393
            thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->OriginalFirstThunk, img_base);
3809 Serge 394
        }
3805 Serge 395
        else
396
        {
397
            thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->FirstThunk, img_base);
3809 Serge 398
        };
3805 Serge 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);
3809 Serge 431
                *iat = NULL;
3805 Serge 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);
3809 Serge 480
                            warn=1;
3805 Serge 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
 
3809 Serge 512
513
 
3805 Serge 514
        return 1;
515
    else
516
        return 0;
517
}
518
519
 
3809 Serge 520
{
521
    struct app_hdr *header = NULL;
522
    PIMAGE_IMPORT_DESCRIPTOR imp;
523
3805 Serge 524
 
3809 Serge 525
3805 Serge 526
 
3809 Serge 527
528
 
529
530
 
531
 
1906 serge 532
{
533
    PIMAGE_DOS_HEADER     dos;
534
    PIMAGE_NT_HEADERS32   nt;
535
536
 
537
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
538
539
 
540
};
2040 serge 541
1906 serge 542
 
543
 
2040 serge 544
{
545
546
 
547
    PIMAGE_NT_HEADERS32      expnt;
548
    PIMAGE_EXPORT_DIRECTORY  exp;
549
550
 
551
    uint16_t   *exp_ordinals;
552
    char      **exp_names;
553
554
 
555
    char *export_name;
556
    uint16_t   ordinal;
557
    void *function=NULL;
558
559
 
560
561
 
562
    exp_ordinals = MakePtr(uint16_t*,  exp->AddressOfNameOrdinals,module->start);
563
    exp_names = MakePtr(char**, exp->AddressOfNames,module->start);
564
565
 
566
    maxn = exp->NumberOfNames - 1;
567
    while (minn <= maxn)
568
    {
569
        int mid;
570
        int res;
571
572
 
573
574
 
575
576
 
577
        if (res == 0)
578
        {
579
            ordinal  = exp_ordinals[mid];
580
            function = MakePtr(void*,exp_functions[ordinal], module->start);
581
582
 
583
            {
584
                printf("forward %s\n", function);
585
            }
586
            else
587
            {
588
                DBG(" \t\tat %x\n", function);
589
            };
590
            break;
591
        }
592
        else if (minn == maxn)
593
        {
594
            DBG(" unresolved %s\n",proc_name);
595
            break;
596
        }
597
        else if (res > 0)
598
        {
599
            maxn = mid - 1;
600
        }
601
        else
602
        {
603
            minn = mid + 1;
604
        }
605
    };
606
607
 
608
};
609
610
 
3900 Serge 611
{
1906 serge 612
    PIMAGE_DOS_HEADER        dos;
3900 Serge 613
    PIMAGE_NT_HEADERS32      nt;
614
    PIMAGE_EXPORT_DIRECTORY  exp;
615
1906 serge 616
 
3900 Serge 617
    void     *raw_img;
618
    size_t    raw_size;
619
    void     *img_base = NULL;
620
3809 Serge 621
 
3900 Serge 622
    raw_img  = uf.data;
623
    raw_size = uf.size;
624
1906 serge 625
 
3900 Serge 626
        return NULL;
627
628
 
629
    {
1906 serge 630
        printf("invalide module %s\n", path);
3900 Serge 631
        user_free(raw_img);
632
        return NULL;
633
    };
634
1906 serge 635
 
3900 Serge 636
    user_free(raw_img);
637
1906 serge 638
 
3900 Serge 639
        printf("cannot create image %s\n",path);
640
1906 serge 641
 
3900 Serge 642
}
643
1906 serge 644
 
3900 Serge 645
{
646
    PIMAGE_DOS_HEADER        dos;
647
    PIMAGE_NT_HEADERS32      nt;
648
    PIMAGE_EXPORT_DIRECTORY  exp;
649
3809 Serge 650
 
3900 Serge 651
    dll_path_t  *dllpath;
652
    char        *path;
653
    int          len;
654
    char        *libname, *tmp;
655
    void        *img_base;
656
3809 Serge 657
 
1906 serge 658
 
3900 Serge 659
3809 Serge 660
 
3900 Serge 661
    libname = path = tmp != NULL ? tmp+1 : (char*)name;
662
663
 
664
665
 
666
    {
667
        if( !strncmp(path, mod->img_name, 16))
668
            return mod;
669
        mod = (module_t*)mod->list.next;
670
    }while(mod != &libc_dll);
671
672
 
673
    {
674
        path = (char*)name;
675
        img_base = load_lib_internal(path);
676
    }
677
    else
678
    {
679
        len = strlen(libname);
680
        list_for_each_entry(dllpath, &path_list, list)
681
        {
1906 serge 682
            path = alloca(len+dllpath->path_len+1);
3900 Serge 683
            memcpy(path, dllpath->path, dllpath->path_len);
684
1906 serge 685
 
3900 Serge 686
            path[len+dllpath->path_len]=0;
687
1906 serge 688
 
3915 Serge 689
3900 Serge 690
 
691
692
 
693
                continue;
694
        };
1906 serge 695
    }
3900 Serge 696
1906 serge 697
 
3900 Serge 698
    {
699
        printf("unable to load %s\n", name);
700
        return NULL;
701
    };
702
1906 serge 703
 
3900 Serge 704
1906 serge 705
 
3900 Serge 706
    {
707
        printf("%s epic fail: no enough memory\n",__FUNCTION__);
708
        goto err1;
709
    }
710
1906 serge 711
 
3900 Serge 712
1906 serge 713
 
3900 Serge 714
    module->img_path = strdup(path);
715
    module->start    = img_base;
716
    module->entry    = get_entry_point(img_base);
717
    module->refcount = 1;
718
1906 serge 719
 
3900 Serge 720
    nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
721
    exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
722
               nt->OptionalHeader.DataDirectory[0].VirtualAddress);
723
1906 serge 724
 
3900 Serge 725
1906 serge 726
 
3900 Serge 727
    module->img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
728
    module->img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
729
                       nt->OptionalHeader.DataDirectory[0].VirtualAddress);
730
1906 serge 731
 
3900 Serge 732
2040 serge 733
 
3900 Serge 734
    {
735
        PIMAGE_IMPORT_DESCRIPTOR imp;
736
        int (*dll_startup)(module_t *mod, uint32_t reason);
737
3809 Serge 738
 
3900 Serge 739
                    nt->OptionalHeader.DataDirectory[1].VirtualAddress);
740
3809 Serge 741
 
3900 Serge 742
            goto err2;
743
744
 
745
        if( dll_startup )
746
        {
747
            if( 0 == dll_startup(module, 1))
748
                goto err2;
749
        }
750
    };
1906 serge 751
3900 Serge 752
 
753
754
 
755
    list_del(&module->list);
756
    free(module->img_name);
757
    free(module->img_path);
758
    free(module);
759
err1:
760
    user_free(img_base);
761
    return NULL;
1906 serge 762
3900 Serge 763
 
1906 serge 764