Subversion Repositories Kolibri OS

Rev

Rev 7983 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7983 Rev 8097
Line 1... Line 1...
1
(*
1
(*
2
    BSD 2-Clause License
2
    BSD 2-Clause License
Line 3... Line 3...
3
 
3
 
4
    Copyright (c) 2019, Anton Krotov
4
    Copyright (c) 2019-2020, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
Line 6... Line 6...
6
*)
6
*)
Line 7... Line 7...
7
 
7
 
Line 8... Line 8...
8
MODULE ELF;
8
MODULE ELF;
Line 9... Line 9...
9
 
9
 
Line 83... Line 83...
83
        shndx: WCHAR
83
        shndx: WCHAR
Line 84... Line 84...
84
 
84
 
Line 85... Line -...
85
    END;
-
 
86
 
-
 
87
 
-
 
88
    FILE = WR.FILE;
85
    END;
Line 89... Line 86...
89
 
86
 
90
 
87
 
91
VAR
88
VAR
Line 92... Line 89...
92
 
89
 
Line 93... Line 90...
93
    dynamic: LISTS.LIST;
90
    dynamic: LISTS.LIST;
94
    strtab:  CHL.BYTELIST;
91
    strtab:  CHL.BYTELIST;
95
    symtab:  LISTS.LIST;
-
 
96
 
-
 
97
    hashtab, bucket, chain: CHL.INTLIST;
-
 
98
 
-
 
99
 
-
 
100
PROCEDURE align (n, _align: INTEGER): INTEGER;
-
 
101
BEGIN
-
 
102
    IF n MOD _align # 0 THEN
-
 
103
        n := n + _align - (n MOD _align)
-
 
104
    END
-
 
105
 
92
    symtab:  LISTS.LIST;
106
    RETURN n
93
 
Line 107... Line 94...
107
END align;
94
    hashtab, bucket, chain: CHL.INTLIST;
108
 
95
 
109
 
96
 
110
PROCEDURE Write16 (file: FILE; w: WCHAR);
97
PROCEDURE Write16 (w: WCHAR);
111
BEGIN
98
BEGIN
112
    WR.Write16LE(file, ORD(w))
99
    WR.Write16LE(ORD(w))
113
END Write16;
100
END Write16;
114
 
101
 
115
 
102
 
116
PROCEDURE WritePH (file: FILE; ph: Elf32_Phdr);
103
PROCEDURE WritePH (ph: Elf32_Phdr);
117
BEGIN
104
BEGIN
Line 118... Line 105...
118
    WR.Write32LE(file, ph.p_type);
105
    WR.Write32LE(ph.p_type);
119
    WR.Write32LE(file, ph.p_offset);
106
    WR.Write32LE(ph.p_offset);
120
    WR.Write32LE(file, ph.p_vaddr);
107
    WR.Write32LE(ph.p_vaddr);
121
    WR.Write32LE(file, ph.p_paddr);
108
    WR.Write32LE(ph.p_paddr);
122
    WR.Write32LE(file, ph.p_filesz);
109
    WR.Write32LE(ph.p_filesz);
123
    WR.Write32LE(file, ph.p_memsz);
110
    WR.Write32LE(ph.p_memsz);
124
    WR.Write32LE(file, ph.p_flags);
111
    WR.Write32LE(ph.p_flags);
125
    WR.Write32LE(file, ph.p_align)
112
    WR.Write32LE(ph.p_align)
126
END WritePH;
113
END WritePH;
127
 
114
 
128
 
115
 
Line 129... Line -...
129
PROCEDURE WritePH64 (file: FILE; ph: Elf32_Phdr);
-
 
130
BEGIN
-
 
131
    WR.Write32LE(file, ph.p_type);
-
 
132
    WR.Write32LE(file, ph.p_flags);
-
 
133
    WR.Write64LE(file, ph.p_offset);
-
 
134
    WR.Write64LE(file, ph.p_vaddr);
-
 
135
    WR.Write64LE(file, ph.p_paddr);
-
 
136
    WR.Write64LE(file, ph.p_filesz);
-
 
137
    WR.Write64LE(file, ph.p_memsz);
-
 
138
    WR.Write64LE(file, ph.p_align)
