Subversion Repositories Kolibri OS

Rev

Rev 6536 | 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
 
9874 turbocat 10
4349 Serge 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
void*   load_library(const char *name);
9874 turbocat 25
4349 Serge 26
 
27
extern int   __appenv_size;
28
29
 
30
31
 
32
{
33
    char  banner[8];
34
    int   version;
35
    int   start;
36
    int   iend;
37
    int   memsize;
38
    int   stacktop;
39
    char  *cmdline;
40
    char  *path;
41
    int    reserved;
42
    void  *__idata_start;
43
    void  *__idata_end;
44
    void  (*main)(int argc, char **argv, char **envp);
45
};
46
47
 
48
{
49
    struct list_head list;
50
51
 
52
    char       *img_path;
53
54
 
55
56
 
5190 serge 57
    char       *end;
58
4349 Serge 59
 
60
61
 
62
    PIMAGE_SECTION_HEADER    img_sec;
63
    PIMAGE_EXPORT_DIRECTORY  img_exp;
64
};
65
66
 
67
{
68
    struct list_head list;
69
    char *path;
70
    int   path_len;
71
}dll_path_t;
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(char*,libc_image, nt->OptionalHeader.SizeOfImage);
5190 serge 234
4349 Serge 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
 
9874 turbocat 270
4349 Serge 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
 
346
{
347
    static jmp_buf loader_env;
348
    static int recursion = -1;
6536 serge 349
    int warn = 0;
4349 Serge 350
351
 
352
    if( !recursion )
353
    {
354
        if( unlikely(setjmp(loader_env) != 0))
355
        {
356
            recursion = -1;
357
            return 0;
358
        };
359
    };
360
361
 
362
    {
363
        PIMAGE_DOS_HEADER        expdos;
364
        PIMAGE_NT_HEADERS32      expnt;
365
        PIMAGE_EXPORT_DIRECTORY  exp;
366
        PIMAGE_THUNK_DATA32      thunk;
367
368
 
369
        char       *libname;
370
        uint32_t   *exp_functions;
371
        uint16_t   *exp_ordinals;
372
        char      **exp_names;
373
374
 
375
376
 
377
378
 
379
380
 
381
        if(unlikely(api == NULL))
382
        {
383
            printf("library %s not found\n", libname);
384
            longjmp(loader_env, 1);
385
        }
386
387
 
388
389
 
390
        {
391
            thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->OriginalFirstThunk, img_base);
392
        }
393
        else
394
        {
395
            thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->FirstThunk, img_base);
396
        };
397
398
 
399
400
 
401
        exp_ordinals = MakePtr(uint16_t*,  exp->AddressOfNameOrdinals,api->start);
402
        exp_names = MakePtr(char**, exp->AddressOfNames,api->start);
403
404
 
405
        {
406
            PIMAGE_IMPORT_BY_NAME imp_name;
407
408
 
409
            {
410
//                ordinal = (*func_list) & 0x7fffffff;
411
//               *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->DllBase, Ordinal);
412
//                if ((*ImportAddressList) == NULL)
413
//                {
414
//                    DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
415
//                    RtlpRaiseImportNotFound(NULL, Ordinal, &ImportedModule->FullDllName);
416
//                    return STATUS_ENTRYPOINT_NOT_FOUND;
417
//                }
418
            }
419
            else
420
            {
421
                char *export_name;
422
                uint16_t   ordinal;
423
                void      *function;
424
                uint32_t   minn;
425
                uint32_t   maxn;
426
427
 
428
                              thunk->u1.AddressOfData, img_base);
429
                *iat = NULL;
430
431
 
432
433
 
434
                {
435
                    export_name = MakePtr(char*,exp_names[imp_name->Hint],
436
                                          api->start);
437
                    if(strcmp(imp_name->Name, export_name) == 0)
438
                    {
439
                        ordinal = exp_ordinals[imp_name->Hint];
440
                        function = MakePtr(void*,exp_functions[ordinal], api->start);
441
                        if((uint32_t)function >= (uint32_t)exp)
442
                        {
443
                            printf("forward %s\n", function);
444
                            warn=1;
445
                        }
446
                        else
447
                        {
448
                            DBG(" \t\tat %x\n", function);
449
                            *iat = function;
450
                        };
451
                        thunk++;  // Advance to next thunk
452
                        iat++;
453
                        continue;
454
                    };
455
                };
456
457
 
458
                maxn = exp->NumberOfNames - 1;
459
                while (minn <= maxn)
460
                {
461
                    int mid;
462
                    int res;
463
464
 
465
466
 
467
468
 
469
                    if (res == 0)
470
                    {
471
                        ordinal  = exp_ordinals[mid];
472
                        function = MakePtr(void*,exp_functions[ordinal], api->start);
473
474
 
475
                        {
476
                            printf("forward %s\n", function);
477
                            warn=1;
478
                        }
479
                        else
480
                        {
481
                            DBG(" \t\tat %x\n", function);
482
                            *iat = function;
483
                        };
484
                        break;
485
                    }
486
                    else if (minn == maxn)
487
                    {
488
                        printf(" unresolved %s\n",imp_name->Name);
489
                        warn=1;
490
                        break;
491
                    }
492
                    else if (res > 0)
493
                    {
494
                        maxn = mid - 1;
495
                    }
496
                    else
497
                    {
498
                        minn = mid + 1;
499
                    }
500
                };
501
            };
