Subversion Repositories Kolibri OS

Rev

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