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