-
 
139
END WritePH64;
-
 
140
 
-
 
141
 
-
 
142
PROCEDURE fixup (program: BIN.PROGRAM; text, data, bss: INTEGER; amd64: BOOLEAN);
-
 
143
VAR
-
 
144
    reloc: BIN.RELOC;
-
 
145
    code:  CHL.BYTELIST;
-
 
146
    L, delta, delta0: INTEGER;
-
 
147
 
-
 
148
BEGIN
-
 
149
    code := program.code;
-
 
150
    delta0 := 3 - 7 * ORD(amd64);
-
 
151
    reloc := program.rel_list.first(BIN.RELOC);
-
 
152
 
-
 
153
    WHILE reloc # NIL DO
-
 
154
 
-
 
155
        L := BIN.get32le(code, reloc.offset);
-
 
156
        delta := delta0 - reloc.offset - text;
116
PROCEDURE WritePH64 (ph: Elf32_Phdr);
157
 
117
BEGIN
158
        CASE reloc.opcode OF
118
    WR.Write32LE(ph.p_type);
Line 159... Line 119...
159
        |BIN.PICDATA: BIN.put32le(code, reloc.offset, L + data + delta)
119
    WR.Write32LE(ph.p_flags);
Line 269... Line 229...
269
 
229
 
270
VAR
230
VAR
271
    ehdr: Elf32_Ehdr;
231
    ehdr: Elf32_Ehdr;
Line 272... Line 232...
272
    phdr: ARRAY 16 OF Elf32_Phdr;
232
    phdr: ARRAY 16 OF Elf32_Phdr;
Line 273... Line 233...
273
 
233
 
Line 274... Line 234...
274
    i, BaseAdr, offset, pad, VA, symCount: INTEGER;
234
    i, BaseAdr, DynAdr, offset, pad, VA, symCount: INTEGER;
275
 
-
 
276
    SizeOf: RECORD header, code, data, bss: INTEGER END;
-
 
Line 277... Line 235...
277
 
235
 
Line 278... Line 236...
278
    Offset: RECORD symtab, reltab, hash, strtab, dyn: INTEGER END;
236
    SizeOf: RECORD header, code, data, bss: INTEGER END;
Line 279... Line 237...
279
 
237
 
Line -... Line 238...
-
 
238
    Offset: RECORD symtab, reltab, hash, strtab: INTEGER END;
-
 
239
 
280
    File: FILE;
240
    Interpreter: ARRAY 40 OF CHAR; lenInterpreter: INTEGER;
281
 
241
 
282
    Interpreter: ARRAY 40 OF CHAR; lenInterpreter: INTEGER;
242
    item: LISTS.ITEM;
283
 
243
 
Line 429... Line 389...
429
    Offset.symtab := LISTS.count(dynamic) * (8 + 8 * ORD(amd64));
389
    Offset.symtab := LISTS.count(dynamic) * (8 + 8 * ORD(amd64));
430
    Offset.reltab := Offset.symtab + symCount * (16 + 8 * ORD(amd64));
390
    Offset.reltab := Offset.symtab + symCount * (16 + 8 * ORD(amd64));
431
    Offset.hash   := Offset.reltab + (8 + 16 * ORD(amd64)) * 2;
391
    Offset.hash   := Offset.reltab + (8 + 16 * ORD(amd64)) * 2;
432
    Offset.strtab := Offset.hash + (symCount * 2 + 2) * 4;
392
    Offset.strtab := Offset.hash + (symCount * 2 + 2) * 4;
Line 433... Line 393...
433
 
393
 
Line 434... Line 394...
434
    Offset.dyn := phdr[dyn].p_offset;
394
    DynAdr := phdr[dyn].p_offset + BaseAdr;
435
 
395
 
436
    item := LISTS.getidx(dynamic, 1); item(Elf32_Dyn).d_val := Offset.strtab + Offset.dyn + BaseAdr;
396
    item := LISTS.getidx(dynamic, 1); item(Elf32_Dyn).d_val := Offset.strtab + DynAdr;
437
    item := LISTS.getidx(dynamic, 3); item(Elf32_Dyn).d_val := Offset.symtab + Offset.dyn + BaseAdr;