502
            thunk++;            // Advance to next thunk
503
            iat++;
504
        }
505
        imp++;  // advance to next IMAGE_IMPORT_DESCRIPTOR
506
    };
507
508
 
509
510
 
511
        return 1;
512
    else
513
        return 0;
514
}
515
516
 
5022 Serge 517
{
518
    __asm__ __volatile__(
519
    "int $0x40"
520
    ::"a"(69),
521
      "b"(10),
522
      "S"(msg));
523
};
524
525
 
526
 
4349 Serge 527
{
528
    struct app_hdr *header = NULL;
529
    PIMAGE_IMPORT_DESCRIPTOR imp;
530
531
 
532
533
 
5022 Serge 534
    {
535
4349 Serge 536
 
5022 Serge 537
        struct
538
        {
539
            void     *start;
540
            uint32_t  end;
541
            char      name[24];
542
        } dbg_msg;
543
544
 
545
546
 
547
        {
548
            printf("%s %x - %x\n",
549
                   mod->img_name, mod->start, mod->end);
550
551
 
552
553
 
554
            dbg_msg.end   = mod->end;
555
            strcpy(dbg_msg.name, mod->img_name);
556
            send_dbg_msg(&dbg_msg);
557
            mod = (module_t*)mod->list.next;
558
        }while(mod != &libc_dll);
559
#endif
560
561
 
562
    };
563
564
 
565
}
4349 Serge 566
567
 
568
 
569
{
570
    PIMAGE_DOS_HEADER     dos;
571
    PIMAGE_NT_HEADERS32   nt;
572
573
 
574
    nt =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
575
576
 
577
};
578
579
 
580
 
5190 serge 581
{
4349 Serge 582
583
 
5190 serge 584
    PIMAGE_DOS_HEADER        expdos;
4349 Serge 585
    PIMAGE_NT_HEADERS32      expnt;
586
    PIMAGE_EXPORT_DIRECTORY  exp;
587
588
 
589
    uint16_t   *exp_ordinals;
590
    char      **exp_names;
591
592
 
593
    char *export_name;
594
    uint16_t   ordinal;
595
    void *function=NULL;
596
597
 
598
599
 
600
    exp_ordinals = MakePtr(uint16_t*,  exp->AddressOfNameOrdinals,module->start);
601
    exp_names = MakePtr(char**, exp->AddressOfNames,module->start);
602
603
 
604
    maxn = exp->NumberOfNames - 1;
605
    while (minn <= maxn)
606
    {
607
        int mid;
608
        int res;
609
610
 
611
612
 
613
614
 
615
        if (res == 0)
616
        {
617
            ordinal  = exp_ordinals[mid];
618
            function = MakePtr(void*,exp_functions[ordinal], module->start);
619
620
 
621
            {
622
                printf("forward %s\n", function);
623
            }
624
            else
625
            {
626
                DBG(" \t\tat %x\n", function);
627
            };
628
            break;
629
        }
630
        else if (minn == maxn)
631
        {
632
            DBG(" unresolved %s\n",proc_name);
633
            break;
634
        }
635
        else if (res > 0)
636
        {
637
            maxn = mid - 1;
638
        }
639
        else
640
        {
641
            minn = mid + 1;
642
        }
643
    };
644
645
 
646
};
647
648
 
