Subversion Repositories Kolibri OS

Rev

Rev 7983 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7983 Rev 8097
1
(*
1
(*
2
    BSD 2-Clause License
2
    BSD 2-Clause License
3
 
3
 
4
    Copyright (c) 2019, Anton Krotov
4
    Copyright (c) 2019-2020, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
6
*)
6
*)
7
 
7
 
8
MODULE ELF;
8
MODULE ELF;
9
 
9
 
10
IMPORT BIN, WR := WRITER, CHL := CHUNKLISTS, LISTS;
10
IMPORT BIN, WR := WRITER, CHL := CHUNKLISTS, LISTS, PE32, UTILS;
11
 
11
 
12
 
12
 
13
CONST
13
CONST
14
 
14
 
15
    EI_NIDENT = 16;
15
    EI_NIDENT = 16;
16
    ET_EXEC = 2;
16
    ET_EXEC = 2;
17
    ET_DYN = 3;
17
    ET_DYN = 3;
18
 
18
 
19
    EM_386 = 3;
19
    EM_386 = 3;
20
    EM_8664 = 3EH;
20
    EM_8664 = 3EH;
21
 
21
 
22
    ELFCLASS32 = 1;
22
    ELFCLASS32 = 1;
23
    ELFCLASS64 = 2;
23
    ELFCLASS64 = 2;
24
 
24
 
25
    ELFDATA2LSB = 1;
25
    ELFDATA2LSB = 1;
26
    ELFDATA2MSB = 2;
26
    ELFDATA2MSB = 2;
27
 
27
 
28
    PF_X = 1;
28
    PF_X = 1;
29
    PF_W = 2;
29
    PF_W = 2;
30
    PF_R = 4;
30
    PF_R = 4;
31
 
31
 
32
 
32
 
33
TYPE
33
TYPE
34
 
34
 
35
    Elf32_Ehdr = RECORD
35
    Elf32_Ehdr = RECORD
36
 
36
 
37
        e_ident: ARRAY EI_NIDENT OF BYTE;
37
        e_ident: ARRAY EI_NIDENT OF BYTE;
38
 
38
 
39
        e_type,
39
        e_type,
40
        e_machine: WCHAR;
40
        e_machine: WCHAR;
41
 
41
 
42
        e_version,
42
        e_version,
43
        e_entry,
43
        e_entry,
44
        e_phoff,
44
        e_phoff,
45
        e_shoff,
45
        e_shoff,
46
        e_flags: INTEGER;
46
        e_flags: INTEGER;
47
 
47
 
48
        e_ehsize,
48
        e_ehsize,
49
        e_phentsize,
49
        e_phentsize,
50
        e_phnum,
50
        e_phnum,
51
        e_shentsize,
51
        e_shentsize,
52
        e_shnum,
52
        e_shnum,
53
        e_shstrndx: WCHAR
53
        e_shstrndx: WCHAR
54
 
54
 
55
    END;
55
    END;
56
 
56
 
57
 
57
 
58
    Elf32_Phdr = RECORD
58
    Elf32_Phdr = RECORD
59
 
59
 
60
        p_type,
60
        p_type,
61
        p_offset,
61
        p_offset,
62
        p_vaddr,
62
        p_vaddr,
63
        p_paddr,
63
        p_paddr,
64
        p_filesz,
64
        p_filesz,
65
        p_memsz,
65
        p_memsz,
66
        p_flags,
66
        p_flags,
67
        p_align: INTEGER
67
        p_align: INTEGER
68
 
68
 
69
    END;
69
    END;
70
 
70
 
71
 
71
 
72
    Elf32_Dyn = POINTER TO RECORD (LISTS.ITEM)
72
    Elf32_Dyn = POINTER TO RECORD (LISTS.ITEM)
73
 
73
 
74
        d_tag, d_val: INTEGER
74
        d_tag, d_val: INTEGER
75
 
75
 
76
    END;
76
    END;
77
 
77
 
78
 
78
 
79
    Elf32_Sym = POINTER TO RECORD (LISTS.ITEM)
79
    Elf32_Sym = POINTER TO RECORD (LISTS.ITEM)
80
 
80
 
81
        name, value, size: INTEGER;
81
        name, value, size: INTEGER;
82
        info, other: CHAR;
82
        info, other: CHAR;
83
        shndx: WCHAR
83
        shndx: WCHAR
84
 
84
 
85
    END;
85
    END;
86
 
86
 
87
 
-
 
88
    FILE = WR.FILE;
-
 
89
 
-
 
90
 
87
 
91
VAR
88
VAR
92
 
89
 
93
    dynamic: LISTS.LIST;
