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