397
    item := LISTS.getidx(dynamic, 3); item(Elf32_Dyn).d_val := Offset.symtab + DynAdr;
Line 438... Line 398...
438
    item := LISTS.getidx(dynamic, 5); item(Elf32_Dyn).d_val := Offset.reltab + Offset.dyn + BaseAdr;
398
    item := LISTS.getidx(dynamic, 5); item(Elf32_Dyn).d_val := Offset.reltab + DynAdr;
439
    item := LISTS.getidx(dynamic, 8); item(Elf32_Dyn).d_val := Offset.hash   + Offset.dyn + BaseAdr;
399
    item := LISTS.getidx(dynamic, 8); item(Elf32_Dyn).d_val := Offset.hash   + DynAdr;
Line 440... Line 400...
440
 
400
 
Line 448... Line 408...
448
 
408
 
449
    phdr[header].p_type := 1;
409
    phdr[header].p_type := 1;
450
    phdr[header].p_offset := offset;
410
    phdr[header].p_offset := offset;
451
    phdr[header].p_vaddr := BaseAdr;
411
    phdr[header].p_vaddr := BaseAdr;
452
    phdr[header].p_paddr := BaseAdr;
412
    phdr[header].p_paddr := BaseAdr;
453
    phdr[header].p_filesz := 244 + 156 * ORD(amd64) + lenInterpreter + phdr[dyn].p_filesz;
413
    phdr[header].p_filesz := SizeOf.header + lenInterpreter + phdr[dyn].p_filesz;
454
    phdr[header].p_memsz  := phdr[header].p_filesz;
414
    phdr[header].p_memsz  := phdr[header].p_filesz;
455
    phdr[header].p_flags := PF_R + PF_W;
415
    phdr[header].p_flags := PF_R + PF_W;
Line 456... Line 416...
456
    phdr[header].p_align := 1000H;
416
    phdr[header].p_align := 1000H;
457
 
417
 
Line 458... Line 418...
458
    offset := offset + phdr[header].p_filesz;
418
    INC(offset, phdr[header].p_filesz);
459
    VA := BaseAdr + offset + 1000H;
419
    VA := BaseAdr + offset + 1000H;
460
 
420
 
Line 467... Line 427...
467
    phdr[text].p_flags := PF_X + PF_R;
427
    phdr[text].p_flags := PF_X + PF_R;
468
    phdr[text].p_align := 1000H;
428
    phdr[text].p_align := 1000H;
Line 469... Line 429...
469
 
429
 
Line 470... Line 430...
470
    ehdr.e_entry := phdr[text].p_vaddr;
430
    ehdr.e_entry := phdr[text].p_vaddr;
471
 
431
 
472
    offset := offset + phdr[text].p_filesz;
432
    INC(offset, phdr[text].p_filesz);
Line 473... Line 433...
473
    VA := BaseAdr + offset + 2000H;
433
    VA := BaseAdr + offset + 2000H;
474
    pad := (16 - VA MOD 16) MOD 16;
434
    pad := (16 - VA MOD 16) MOD 16;
Line 480... Line 440...
480
    phdr[data].p_filesz := SizeOf.data + pad;
440
    phdr[data].p_filesz := SizeOf.data + pad;
481
    phdr[data].p_memsz := SizeOf.data + pad;
441
    phdr[data].p_memsz := SizeOf.data + pad;
482
    phdr[data].p_flags := PF_R + PF_W;
442
    phdr[data].p_flags := PF_R + PF_W;
483
    phdr[data].p_align := 1000H;
443
    phdr[data].p_align := 1000H;
Line 484... Line 444...
484
 
444
 
485
    offset := offset + phdr[data].p_filesz;
445
    INC(offset, phdr[data].p_filesz);
Line 486... Line 446...
486
    VA := BaseAdr + offset + 3000H;
446
    VA := BaseAdr + offset + 3000H;
487
 
447
 
488
    phdr[bss].p_type := 1;
448
    phdr[bss].p_type := 1;
Line 492... Line 452...
492
    phdr[bss].p_filesz := 0;
452
    phdr[bss].p_filesz := 0;
493
    phdr[bss].p_memsz := SizeOf.bss + 16;