90
    dynamic: LISTS.LIST;
94
    strtab:  CHL.BYTELIST;
91
    strtab:  CHL.BYTELIST;
95
    symtab:  LISTS.LIST;
92
    symtab:  LISTS.LIST;
96
 
93
 
97
    hashtab, bucket, chain: CHL.INTLIST;
94
    hashtab, bucket, chain: CHL.INTLIST;
98
 
95
 
99
 
96
 
100
PROCEDURE align (n, _align: INTEGER): INTEGER;
97
PROCEDURE Write16 (w: WCHAR);
101
BEGIN
-
 
102
    IF n MOD _align # 0 THEN
-
 
103
        n := n + _align - (n MOD _align)
-
 
104
    END
-
 
105
 
-
 
106
    RETURN n
-
 
107
END align;
-
 
108
 
-
 
109
 
-
 
110
PROCEDURE Write16 (file: FILE; 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
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
 
129
PROCEDURE WritePH64 (file: FILE; ph: Elf32_Phdr);
116
PROCEDURE WritePH64 (ph: Elf32_Phdr);
130
BEGIN
117
BEGIN
131
    WR.Write32LE(file, ph.p_type);
118
    WR.Write32LE(ph.p_type);
132
    WR.Write32LE(file, ph.p_flags);
119
    WR.Write32LE(ph.p_flags);
133
    WR.Write64LE(file, ph.p_offset);
120
    WR.Write64LE(ph.p_offset);
134
    WR.Write64LE(file, ph.p_vaddr);
121
    WR.Write64LE(ph.p_vaddr);
135
    WR.Write64LE(file, ph.p_paddr);
122
    WR.Write64LE(ph.p_paddr);
136
    WR.Write64LE(file, ph.p_filesz);
123
    WR.Write64LE(ph.p_filesz);
137
    WR.Write64LE(file, ph.p_memsz);
124
    WR.Write64LE(ph.p_memsz);
138
    WR.Write64LE(file, ph.p_align)
125
    WR.Write64LE(ph.p_align)
139
END WritePH64;
126
END WritePH64;
140
 
127
 
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;
-
 
157
 
-
 
158
        CASE reloc.opcode OF
-
 
159
        |BIN.PICDATA: BIN.put32le(code, reloc.offset, L + data + delta)
-
 
160
        |BIN.PICCODE: BIN.put32le(code, reloc.offset, BIN.GetLabel(program, L) + text + delta)
-
 
161
        |BIN.PICBSS:  BIN.put32le(code, reloc.offset, L + bss + delta)
-
 
162
        END;
-
 
163
 
-
 
164
        reloc := reloc.next(BIN.RELOC)
-
 
165
    END
-
 
166
END fixup;
-
 
167
 
-
 
168
 
128
 
169
PROCEDURE NewDyn (tag, val: INTEGER);
129
PROCEDURE NewDyn (tag, val: INTEGER);
170
VAR
130
VAR
171
    dyn: Elf32_Dyn;
131
    dyn: Elf32_Dyn;
172
 
132
 
173
BEGIN
133
BEGIN
174
    NEW(dyn);
134
    NEW(dyn);
175
    dyn.d_tag := tag;
135
    dyn.d_tag := tag;
176
    dyn.d_val := val;
136
    dyn.d_val := val;
177
    LISTS.push(dynamic, dyn)
137
    LISTS.push(dynamic, dyn)
178
END NewDyn;
138
END NewDyn;
179
 
139
 
180
 
140
 
181
PROCEDURE NewSym (name, value, size: INTEGER; info, other: CHAR; shndx: WCHAR);
141
PROCEDURE NewSym (name, value, size: INTEGER; info, other: CHAR; shndx: WCHAR);
182
VAR
142
VAR
183
    sym: Elf32_Sym;
143
    sym: Elf32_Sym;
184
 
144
 
185
BEGIN
145
BEGIN
186
    NEW(sym);
146
    NEW(sym);
187
    sym.name := name;
147
    sym.name := name;
188
    sym.value := value;
148
    sym.value := value;
189
    sym.size := size;
149
    sym.size := size;
190
    sym.info := info;
150
    sym.info := info;
191
    sym.other := other;
151
    sym.other := other;
192
    sym.shndx := shndx;
152
    sym.shndx := shndx;
193
 
153
 
194
    LISTS.push(symtab, sym)
154
    LISTS.push(symtab, sym)
195
END NewSym;
155
END NewSym;
196
 
156
 
197
 
157
 
198
PROCEDURE HashStr (name: ARRAY OF CHAR): INTEGER;
158
PROCEDURE HashStr (name: ARRAY OF CHAR): INTEGER;
199
VAR
159
VAR
200
    i, h: INTEGER;
160
    i, h: INTEGER;
201
    g: SET;
161
    g: SET;
202
 
162
 
203
BEGIN
163
BEGIN
204
    h := 0;
164
    h := 0;
205
    i := 0;
165
    i := 0;
206
    WHILE name[i] # 0X DO
166
    WHILE name[i] # 0X DO
207
        h := h * 16 + ORD(name[i]);
167
        h := h * 16 + ORD(name[i]);
208
        g := BITS(h) * {28..31};
168
        g := BITS(h) * {28..31};
209
        h := ORD(BITS(h) / BITS(LSR(ORD(g), 24)) - g);
169
        h := ORD(BITS(h) / BITS(LSR(ORD(g), 24)) - g);
210
        INC(i)
170
        INC(i)
211
    END
171
    END
212
 
172
 
213
    RETURN h
173
    RETURN h
214
END HashStr;
174
END HashStr;
215
 
175
 
216
 
176
 
217
PROCEDURE MakeHash (bucket, chain: CHL.INTLIST; symCount: INTEGER);
177
PROCEDURE MakeHash (bucket, chain: CHL.INTLIST; symCount: INTEGER);
218
VAR
178
VAR
219
    symi, hi, k: INTEGER;
179
    symi, hi, k: INTEGER;
220
 
180
 
221
BEGIN
181
BEGIN
222
    FOR symi := 0 TO symCount - 1 DO
182
    FOR symi := 0 TO symCount - 1 DO
223
        CHL.SetInt(chain, symi, 0);
183
        CHL.SetInt(chain, symi, 0);
224
        hi := CHL.GetInt(hashtab, symi) MOD symCount;
184
        hi := CHL.GetInt(hashtab, symi) MOD symCount;
225
        IF CHL.GetInt(bucket, hi) # 0 THEN
185
        IF CHL.GetInt(bucket, hi) # 0 THEN
226
            k := symi;
186
            k := symi;
227
            WHILE CHL.GetInt(chain, k) # 0 DO
187
            WHILE CHL.GetInt(chain, k) # 0 DO
228
                k := CHL.GetInt(chain, k)
188
                k := CHL.GetInt(chain, k)
229
            END;
189
            END;
230
            CHL.SetInt(chain, k, CHL.GetInt(bucket, hi))
190
            CHL.SetInt(chain, k, CHL.GetInt(bucket, hi))
231
        END;
191
        END;
232
        CHL.SetInt(bucket, hi, symi)
192
        CHL.SetInt(bucket, hi, symi)
233
    END
193
    END
234
END MakeHash;
194
END MakeHash;
235
 
195
 
236
 
196
 
237
PROCEDURE write* (program: BIN.PROGRAM; FileName: ARRAY OF CHAR; fini: INTEGER; so, amd64: BOOLEAN);
197
PROCEDURE write* (program: BIN.PROGRAM; FileName: ARRAY OF CHAR; fini: INTEGER; so, amd64: BOOLEAN);
238
CONST
198
CONST
239
    interp  =  0;
199
    interp  =  0;
240
    dyn     =  1;
200
    dyn     =  1;
241
    header  =  2;
201
    header  =  2;
242
    text    =  3;
202
    text    =  3;
243
    data    =  4;
203
    data    =  4;
244
    bss     =  5;
204
    bss     =  5;
245
 
205
 
246
    linuxInterpreter64 = "/lib64/ld-linux-x86-64.so.2";
206
    linuxInterpreter64 = "/lib64/ld-linux-x86-64.so.2";
247
    linuxInterpreter32 = "/lib/ld-linux.so.2";
207
    linuxInterpreter32 = "/lib/ld-linux.so.2";
248
 
208
 
249
    exeBaseAddress32 = 8048000H;
209
    exeBaseAddress32 = 8048000H;
250
    exeBaseAddress64 = 400000H;
210
    exeBaseAddress64 = 400000H;
251
    dllBaseAddress = 0;
211
    dllBaseAddress = 0;
252
 
212
 
253
    DT_NULL = 0;
213
    DT_NULL = 0;
254
    DT_NEEDED = 1;
214
    DT_NEEDED = 1;
255
    DT_HASH = 4;
215
    DT_HASH = 4;
256
    DT_STRTAB = 5;
216
    DT_STRTAB = 5;
257
    DT_SYMTAB = 6;
217
    DT_SYMTAB = 6;
258
    DT_RELA = 7;
218
    DT_RELA = 7;
259
    DT_RELASZ = 8;
219
    DT_RELASZ = 8;
260
    DT_RELAENT = 9;
220
    DT_RELAENT = 9;
261
    DT_STRSZ = 10;
221
    DT_STRSZ = 10;
262
    DT_SYMENT = 11;
222
    DT_SYMENT = 11;
263
    DT_INIT = 12;
223
    DT_INIT = 12;
264
    DT_FINI = 13;
224
    DT_FINI = 13;
265
    DT_SONAME = 14;
225
    DT_SONAME = 14;
266
    DT_REL = 17;
226
    DT_REL = 17;
267
    DT_RELSZ = 18;
227
    DT_RELSZ = 18;
268
    DT_RELENT = 19;
228
    DT_RELENT = 19;
269
 
229
 
270
VAR
230
VAR
271
    ehdr: Elf32_Ehdr;
231
    ehdr: Elf32_Ehdr;
272
    phdr: ARRAY 16 OF Elf32_Phdr;
232
    phdr: ARRAY 16 OF Elf32_Phdr;
273
 
233
 
274
    i, BaseAdr, offset, pad, VA, symCount: INTEGER;
234
    i, BaseAdr, DynAdr, offset, pad, VA, symCount: INTEGER;
275
 
235
 
276
    SizeOf: RECORD header, code, data, bss: INTEGER END;
236
    SizeOf: RECORD header, code, data, bss: INTEGER END;
277
 
237
 
278
    Offset: RECORD symtab, reltab, hash, strtab, dyn: INTEGER END;
-
 
279
 
-
 
280
    File: FILE;
238
    Offset: RECORD symtab, reltab, hash, strtab: INTEGER END;
281
 
239
 
282
    Interpreter: ARRAY 40 OF CHAR; lenInterpreter: INTEGER;
240
    Interpreter: ARRAY 40 OF CHAR; lenInterpreter: INTEGER;
283
 
241
 
284
    item: LISTS.ITEM;
242
    item: LISTS.ITEM;
285
 
243
 
286
    Name: ARRAY 2048 OF CHAR;
244
    Name: ARRAY 2048 OF CHAR;
-
 
245
 
-
 
246
    Address: PE32.VIRTUAL_ADDR;
287
 
247
 
288
BEGIN
248
BEGIN
289
    dynamic := LISTS.create(NIL);
249
    dynamic := LISTS.create(NIL);
290
    symtab  := LISTS.create(NIL);
250
    symtab  := LISTS.create(NIL);
291
    strtab  := CHL.CreateByteList();
251
    strtab  := CHL.CreateByteList();
292
 
252
 
293
    IF amd64 THEN
253
    IF amd64 THEN
294
        BaseAdr := exeBaseAddress64;
254
        BaseAdr := exeBaseAddress64;
295
        Interpreter := linuxInterpreter64
255
        Interpreter := linuxInterpreter64
296
    ELSE
256
    ELSE
297
        BaseAdr := exeBaseAddress32;
257
        BaseAdr := exeBaseAddress32;
298
        Interpreter := linuxInterpreter32
258
        Interpreter := linuxInterpreter32
299
    END;
259
    END;
300
 
260
 
301
    IF so THEN
261
    IF so THEN
302
        BaseAdr := dllBaseAddress
262
        BaseAdr := dllBaseAddress
303
    END;
263
    END;
304
 
264
 
305
    lenInterpreter := LENGTH(Interpreter) + 1;
265
    lenInterpreter := LENGTH(Interpreter) + 1;
306
 
266
 
307
    SizeOf.code := CHL.Length(program.code);
267
    SizeOf.code := CHL.Length(program.code);
308
    SizeOf.data := CHL.Length(program.data);
268
    SizeOf.data := CHL.Length(program.data);
309
    SizeOf.bss  := program.bss;
269
    SizeOf.bss  := program.bss;
310
 
270
 
311
    ehdr.e_ident[0] := 7FH;
271
    ehdr.e_ident[0] := 7FH;
312
    ehdr.e_ident[1] := ORD("E");
272
    ehdr.e_ident[1] := ORD("E");
313
    ehdr.e_ident[2] := ORD("L");
273
    ehdr.e_ident[2] := ORD("L");
314
    ehdr.e_ident[3] := ORD("F");
274
    ehdr.e_ident[3] := ORD("F");
315
    IF amd64 THEN
275
    IF amd64 THEN
316
        ehdr.e_ident[4] := ELFCLASS64
276
        ehdr.e_ident[4] := ELFCLASS64
317
    ELSE
277
    ELSE
318
        ehdr.e_ident[4] := ELFCLASS32
278
        ehdr.e_ident[4] := ELFCLASS32
319
    END;
279
    END;
320
    ehdr.e_ident[5] := ELFDATA2LSB;
280
    ehdr.e_ident[5] := ELFDATA2LSB;
321
    ehdr.e_ident[6] := 1;
281
    ehdr.e_ident[6] := 1;
322
    ehdr.e_ident[7] := 3;
282
    ehdr.e_ident[7] := 3;
323
    FOR i := 8 TO EI_NIDENT - 1 DO
283
    FOR i := 8 TO EI_NIDENT - 1 DO
324
        ehdr.e_ident[i] := 0
284
        ehdr.e_ident[i] := 0
325
    END;
285
    END;
326
 
286
 
327
    IF so THEN
287
    IF so THEN
328
        ehdr.e_type := WCHR(ET_DYN)
288
        ehdr.e_type := WCHR(ET_DYN)
329
    ELSE
289
    ELSE
330
        ehdr.e_type := WCHR(ET_EXEC)
290
        ehdr.e_type := WCHR(ET_EXEC)
331
    END;
291
    END;
332
 
292
 
333
    ehdr.e_version := 1;
293
    ehdr.e_version := 1;
334
    ehdr.e_shoff := 0;
294
    ehdr.e_shoff := 0;
335
    ehdr.e_flags := 0;
295
    ehdr.e_flags := 0;
336
    ehdr.e_shnum := WCHR(0);
296
    ehdr.e_shnum := WCHR(0);
337
    ehdr.e_shstrndx := WCHR(0);
297
    ehdr.e_shstrndx := WCHR(0);
338
    ehdr.e_phnum := WCHR(6);
298
    ehdr.e_phnum := WCHR(6);
339
 
299
 
340
    IF amd64 THEN
300
    IF amd64 THEN
341
        ehdr.e_machine := WCHR(EM_8664);
301
        ehdr.e_machine := WCHR(EM_8664);
342
        ehdr.e_phoff := 40H;
302
        ehdr.e_phoff := 40H;
343
        ehdr.e_ehsize := WCHR(40H);
303
        ehdr.e_ehsize := WCHR(40H);
344
        ehdr.e_phentsize := WCHR(38H);
304
        ehdr.e_phentsize := WCHR(38H);
345
        ehdr.e_shentsize := WCHR(40H)
305
        ehdr.e_shentsize := WCHR(40H)
346
    ELSE
306
    ELSE
347
        ehdr.e_machine := WCHR(EM_386);
307
        ehdr.e_machine := WCHR(EM_386);
348
        ehdr.e_phoff := 34H;
308
        ehdr.e_phoff := 34H;
349
        ehdr.e_ehsize := WCHR(34H);
309
        ehdr.e_ehsize := WCHR(34H);
350
        ehdr.e_phentsize := WCHR(20H);
310
        ehdr.e_phentsize := WCHR(20H);
351
        ehdr.e_shentsize := WCHR(28H)
311
        ehdr.e_shentsize := WCHR(28H)
352
    END;
312
    END;
353
 
313
 
354
    SizeOf.header := ORD(ehdr.e_ehsize) + ORD(ehdr.e_phentsize) * ORD(ehdr.e_phnum);
314
    SizeOf.header := ORD(ehdr.e_ehsize) + ORD(ehdr.e_phentsize) * ORD(ehdr.e_phnum);
355
 
315
 
356
    phdr[interp].p_type := 3;
316
    phdr[interp].p_type := 3;
357
    phdr[interp].p_offset := SizeOf.header;
317
    phdr[interp].p_offset := SizeOf.header;
358
    phdr[interp].p_vaddr := BaseAdr + phdr[interp].p_offset;
318
    phdr[interp].p_vaddr := BaseAdr + phdr[interp].p_offset;
359
    phdr[interp].p_paddr := phdr[interp].p_vaddr;
319
    phdr[interp].p_paddr := phdr[interp].p_vaddr;
360
    phdr[interp].p_filesz := lenInterpreter;
320
    phdr[interp].p_filesz := lenInterpreter;
361
    phdr[interp].p_memsz := lenInterpreter;
321
    phdr[interp].p_memsz := lenInterpreter;
362
    phdr[interp].p_flags := PF_R;
322
    phdr[interp].p_flags := PF_R;
363
    phdr[interp].p_align := 1;
323
    phdr[interp].p_align := 1;
364
 
324
 
365
    phdr[dyn].p_type := 2;
325
    phdr[dyn].p_type := 2;
366
    phdr[dyn].p_offset := phdr[interp].p_offset + phdr[interp].p_filesz;
326
    phdr[dyn].p_offset := phdr[interp].p_offset + phdr[interp].p_filesz;
367
    phdr[dyn].p_vaddr := BaseAdr + phdr[dyn].p_offset;
327
    phdr[dyn].p_vaddr := BaseAdr + phdr[dyn].p_offset;
368
    phdr[dyn].p_paddr := phdr[dyn].p_vaddr;
328
    phdr[dyn].p_paddr := phdr[dyn].p_vaddr;
369
 
329
 
370
    hashtab := CHL.CreateIntList();
330
    hashtab := CHL.CreateIntList();
371
 
331
 
372
    CHL.PushInt(hashtab, HashStr(""));
332
    CHL.PushInt(hashtab, HashStr(""));
373
    NewSym(CHL.PushStr(strtab, ""), 0, 0, 0X, 0X, 0X);
333
    NewSym(CHL.PushStr(strtab, ""), 0, 0, 0X, 0X, 0X);
374
    CHL.PushInt(hashtab, HashStr("dlopen"));
334
    CHL.PushInt(hashtab, HashStr("dlopen"));
375
    NewSym(CHL.PushStr(strtab, "dlopen"), 0, 0, 12X, 0X, 0X);
335
    NewSym(CHL.PushStr(strtab, "dlopen"), 0, 0, 12X, 0X, 0X);
376
    CHL.PushInt(hashtab, HashStr("dlsym"));
336
    CHL.PushInt(hashtab, HashStr("dlsym"));
377
    NewSym(CHL.PushStr(strtab, "dlsym"), 0, 0, 12X, 0X, 0X);
337
    NewSym(CHL.PushStr(strtab, "dlsym"), 0, 0, 12X, 0X, 0X);
378
 
338
 
379
    IF so THEN
339
    IF so THEN
380
        item := program.exp_list.first;
340
        item := program.exp_list.first;
381
        WHILE item # NIL DO
341
        WHILE item # NIL DO
382
            ASSERT(CHL.GetStr(program.export, item(BIN.EXPRT).nameoffs, Name));
342
            ASSERT(CHL.GetStr(program.export, item(BIN.EXPRT).nameoffs, Name));
383
            CHL.PushInt(hashtab, HashStr(Name));
343
            CHL.PushInt(hashtab, HashStr(Name));
384
            NewSym(CHL.PushStr(strtab, Name), item(BIN.EXPRT).label, 0, 12X, 0X, 0X);
344
            NewSym(CHL.PushStr(strtab, Name), item(BIN.EXPRT).label, 0, 12X, 0X, 0X);
385
            item := item.next
345
            item := item.next
386
        END;
346
        END;
387
        ASSERT(CHL.GetStr(program.data, program.modname, Name))
347
        ASSERT(CHL.GetStr(program.data, program.modname, Name))
388
    END;
348
    END;
389
 
349
 
390
    symCount := LISTS.count(symtab);
350
    symCount := LISTS.count(symtab);
391
 
351
 
392
    bucket  := CHL.CreateIntList();
352
    bucket := CHL.CreateIntList();
393
    chain   := CHL.CreateIntList();
353
    chain  := CHL.CreateIntList();
394
 
354
 
395
    FOR i := 1 TO symCount DO
355
    FOR i := 1 TO symCount DO
396
        CHL.PushInt(bucket, 0);
356
        CHL.PushInt(bucket, 0);
397
        CHL.PushInt(chain, 0)
357
        CHL.PushInt(chain, 0)
398
    END;
358
    END;
399
 
359
 
400
    MakeHash(bucket, chain, symCount);
360
    MakeHash(bucket, chain, symCount);
401
 
361
 
402
    NewDyn(DT_NEEDED, CHL.PushStr(strtab, "libdl.so.2"));
362
    NewDyn(DT_NEEDED, CHL.PushStr(strtab, "libdl.so.2"));
403
    NewDyn(DT_STRTAB, 0);
363
    NewDyn(DT_STRTAB, 0);
404
    NewDyn(DT_STRSZ, CHL.Length(strtab));
364
    NewDyn(DT_STRSZ, CHL.Length(strtab));
405
    NewDyn(DT_SYMTAB, 0);
365
    NewDyn(DT_SYMTAB, 0);
406
 
366
 
407
    IF amd64 THEN
367
    IF amd64 THEN
408
        NewDyn(DT_SYMENT, 24);
368
        NewDyn(DT_SYMENT, 24);
409
        NewDyn(DT_RELA, 0);
369
        NewDyn(DT_RELA, 0);
410
        NewDyn(DT_RELASZ, 48);
370
        NewDyn(DT_RELASZ, 48);
411
        NewDyn(DT_RELAENT, 24)
371
        NewDyn(DT_RELAENT, 24)
412
    ELSE
372
    ELSE
413
        NewDyn(DT_SYMENT, 16);
373
        NewDyn(DT_SYMENT, 16);
414
        NewDyn(DT_REL, 0);
374
        NewDyn(DT_REL, 0);
415
        NewDyn(DT_RELSZ, 16);
375
        NewDyn(DT_RELSZ, 16);
416
        NewDyn(DT_RELENT, 8)
376
        NewDyn(DT_RELENT, 8)
417
    END;
377
    END;
418
 
378
 
419
    NewDyn(DT_HASH, 0);
379
    NewDyn(DT_HASH, 0);
420
 
380
 
421
    IF so THEN
381
    IF so THEN
422
        NewDyn(DT_SONAME, CHL.PushStr(strtab, Name));
382
        NewDyn(DT_SONAME, CHL.PushStr(strtab, Name));
423
        NewDyn(DT_INIT, 0);
383
        NewDyn(DT_INIT, 0);
424
        NewDyn(DT_FINI, 0)
384
        NewDyn(DT_FINI, 0)
425
    END;
385
    END;
426
 
386
 
427
    NewDyn(DT_NULL, 0);
387
    NewDyn(DT_NULL, 0);
428
 
388
 
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;
433
 
393
 
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;
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;
440
 
400
 
441
    phdr[dyn].p_filesz := Offset.strtab + CHL.Length(strtab) + 8 + 8 * ORD(amd64);
401
    phdr[dyn].p_filesz := Offset.strtab + CHL.Length(strtab) + 8 + 8 * ORD(amd64);
442
    phdr[dyn].p_memsz  := phdr[dyn].p_filesz;
402
    phdr[dyn].p_memsz  := phdr[dyn].p_filesz;
443
 
403
 
444
    phdr[dyn].p_flags := PF_R;
404
    phdr[dyn].p_flags := PF_R;
445
    phdr[dyn].p_align := 1;
405
    phdr[dyn].p_align := 1;
446
 
406
 
447
    offset := 0;
407
    offset := 0;
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;
456
    phdr[header].p_align := 1000H;
416
    phdr[header].p_align := 1000H;
457
 
417
 
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
 
461
    phdr[text].p_type := 1;
421
    phdr[text].p_type := 1;
462
    phdr[text].p_offset := offset;
422
    phdr[text].p_offset := offset;
463
    phdr[text].p_vaddr := VA;
423
    phdr[text].p_vaddr := VA;
464
    phdr[text].p_paddr := VA;
424
    phdr[text].p_paddr := VA;
465
    phdr[text].p_filesz := SizeOf.code;
425
    phdr[text].p_filesz := SizeOf.code;
466
    phdr[text].p_memsz := SizeOf.code;
426
    phdr[text].p_memsz := SizeOf.code;
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;
469
 
429
 
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);
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;
475
 
