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