453
    phdr[bss].p_memsz := SizeOf.bss + 16;
494
    phdr[bss].p_flags := PF_R + PF_W;
454
    phdr[bss].p_flags := PF_R + PF_W;
495
    phdr[bss].p_align := 1000H;
455
    phdr[bss].p_align := 1000H;
Line -... Line 456...
-
 
456
 
-
 
457
    Address.Code   := ehdr.e_entry;
496
 
458
    Address.Data   := phdr[data].p_vaddr + pad;
-
 
459
    Address.Bss    := WR.align(phdr[bss].p_vaddr, 16);
-
 
460
    Address.Import := 0;
-
 
461
 
Line 497... Line 462...
497
    fixup(program, ehdr.e_entry, phdr[data].p_vaddr + pad, align(phdr[bss].p_vaddr, 16), amd64);
462
    PE32.fixup(program, Address, amd64);
498
 
463
 
499
    item := symtab.first;
464
    item := symtab.first;
500
    WHILE item # NIL DO
465
    WHILE item # NIL DO
Line 507... Line 472...
507
    IF so THEN
472
    IF so THEN
508
        item := LISTS.getidx(dynamic, 10); item(Elf32_Dyn).d_val := ehdr.e_entry;
473
        item := LISTS.getidx(dynamic, 10); item(Elf32_Dyn).d_val := ehdr.e_entry;
509
        item := LISTS.getidx(dynamic, 11); item(Elf32_Dyn).d_val := BIN.GetLabel(program, fini) + ehdr.e_entry
474
        item := LISTS.getidx(dynamic, 11); item(Elf32_Dyn).d_val := BIN.GetLabel(program, fini) + ehdr.e_entry
510
    END;
475
    END;
Line 511... Line 476...
511
 
476
 
Line 512... Line 477...
512
    File := WR.Create(FileName);
477
    WR.Create(FileName);
513
 
478
 
514
    FOR i := 0 TO EI_NIDENT - 1 DO
479
    FOR i := 0 TO EI_NIDENT - 1 DO
Line 515... Line 480...
515
        WR.WriteByte(File, ehdr.e_ident[i])
480
        WR.WriteByte(ehdr.e_ident[i])
516
    END;
481
    END;
Line 517... Line 482...
517
 
482
 
518
    Write16(File, ehdr.e_type);
483
    Write16(ehdr.e_type);
519
    Write16(File, ehdr.e_machine);
484
    Write16(ehdr.e_machine);
520
 
485
 
521
    WR.Write32LE(File, ehdr.e_version);
486
    WR.Write32LE(ehdr.e_version);
522
    IF amd64 THEN
487
    IF amd64 THEN
523
        WR.Write64LE(File, ehdr.e_entry);
488
        WR.Write64LE(ehdr.e_entry);
524
        WR.Write64LE(File, ehdr.e_phoff);
489
        WR.Write64LE(ehdr.e_phoff);
525
        WR.Write64LE(File, ehdr.e_shoff)
490
        WR.Write64LE(ehdr.e_shoff)
526
    ELSE
491
    ELSE
527
        WR.Write32LE(File, ehdr.e_entry);
492
        WR.Write32LE(ehdr.e_entry);
528
        WR.Write32LE(File, ehdr.e_phoff);
493
        WR.Write32LE(ehdr.e_phoff);
529
        WR.Write32LE(File, ehdr.e_shoff)
494
        WR.Write32LE(ehdr.e_shoff)
530
    END;
495
    END;
531
    WR.Write32LE(File, ehdr.e_flags);
496
    WR.Write32LE(ehdr.e_flags);
532
 
497
 
533
    Write16(File, ehdr.e_ehsize);
498
    Write16(ehdr.e_ehsize);
534
    Write16(File, ehdr.e_phentsize);
499
    Write16(ehdr.e_phentsize);
Line 535... Line 500...
535
    Write16(File, ehdr.e_phnum);
500
    Write16(ehdr.e_phnum);
536
    Write16(File, ehdr.e_shentsize);
501
    Write16(ehdr.e_shentsize);
537
    Write16(File, ehdr.e_shnum);
502
    Write16(ehdr.e_shnum);
538
    Write16(File, ehdr.e_shstrndx);