435
 
476
    phdr[data].p_type := 1;
436
    phdr[data].p_type := 1;
477
    phdr[data].p_offset := offset;
437
    phdr[data].p_offset := offset;
478
    phdr[data].p_vaddr := VA;
438
    phdr[data].p_vaddr := VA;
479
    phdr[data].p_paddr := VA;
439
    phdr[data].p_paddr := VA;
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;
484
 
444
 
485
    offset := offset + phdr[data].p_filesz;
445
    INC(offset, phdr[data].p_filesz);
486
    VA := BaseAdr + offset + 3000H;
446
    VA := BaseAdr + offset + 3000H;
487
 
447
 
488
    phdr[bss].p_type := 1;
448
    phdr[bss].p_type := 1;
489
    phdr[bss].p_offset := offset;
449
    phdr[bss].p_offset := offset;
490
    phdr[bss].p_vaddr := VA;
450
    phdr[bss].p_vaddr := VA;
491
    phdr[bss].p_paddr := VA;
451
    phdr[bss].p_paddr := VA;
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;
-
 
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
 
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
501
        IF item(Elf32_Sym).value # 0 THEN
466
        IF item(Elf32_Sym).value # 0 THEN
502
            INC(item(Elf32_Sym).value, ehdr.e_entry)
467
            INC(item(Elf32_Sym).value, ehdr.e_entry)
