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