503
    Write16(ehdr.e_shstrndx);
539
 
504
 
540
    IF amd64 THEN
505
    IF amd64 THEN
541
        WritePH64(File, phdr[interp]);
506
        WritePH64(phdr[interp]);
542
        WritePH64(File, phdr[dyn]);
507
        WritePH64(phdr[dyn]);
543
        WritePH64(File, phdr[header]);
508
        WritePH64(phdr[header]);
544
        WritePH64(File, phdr[text]);
509
        WritePH64(phdr[text]);
545
        WritePH64(File, phdr[data]);
510
        WritePH64(phdr[data]);
546
        WritePH64(File, phdr[bss])
511
        WritePH64(phdr[bss])
547
    ELSE
512
    ELSE
548
        WritePH(File, phdr[interp]);
513
        WritePH(phdr[interp]);
549
        WritePH(File, phdr[dyn]);
514
        WritePH(phdr[dyn]);
Line 550... Line 515...
550
        WritePH(File, phdr[header]);
515
        WritePH(phdr[header]);
551
        WritePH(File, phdr[text]);
516
        WritePH(phdr[text]);
552
        WritePH(File, phdr[data]);
517
        WritePH(phdr[data]);
Line 553... Line -...
553
        WritePH(File, phdr[bss])
-
 
554
    END;
518
        WritePH(phdr[bss])
555
 
519
    END;
556
    FOR i := 0 TO lenInterpreter - 1 DO
520
 
557
        WR.WriteByte(File, ORD(Interpreter[i]))
521
    FOR i := 0 TO lenInterpreter - 1 DO
558
    END;
522
        WR.WriteByte(ORD(Interpreter[i]))
559
 
523
    END;
560
    i := 0;
524
 
Line 561... Line 525...
561
    IF amd64 THEN
525
    IF amd64 THEN
562
        item := dynamic.first;
526
        item := dynamic.first;
563
        WHILE item # NIL DO
527
        WHILE item # NIL DO
564
            WR.Write64LE(File, item(Elf32_Dyn).d_tag);
528
            WR.Write64LE(item(Elf32_Dyn).d_tag);
565
            WR.Write64LE(File, item(Elf32_Dyn).d_val);
529
            WR.Write64LE(item(Elf32_Dyn).d_val);
566
            item := item.next
530
            item := item.next
567
        END;
531
        END;
568
 
532
 
569
        item := symtab.first;
533
        item := symtab.first;
570
        WHILE item # NIL DO
534
        WHILE item # NIL DO
Line 571... Line 535...
571
            WR.Write32LE(File, item(Elf32_Sym).name);
535
            WR.Write32LE(item(Elf32_Sym).name);
572
            WR.WriteByte(File, ORD(item(Elf32_Sym).info));
536
            WR.WriteByte(ORD(item(Elf32_Sym).info));
573
            WR.WriteByte(File, ORD(item(Elf32_Sym).other));
537
            WR.WriteByte(ORD(item(Elf32_Sym).other));
574
            Write16(File, item(Elf32_Sym).shndx);
538
            Write16(item(Elf32_Sym).shndx);
575
            WR.Write64LE(File, item(Elf32_Sym).value);
539
            WR.Write64LE(item(Elf32_Sym).value);
576
            WR.Write64LE(File, item(Elf32_Sym).size);
540
            WR.Write64LE(item(Elf32_Sym).size);
577
            item := item.next
541
            item := item.next
578
        END;
-
 
579
 
-
 
580
        WR.Write64LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 16);
-
 
581
        WR.Write32LE(File, 1);
-
 
582
        WR.Write32LE(File, 1);
-
 
583
        WR.Write64LE(File, 0);
-
 
584
        WR.Write64LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 8);
-
 
585
        WR.Write32LE(File, 1);
-
 
586
        WR.Write32LE(File, 2);
-
 
587
        WR.Write64LE(File, 0);
-
 
588
 
-
 
589
        WR.Write32LE(File, symCount);
-
 
590
        WR.Write32LE(File, symCount);
-
 
591
 
-
 
592
        FOR i := 0 TO symCount - 1 DO
-
 
593
            WR.Write32LE(File, CHL.GetInt(bucket, i))
542
        END;