649
{
650
    PIMAGE_DOS_HEADER        dos;
651
    PIMAGE_NT_HEADERS32      nt;
652
    PIMAGE_EXPORT_DIRECTORY  exp;
653
654
 
9874 turbocat 655
    void     *raw_img;
4349 Serge 656
    size_t    raw_size;
657
    void     *img_base = NULL;
658
659
 
9874 turbocat 660
    raw_img  = uf.data;
4349 Serge 661
    raw_size = uf.size;
662
663
 
664
        return NULL;
665
666
 
667
    {
668
        printf("invalide module %s\n", path);
669
        _ksys_free(raw_img);
9874 turbocat 670
        return NULL;
4349 Serge 671
    };
672
673
 
674
    _ksys_free(raw_img);
9874 turbocat 675
4349 Serge 676
 
677
        printf("cannot create image %s\n",path);
678
679
 
680
}
681
682
 
5190 serge 683
{
4349 Serge 684
    PIMAGE_DOS_HEADER        dos;
685
    PIMAGE_NT_HEADERS32      nt;
686
    PIMAGE_EXPORT_DIRECTORY  exp;
687
688
 
689
    dll_path_t  *dllpath;
690
    char        *path;
691
    int          len;
692
    char        *libname, *tmp;
693
    void        *img_base;
694
695
 
696
 
697
698
 
699
    libname = path = tmp != NULL ? tmp+1 : (char*)name;
700
701
 
702
703
 
704
    {
705
        if( !strncmp(path, mod->img_name, 16))
706
            return mod;
707
        mod = (module_t*)mod->list.next;
708
    }while(mod != &libc_dll);
709
710
 
711
    {
712
        path = (char*)name;
713
        img_base = load_lib_internal(path);
714
    }
715
    else
716
    {
717
        len = strlen(libname);
718
        list_for_each_entry(dllpath, &path_list, list)
719
        {
720
            path = alloca(len+dllpath->path_len+1);
721
            memcpy(path, dllpath->path, dllpath->path_len);
722
723
 
724
            path[len+dllpath->path_len]=0;
725
726
 
727
728
 
729
730
 
731
                continue;
732
        };
733
    }
734
735
 
736
    {
737
        printf("unable to load %s\n", name);
738
        return 0;
5190 serge 739
    };
4349 Serge 740
741
 
5190 serge 742
4349 Serge 743
 
744
    {
745
        printf("%s epic fail: no enough memory\n",__FUNCTION__);
746
        goto err1;
747
    }
748
749
 
750
751
 
752
    module->img_path = strdup(path);
753
    module->start    = img_base;
754
    module->entry    = get_entry_point(img_base);
755
    module->refcount = 1;
756
757
 
758
    nt  =  MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
759
    exp =  MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
760
               nt->OptionalHeader.DataDirectory[0].VirtualAddress);
761
762
 
5190 serge 763
4349 Serge 764
 
765
    module->img_sec  = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
766
    module->img_exp  = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
767
                       nt->OptionalHeader.DataDirectory[0].VirtualAddress);
768
769
 
770
771
 
772
    {
773
        PIMAGE_IMPORT_DESCRIPTOR imp;
774
        int (*dll_startup)(module_t *mod, uint32_t reason);
775
776
 
777
                    nt->OptionalHeader.DataDirectory[1].VirtualAddress);
778
779
 
780
            goto err2;
781
782
 
783
        if( dll_startup )
784
        {
785
            if( 0 == dll_startup(module, 1))
786
                goto err2;
787
        }
788
    };
789
790
 
4382 Serge 791
792
 
4349 Serge 793
794
 
795
    list_del(&module->list);
796
    free(module->img_name);
797
    free(module->img_path);
798
    free(module);
799
err1:
800
    _ksys_free(img_base);
9874 turbocat 801
    return NULL;
4349 Serge 802
};
803
804
 
5190 serge 805
                                         uint32_t base, uint32_t size, void *user_data),
806
                         void *user_data)
807
{
808
    module_t *mod = &libc_dll;
809
4349 Serge 810
 
5190 serge 811
    {
812
        if(0 == callback(mod, mod->img_name, (uint32_t)mod->start,
813
                         mod->end - mod->start, user_data))
814
            break;
815
        mod = (module_t*)mod->list.next;
816
    }while(mod != &libc_dll);
817
}
818