503
        END;
468
        END;
504
        item := item.next
469
        item := item.next
505
    END;
470
    END;
506
 
471
 
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;
511
 
476
 
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
515
        WR.WriteByte(File, ehdr.e_ident[i])
480
        WR.WriteByte(ehdr.e_ident[i])
516
    END;
481
    END;
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);
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]);
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]);
553
        WritePH(File, phdr[bss])
518
        WritePH(phdr[bss])
554
    END;
519
    END;
555
 
520
 
556
    FOR i := 0 TO lenInterpreter - 1 DO
521
    FOR i := 0 TO lenInterpreter - 1 DO
557
        WR.WriteByte(File, ORD(Interpreter[i]))
522
        WR.WriteByte(ORD(Interpreter[i]))
558
    END;
523
    END;
559
 
-
 
560
    i := 0;
524
 
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
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;
542
        END;
579
 
543
 
580
        WR.Write64LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 16);
544
        WR.Write64LE(phdr[dyn].p_filesz + DynAdr - 16);
581
        WR.Write32LE(File, 1);
545
        WR.Write32LE(1);
582
        WR.Write32LE(File, 1);
546
        WR.Write32LE(1);
583
        WR.Write64LE(File, 0);
547
        WR.Write64LE(0);
584
        WR.Write64LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 8);