Line 594... Line 543...
594
        END;
543
 
595
 
544
        WR.Write64LE(phdr[dyn].p_filesz + DynAdr - 16);
596
        FOR i := 0 TO symCount - 1 DO
545
        WR.Write32LE(1);
597
            WR.Write32LE(File, CHL.GetInt(chain, i))
546
        WR.Write32LE(1);
598
        END;
547
        WR.Write64LE(0);
599
 
548
        WR.Write64LE(phdr[dyn].p_filesz + DynAdr - 8);
600
        CHL.WriteToFile(File, strtab);
549
        WR.Write32LE(1);
Line 601... Line 550...
601
        WR.Write64LE(File, 0);
550
        WR.Write32LE(2);
602
        WR.Write64LE(File, 0)
551
        WR.Write64LE(0)
603
 
552
 
604
    ELSE
553
    ELSE
605
        item := dynamic.first;
554
        item := dynamic.first;
606
        WHILE item # NIL DO
555
        WHILE item # NIL DO
607
            WR.Write32LE(File, item(Elf32_Dyn).d_tag);
556
            WR.Write32LE(item(Elf32_Dyn).d_tag);
608
            WR.Write32LE(File, item(Elf32_Dyn).d_val);
557
            WR.Write32LE(item(Elf32_Dyn).d_val);
609
            item := item.next
558
            item := item.next
610
        END;
559
        END;
Line 611... Line 560...
611
 
560
 
612
        item := symtab.first;
561
        item := symtab.first;
613
        WHILE item # NIL DO
562
        WHILE item # NIL DO
614
            WR.Write32LE(File, item(Elf32_Sym).name);
563
            WR.Write32LE(item(Elf32_Sym).name);
Line -... Line 564...
-
 
564
            WR.Write32LE(item(Elf32_Sym).value);
-
 
565
            WR.Write32LE(item(Elf32_Sym).size);
615
            WR.Write32LE(File, item(Elf32_Sym).value);
566
            WR.WriteByte(ORD(item(Elf32_Sym).info));
616
            WR.Write32LE(File, item(Elf32_Sym).size);
567
            WR.WriteByte(ORD(item(Elf32_Sym).other));
Line 617... Line 568...
617
            WR.WriteByte(File, ORD(item(Elf32_Sym).info));
568
            Write16(item(Elf32_Sym).shndx);
618
            WR.WriteByte(File, ORD(item(Elf32_Sym).other));
569
            item := item.next
619
            Write16(File, item(Elf32_Sym).shndx);
570
        END;
Line 620... Line 571...
620
            item := item.next
571
 
621
        END;
572
        WR.Write32LE(phdr[dyn].p_filesz + DynAdr - 8);
622
 
573
        WR.Write32LE(00000101H);
Line 623... Line 574...
623
        WR.Write32LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 8);
574
        WR.Write32LE(phdr[dyn].p_filesz + DynAdr - 4);
624
        WR.Write32LE(File, 00000101H);
-
 
625
        WR.Write32LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 4);
-
 
Line -... Line 575...
-
 
575
        WR.Write32LE(00000201H)
-
 
576
 
-
 
577
    END;
-
 
578
    
-
 
579
    WR.Write32LE(symCount);
-
 
580
    WR.Write32LE(symCount);
626
        WR.Write32LE(File, 00000201H);
581
 
Line 627... Line 582...
627
 
582
    FOR i := 0 TO symCount - 1 DO
628
        WR.Write32LE(File, symCount);
583
        WR.Write32LE(CHL.GetInt(bucket, i))
629
        WR.Write32LE(File, symCount);
584
    END;
630
 
585
 
631
        FOR i := 0 TO symCount - 1 DO
586
    FOR i := 0 TO symCount - 1 DO
632
            WR.Write32LE(File, CHL.GetInt(bucket, i))
587
        WR.Write32LE(CHL.GetInt(chain, i))
633
        END;
588
    END;
-
 
589
 
634
 
590
    CHL.WriteToFile(strtab);
Line 635... Line 591...
635
        FOR i := 0 TO symCount - 1 DO
591
        
636
            WR.Write32LE(File, CHL.GetInt(chain, i))
592
    IF amd64 THEN