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. |