548
        WR.Write64LE(phdr[dyn].p_filesz + DynAdr - 8);
585
        WR.Write32LE(File, 1);
549
        WR.Write32LE(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))
-
 
594
        END;
-
 
595
 
-
 
596
        FOR i := 0 TO symCount - 1 DO
-
 
597
            WR.Write32LE(File, CHL.GetInt(chain, i))
-
 
598
        END;
-
 
599
 
-
 
600
        CHL.WriteToFile(File, strtab);
-
 
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;
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);
615
            WR.Write32LE(File, item(Elf32_Sym).value);
564
            WR.Write32LE(item(Elf32_Sym).value);
616
            WR.Write32LE(File, item(Elf32_Sym).size);
565
            WR.Write32LE(item(Elf32_Sym).size);
617
            WR.WriteByte(File, ORD(item(Elf32_Sym).info));
566
            WR.WriteByte(ORD(item(Elf32_Sym).info));
618
            WR.WriteByte(File, ORD(item(Elf32_Sym).other));
567
            WR.WriteByte(ORD(item(Elf32_Sym).other));
619
            Write16(File, item(Elf32_Sym).shndx);
568
            Write16(item(Elf32_Sym).shndx);
620
            item := item.next
569
            item := item.next
621
        END;
570
        END;
622
 
571
 
623
        WR.Write32LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 8);
572
        WR.Write32LE(phdr[dyn].p_filesz + DynAdr - 8);
624
        WR.Write32LE(File, 00000101H);
573
        WR.Write32LE(00000101H);
625
        WR.Write32LE(File, phdr[dyn].p_filesz + Offset.dyn + BaseAdr - 4);
574
        WR.Write32LE(phdr[dyn].p_filesz + DynAdr - 4);
-
 
575
        WR.Write32LE(00000201H)
-
 
576
 
626
        WR.Write32LE(File, 00000201H);
577
    END;
627
 
578
    
628
        WR.Write32LE(File, symCount);
579
    WR.Write32LE(symCount);
629
        WR.Write32LE(File, symCount);
580
    WR.Write32LE(symCount);
630
 
581
 
631
        FOR i := 0 TO symCount - 1 DO
582
    FOR i := 0 TO symCount - 1 DO
632
            WR.Write32LE(File, CHL.GetInt(bucket, i))
583
        WR.Write32LE(CHL.GetInt(bucket, i))
633
        END;
584
    END;
634
 
585
 
635
        FOR i := 0 TO symCount - 1 DO
586
    FOR i := 0 TO symCount - 1 DO
636
            WR.Write32LE(File, CHL.GetInt(chain, i))
587
        WR.Write32LE(CHL.GetInt(chain, i))
637
        END;
588
    END;
638
 
589
 
639
        CHL.WriteToFile(File, strtab);
-
 
640
        WR.Write32LE(File, 0);
-
 
-
 
590
    CHL.WriteToFile(strtab);
-
 
591
        
-
 
592
    IF amd64 THEN
-
 
593
        WR.Write64LE(0);
-
 
594
        WR.Write64LE(0)
-
 
595
    ELSE
641
        WR.Write32LE(File, 0)
596
        WR.Write32LE(0);
642
 
597
        WR.Write32LE(0)    
643
    END;
598
    END;    
644
 
599
 
645
    CHL.WriteToFile(File, program.code);
600
    CHL.WriteToFile(program.code);
646
    WHILE pad > 0 DO
601
    WHILE pad > 0 DO
647
        WR.WriteByte(File, 0);
602
        WR.WriteByte(0);
648
        DEC(pad)
603
        DEC(pad)
-
 
604
    END;
649
    END;
605
    CHL.WriteToFile(program.data);
650
    CHL.WriteToFile(File, program.data);
606
    WR.Close;
651
    WR.Close(File)
607
    UTILS.chmod(FileName)
652
END write;
608
END write;
653
 
609
 
654
 
610
 
655
END ELF.
611
END ELF.