initial commit: a mess of assembly code
[fmap.git] / x86_64_sse2_x87 / fasm / examples / x86 / include / format / elf64.inc
blob42481f3bea86b9f91da348b1cf9eccc8c7804699
1 \r
2 macro struct? name\r
3         macro end?.struct?!\r
4                         end namespace\r
5                 esc end struc\r
6                 virtual at 0\r
7                         name name\r
8                         sizeof.name = $\r
9                 end virtual\r
10                 purge end?.struct?\r
11         end macro\r
12         esc struc name\r
13                 label . : sizeof.name\r
14                 namespace .\r
15 end macro\r
17 struct Elf64_Shdr\r
18         sh_name         dd ?\r
19         sh_type         dd ?\r
20         sh_flags        dq ?\r
21         sh_addr         dq ?\r
22         sh_offset       dq ?\r
23         sh_size         dq ?\r
24         sh_link         dd ?\r
25         sh_info         dd ?\r
26         sh_addralign    dq ?\r
27         sh_entsize      dq ?\r
28 end struct\r
30 struct Elf64_Sym\r
31         st_name         dd ?\r
32         st_info         db ?\r
33         st_other        db ?\r
34         st_shndx        dw ?\r
35         st_value        dq ?\r
36         st_size         dq ?\r
37 end struct\r
39 struct Elf64_Rel\r
40         r_offset        dq ?\r
41         r_info          dq ?\r
42 end struct\r
44 struct Elf64_Rela\r
45         r_offset        dq ?\r
46         r_info          dq ?\r
47         r_addend        dq ?\r
48 end struct\r
50 struct Elf64_Phdr\r
51         p_type          dd ?\r
52         p_flags         dd ?\r
53         p_offset        dq ?\r
54         p_vaddr         dq ?\r
55         p_paddr         dq ?\r
56         p_filesz        dq ?\r
57         p_memsz         dq ?\r
58         p_align         dq ?\r
59 end struct\r
61 purge struct?\r
63 ELFCLASSNONE = 0\r
64 ELFCLASS32   = 1\r
65 ELFCLASS64   = 2\r
67 ELFDATANONE = 0\r
68 ELFDATA2LSB = 1\r
69 ELFDATA2MSB = 2\r
71 ELFOSABI_NONE     = 0\r
72 ELFOSABI_HPUX     = 1\r
73 ELFOSABI_NETBSD   = 2\r
74 ELFOSABI_GNU      = 3\r
75 ELFOSABI_LINUX    = 3\r
76 ELFOSABI_SOLARIS  = 6\r
77 ELFOSABI_AIX      = 7\r
78 ELFOSABI_IRIX     = 8\r
79 ELFOSABI_FREEBSD  = 9\r
80 ELFOSABI_TRU64    = 10\r
81 ELFOSABI_MODESTO  = 11\r
82 ELFOSABI_OPENBSD  = 12\r
83 ELFOSABI_OPENVMS  = 13\r
84 ELFOSABI_NSK      = 14\r
85 ELFOSABI_AROS     = 15\r
86 ELFOSABI_FENIXOS  = 16\r
87 ELFOSABI_CLOUDABI = 17\r
88 ELFOSABI_OPENVOS  = 18\r
90 ET_NONE   = 0\r
91 ET_REL    = 1\r
92 ET_EXEC   = 2\r
93 ET_DYN    = 3\r
94 ET_CORE   = 4\r
95 ET_LOPROC = 0xff00\r
96 ET_HIPROC = 0xffff\r
98 EM_NONE   = 0\r
99 EM_IA_64  = 50\r
100 EM_X86_64 = 62\r
102 EV_NONE    = 0\r
103 EV_CURRENT = 1\r
105 SHN_UNDEF     = 0\r
106 SHN_LORESERVE = 0xff00\r
107 SHN_LOPROC    = 0xff00\r
108 SHN_HIPROC    = 0xff1f\r
109 SHN_ABS       = 0xfff1\r
110 SHN_COMMON    = 0xfff2\r
111 SHN_HIRESERVE = 0xffff\r
113 SHT_NULL        = 0\r
114 SHT_PROGBITS    = 1\r
115 SHT_SYMTAB      = 2\r
116 SHT_STRTAB      = 3\r
117 SHT_RELA        = 4\r
118 SHT_HASH        = 5\r
119 SHT_DYNAMIC     = 6\r
120 SHT_NOTE        = 7\r
121 SHT_NOBITS      = 8\r
122 SHT_REL         = 9\r
123 SHT_SHLIB       = 10\r
124 SHT_DYNSYM      = 11\r
125 SHT_LOPROC      = 0x70000000\r
126 SHT_HIPROC      = 0x7fffffff\r
127 SHT_LOUSER      = 0x80000000\r
128 SHT_HIUSER      = 0xffffffff\r
130 SHF_WRITE       = 0x1\r
131 SHF_ALLOC       = 0x2\r
132 SHF_EXECINSTR   = 0x4\r
133 SHF_MASKPROC    = 0xf0000000\r
135 STT_NOTYPE      = 0\r
136 STT_OBJECT      = 1\r
137 STT_FUNC        = 2\r
138 STT_SECTION     = 3\r
139 STT_FILE        = 4\r
140 STT_LOPROC      = 13\r
141 STT_HIPROC      = 15\r
143 STB_LOCAL       = 0\r
144 STB_GLOBAL      = 1\r
145 STB_WEAK        = 2\r
146 STB_LOPROC      = 13\r
147 STB_HIPROC      = 15\r
149 R_X86_64_NONE      = 0\r
150 R_X86_64_64        = 1\r
151 R_X86_64_PC32      = 2\r
152 R_X86_64_GOT32     = 3\r
153 R_X86_64_PLT32     = 4\r
154 R_X86_64_COPY      = 5\r
155 R_X86_64_GLOB_DAT  = 6\r
156 R_X86_64_JUMP_SLOT = 7\r
157 R_X86_64_RELATIVE  = 8\r
158 R_X86_64_GOTPCREL  = 9\r
159 R_X86_64_32        = 10\r
160 R_X86_64_32S       = 11\r
161 R_X86_64_16        = 12\r
162 R_X86_64_PC16      = 13\r
163 R_X86_64_8         = 14\r
164 R_X86_64_PC8       = 15\r
165 R_X86_64_DPTMOD64  = 16\r
166 R_X86_64_DTPOFF64  = 17\r
167 R_X86_64_TPOFF64   = 18\r
168 R_X86_64_TLSGD     = 19\r
169 R_X86_64_TLSLD     = 20\r
170 R_X86_64_DTPOFF32  = 21\r
171 R_X86_64_GOTTPOFF  = 22\r
172 R_X86_64_TPOFF32   = 23\r
173 R_X86_64_PC64      = 24\r
174 R_X86_64_GOTOFF64  = 25\r
175 R_X86_64_GOTPC32   = 26\r
177 ELF::\r
179 namespace ELF\r
181         if defined Settings.Machine\r
182                 MACHINE := Settings.Machine\r
183         else\r
184                 MACHINE := EM_X86_64\r
185         end if\r
187         if defined Settings.ABI\r
188                 ABI := Settings.ABI\r
189         else\r
190                 ABI := ELFOSABI_NONE\r
191         end if\r
193         if MACHINE = EM_X86_64\r
194                 R_64 = R_X86_64_64\r
195                 R_32 = R_X86_64_32S\r
196                 R_PC32 = R_X86_64_PC32\r
197                 R_PLT32 = R_X86_64_PLT32\r
198         end if\r
200         Header:\r
202         e_ident         db 0x7F,'ELF',ELFCLASS64,ELFDATA2LSB,EV_CURRENT,ABI,(16-$) dup 0\r
203         e_type          dw ET_REL\r
204         e_machine       dw MACHINE\r
205         e_version       dd EV_CURRENT\r
206         e_entry         dq 0\r
207         e_phoff         dq 0\r
208         e_shoff         dq SECTION_TABLE_OFFSET\r
209         e_flags         dd 0\r
210         e_ehsize        dw Content\r
211         e_phentsize     dw 0\r
212         e_phnum         dw 0\r
213         e_shentsize     dw sizeof Elf64_Shdr\r
214         e_shnum         dw NUMBER_OF_SECTIONS\r
215         e_shstrndx      dw STRING_TABLE_SECTION_INDEX\r
217         Content:\r
219         virtual at 0\r
220                 section_table:: rb NUMBER_OF_SECTIONS * sizeof Elf64_Shdr\r
221         end virtual\r
223         virtual at 0\r
224                 symbol_table:: rb NUMBER_OF_SYMBOLS * sizeof Elf64_Sym\r
225         end virtual\r
227         virtual at 0\r
228                 string_table::\r
229                 _null db 0\r
230                 _symtab db '.symtab',0\r
231                 _strtab db '.strtab',0\r
232                 SECTION_NAME_POSITION = $\r
233                 rb SECTION_NAME_TABLE_SIZE - $\r
234                 STRING_POSITION = $\r
235                 rb STRING_TABLE_SIZE - $\r
236         end virtual\r
238         virtual at 0\r
239                 relocations:: rb NUMBER_OF_RELOCATIONS * sizeof Elf64_Rela\r
240         end virtual\r
242         element relocatable?\r
244         macro section_org\r
245                 local sym\r
246                 element sym : relocatable * SECTION_INDEX + SECTION_SYMBOL_INDEX\r
247                 SECTION_BASE = sym\r
248                 org sym\r
249         end macro\r
251         RELOCATION_INDEX = 0\r
252         SECTION_INDEX = 1\r
253         SECTION_SYMBOL_INDEX = SECTION_INDEX\r
254         SECTION_RELOCATION_INDEX = RELOCATION_INDEX\r
255         SYMBOL_INDEX = NUMBER_OF_SECTION_SYMBOLS\r
257         SECTION_OFFSET = $%\r
258         SECTION_ALIGN = 8\r
259         SECTION_NAME = '.flat'\r
260         SECTION_FLAGS = SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR\r
261         DEFINED_SECTION = 0\r
262         section_org\r
264 end namespace\r
266 macro section?\r
267         namespace ELF\r
269                 SECTION_SIZE = $% - SECTION_OFFSET\r
271                 if DEFINED_SECTION | SECTION_SIZE > 0\r
273                         store SECTION_OFFSET at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr\r
274                         store SECTION_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr\r
275                         store SECTION_ALIGN at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr\r
276                         store SECTION_FLAGS at section_table : Elf64_Shdr.sh_flags + SECTION_INDEX * sizeof Elf64_Shdr\r
278                         if $%% = SECTION_OFFSET\r
279                                 store SHT_NOBITS at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr\r
280                                 section $\r
281                         else\r
282                                 store SHT_PROGBITS at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr\r
283                                 UNINITIALIZED_LENGTH = $% - $%%\r
284                                 section $\r
285                                 db UNINITIALIZED_LENGTH dup 0\r
286                         end if\r
288                         store SECTION_INDEX at symbol_table : Elf64_Sym.st_shndx + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym\r
289                         store STT_SECTION + STB_LOCAL shl 4 at symbol_table : Elf64_Sym.st_info + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym\r
291                         if RELOCATION_INDEX > SECTION_RELOCATION_INDEX\r
293                                 store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_offset + (SECTION_INDEX+1) * sizeof Elf64_Shdr\r
294                                 store (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_size + (SECTION_INDEX+1) * sizeof Elf64_Shdr\r
295                                 store SHT_RELA at section_table : Elf64_Shdr.sh_type + (SECTION_INDEX+1) * sizeof Elf64_Shdr\r
296                                 store SYMBOL_TABLE_SECTION_INDEX at section_table : Elf64_Shdr.sh_link + (SECTION_INDEX+1) * sizeof Elf64_Shdr\r
297                                 store SECTION_INDEX at section_table : Elf64_Shdr.sh_info + (SECTION_INDEX+1) * sizeof Elf64_Shdr\r
298                                 store sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_entsize + (SECTION_INDEX+1) * sizeof Elf64_Shdr\r
299                                 store 8 at section_table : Elf64_Shdr.sh_addralign + (SECTION_INDEX+1) * sizeof Elf64_Shdr\r
301                                 store SECTION_NAME_POSITION at section_table : Elf64_Shdr.sh_name + (SECTION_INDEX+1) * sizeof Elf64_Shdr\r
302                                 store SECTION_NAME_POSITION + 5 at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr\r
303                                 store SECTION_NAME_POSITION + 5 at symbol_table : Elf64_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym\r
304                                 store '.rela' + SECTION_NAME shl (5*8) : 5 + lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION\r
305                                 SECTION_NAME_POSITION = SECTION_NAME_POSITION + 5 + lengthof (string SECTION_NAME) + 1\r
307                                 SECTION_INDEX = SECTION_INDEX + 2\r
308                                 SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1\r
310                         else\r
311                                 store SECTION_NAME_POSITION at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr\r
312                                 store SECTION_NAME_POSITION at symbol_table : Elf64_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym\r
313                                 store SECTION_NAME : lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION\r
314                                 SECTION_NAME_POSITION = SECTION_NAME_POSITION + lengthof (string SECTION_NAME) + 1\r
316                                 SECTION_INDEX = SECTION_INDEX + 1\r
317                                 SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1\r
319                         end if\r
321                 end if\r
323         end namespace\r
324 end macro\r
326 macro section? declaration*\r
327         namespace ELF\r
329                 section\r
331                 DEFINED_SECTION = 1\r
332                 SECTION_FLAGS = SHF_ALLOC\r
333                 SECTION_OFFSET = $%\r
334                 SECTION_ALIGN = 8\r
336                 match name attributes, declaration\r
338                         SECTION_NAME = name\r
340                         local seq,list\r
341                         match flags =align? boundary, attributes\r
342                                 SECTION_ALIGN = boundary\r
343                                 define seq flags\r
344                         else match =align? boundary, attributes\r
345                                 SECTION_ALIGN = boundary\r
346                                 define seq\r
347                         else\r
348                                 define seq attributes\r
349                         end match\r
350                         while 1\r
351                                 match car cdr, seq\r
352                                         define list car\r
353                                         define seq cdr\r
354                                 else\r
355                                         match any, seq\r
356                                                 define list any\r
357                                         end match\r
358                                         break\r
359                                 end match\r
360                         end while\r
361                         irpv attribute, list\r
362                                 match =writeable?, attribute\r
363                                         SECTION_FLAGS = SECTION_FLAGS or SHF_WRITE\r
364                                 else match =executable?, attribute\r
365                                         SECTION_FLAGS = SECTION_FLAGS or SHF_EXECINSTR\r
366                                 else\r
367                                         err 'unknown attribute "',`attribute,'"'\r
368                                 end match\r
369                         end irpv\r
371                 else\r
373                         SECTION_NAME = declaration\r
375                 end match\r
377                 section_org\r
379                 SECTION_RELOCATION_INDEX = RELOCATION_INDEX\r
381         end namespace\r
382 end macro\r
384 calminstruction align? boundary,value:?\r
385         check   ELF.SECTION_ALIGN mod (boundary) = 0\r
386         jyes    allowed\r
387         arrange value, =err 'section not aligned enough'\r
388         assemble value\r
389         exit\r
390     allowed:\r
391         compute boundary, (boundary-1)-($-ELF.SECTION_BASE+boundary-1) mod boundary\r
392         arrange value, =db boundary =dup value\r
393         assemble value\r
394 end calminstruction\r
396 macro public? declaration*\r
397         namespace ELF\r
398                 match value =as? str, declaration\r
399                         SYMBOL_VALUE = value\r
400                         SYMBOL_SIZE = sizeof value\r
401                         SYMBOL_NAME = string str\r
402                 else\r
403                         SYMBOL_VALUE = declaration\r
404                         SYMBOL_SIZE = sizeof declaration\r
405                         SYMBOL_NAME = `declaration\r
406                 end match\r
407                 if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & 1 scaleof (1 metadataof SYMBOL_VALUE) > 0\r
408                         SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE)\r
409                         SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE\r
410                 else\r
411                         SYMBOL_SECTION_INDEX = SHN_ABS\r
412                 end if\r
413                 store STRING_POSITION at symbol_table : Elf64_Sym.st_name + SYMBOL_INDEX * sizeof Elf64_Sym\r
414                 store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION\r
415                 STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1\r
416                 store SYMBOL_VALUE at symbol_table : Elf64_Sym.st_value + SYMBOL_INDEX * sizeof Elf64_Sym\r
417                 store SYMBOL_SIZE at symbol_table : Elf64_Sym.st_size + SYMBOL_INDEX * sizeof Elf64_Sym\r
418                 store SYMBOL_SECTION_INDEX at symbol_table : Elf64_Sym.st_shndx + SYMBOL_INDEX * sizeof Elf64_Sym\r
419                 if SYMBOL_SIZE\r
420                         store STT_OBJECT + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym\r
421                 else\r
422                         store STT_FUNC + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym\r
423                 end if\r
424                 SYMBOL_INDEX = SYMBOL_INDEX + 1\r
425         end namespace\r
426 end macro\r
428 macro extrn? declaration*\r
429         namespace ELF\r
430                 local sym,psym\r
431                 element sym : relocatable * (-1) + SYMBOL_INDEX\r
432                 element psym : PLT + SYMBOL_INDEX\r
433                 match str =as? name:size, declaration\r
434                         label name:size at sym\r
435                         label PLT.name at psym\r
436                         SYMBOL_NAME = string str\r
437                         SYMBOL_SIZE = size\r
438                 else match name:size, declaration\r
439                         label name:size at sym\r
440                         label PLT.name at psym\r
441                         SYMBOL_NAME = `name\r
442                         SYMBOL_SIZE = size\r
443                 else match str =as? name, declaration\r
444                         label name at sym\r
445                         label PLT.name at psym\r
446                         SYMBOL_NAME = string str\r
447                         SYMBOL_SIZE = 0\r
448                 else\r
449                         label declaration at sym\r
450                         label PLT.declaration at psym\r
451                         SYMBOL_NAME = `declaration\r
452                         SYMBOL_SIZE = 0\r
453                 end match\r
454                 store STRING_POSITION at symbol_table : Elf64_Sym.st_name + SYMBOL_INDEX * sizeof Elf64_Sym\r
455                 store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION\r
456                 STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1\r
457                 store SYMBOL_SIZE at symbol_table : Elf64_Sym.st_size + SYMBOL_INDEX * sizeof Elf64_Sym\r
458                 store STT_NOTYPE + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym\r
459                 SYMBOL_INDEX = SYMBOL_INDEX + 1\r
460         end namespace\r
461 end macro\r
463 element PLT?\r
465 calminstruction calminstruction?.init? var*, val:0\r
466         compute val, val\r
467         publish var, val\r
468 end calminstruction\r
470 calminstruction calminstruction?.initsym? var*, val&\r
471         publish var, val\r
472 end calminstruction\r
474 calminstruction calminstruction?.unique? name\r
475         local counter, buffer\r
476         init counter\r
477         compute counter, counter + 1\r
478         arrange buffer, name#counter\r
479         publish name, buffer\r
480 end calminstruction\r
482 calminstruction calminstruction?.asm? line&\r
483         local tmp, ln, buffer\r
484         initsym tmp, unique ln\r
485         assemble tmp\r
486         publish ln, line\r
487         arrange buffer, =assemble ln\r
488         assemble buffer\r
489 end calminstruction\r
491 calminstruction dword? value\r
492         compute value, value\r
493         check   ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto ELF.relocatable\r
494         jyes    r_32\r
495         check   ~ value relativeto 0 & (value + ELF.SECTION_BASE) relativeto 1 elementof (value + ELF.SECTION_BASE)\r
496         jno     plain\r
497         check   1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto ELF.relocatable\r
498         jyes    r_pc32\r
499         check   1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto PLT\r
500         jyes    r_plt32\r
501     plain:\r
502         asm     emit 4: value\r
503         exit\r
504         local   offset, addend, info\r
505     r_32:\r
506         compute offset, $%\r
507         asm     emit 4: ?\r
508         check   $% > offset\r
509         jno     done\r
510         compute offset, offset - ELF.SECTION_OFFSET\r
511         compute addend, 0 scaleof value\r
512         compute info, ELF.R_32 + (0 scaleof (1 metadataof value)) shl 32\r
513         jump    add_relocation\r
514     r_pc32:\r
515         compute offset, $%\r
516         asm     emit 4: ?\r
517         check   $% > offset\r
518         jno     done\r
519         compute offset, offset - ELF.SECTION_OFFSET\r
520         compute addend, 0 scaleof (value + ELF.SECTION_BASE + offset)\r
521         compute info, ELF.R_PC32 + (0 scaleof (1 metadataof value)) shl 32\r
522         jump    add_relocation\r
523     r_plt32:\r
524         compute offset, $%\r
525         asm     emit 4: ?\r
526         check   $% > offset\r
527         jno     done\r
528         compute offset, offset - ELF.SECTION_OFFSET\r
529         compute addend, 0 scaleof (value + ELF.SECTION_BASE + offset)\r
530         compute info, ELF.R_PLT32 + (0 scaleof (1 metadataof value)) shl 32\r
531         jump    add_relocation\r
532     add_relocation:\r
533         local   Rela\r
534         compute Rela, ELF.RELOCATION_INDEX * sizeof Elf64_Rela\r
535         asm     store offset at ELF.relocations : Rela + Elf64_Rela.r_offset\r
536         asm     store addend at ELF.relocations : Rela + Elf64_Rela.r_addend\r
537         asm     store info at ELF.relocations : Rela + Elf64_Rela.r_info\r
538         compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1\r
539     done:\r
540 end calminstruction\r
542 calminstruction qword? value\r
543         compute value, value\r
544         check   ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto ELF.relocatable\r
545         jyes    r_64\r
546     plain:\r
547         asm     emit 8: value\r
548         exit\r
549         local   offset, addend, info\r
550     r_64:\r
551         compute offset, $%\r
552         asm     emit 8: ?\r
553         check   $% > offset\r
554         jno     done\r
555         compute offset, offset - ELF.SECTION_OFFSET\r
556         compute addend, 0 scaleof value\r
557         compute info, ELF.R_64 + (0 scaleof (1 metadataof value)) shl 32\r
558     add_relocation:\r
559         local   Rela\r
560         compute Rela, ELF.RELOCATION_INDEX * sizeof Elf64_Rela\r
561         asm     store offset at ELF.relocations : Rela + Elf64_Rela.r_offset\r
562         asm     store addend at ELF.relocations : Rela + Elf64_Rela.r_addend\r
563         asm     store info at ELF.relocations : Rela + Elf64_Rela.r_info\r
564         compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1\r
565     done:\r
566 end calminstruction\r
568 iterate <dd,dword>, dd,dword, dq,qword\r
570         calminstruction dd? definitions&\r
571                 local   value, n\r
572             start:\r
573                 match   value=,definitions, definitions, ()\r
574                 jyes    recognize\r
575                 match   value, definitions\r
576                 arrange definitions,\r
577             recognize:\r
578                 match   n =dup? value, value, ()\r
579                 jyes    duplicate\r
580                 match   ?, value\r
581                 jyes    reserve\r
582                 arrange value, =dword value\r
583                 assemble value\r
584             next:\r
585                 match   , definitions\r
586                 jno     start\r
587                 take    , definitions\r
588                 take    definitions, definitions\r
589                 jyes    next\r
590                 exit\r
591             reserve:\r
592                 arrange value, =dd ?\r
593                 assemble value\r
594                 jump    next\r
595             duplicate:\r
596                 match   (value), value\r
597             stack:\r
598                 check   n\r
599                 jno     next\r
600                 take    definitions, value\r
601                 arrange value, definitions\r
602                 compute n, n - 1\r
603                 jump    stack\r
604         end calminstruction\r
606         calminstruction (label) dd? definitions&\r
607                 local   cmd\r
608                 arrange cmd, =label label : =dword\r
609                 assemble cmd\r
610                 arrange cmd, =dd definitions\r
611                 assemble cmd\r
612         end calminstruction\r
614 end iterate\r
616 postpone\r
617         purge section?\r
618         section\r
619         namespace ELF\r
621                 SECTION_NAME_TABLE_SIZE := SECTION_NAME_POSITION\r
622                 STRING_TABLE_SIZE := STRING_POSITION\r
624                 NUMBER_OF_SECTION_SYMBOLS := SECTION_SYMBOL_INDEX\r
625                 NUMBER_OF_SYMBOLS := SYMBOL_INDEX\r
626                 SYMBOL_TABLE_SIZE := NUMBER_OF_SYMBOLS * sizeof Elf64_Sym\r
628                 NUMBER_OF_RELOCATIONS := RELOCATION_INDEX\r
629                 rb (-$%) and 111b\r
630                 RELOCATIONS_OFFSET = $%\r
631                 load byte_sequence : NUMBER_OF_RELOCATIONS * sizeof Elf64_Rela from relocations:0\r
632                 db byte_sequence\r
634                 store _symtab at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr\r
635                 store $% at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr\r
636                 store SYMBOL_TABLE_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr\r
637                 store sizeof Elf64_Sym at section_table : Elf64_Shdr.sh_entsize + SECTION_INDEX * sizeof Elf64_Shdr\r
638                 store 8 at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr\r
639                 store SHT_SYMTAB at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr\r
640                 store STRING_TABLE_SECTION_INDEX at section_table : Elf64_Shdr.sh_link + SECTION_INDEX * sizeof Elf64_Shdr\r
641                 store NUMBER_OF_SECTION_SYMBOLS at section_table : Elf64_Shdr.sh_info + SECTION_INDEX * sizeof Elf64_Shdr\r
642                 SYMBOL_TABLE_SECTION_INDEX := SECTION_INDEX\r
643                 load byte_sequence : SYMBOL_TABLE_SIZE from symbol_table:0\r
644                 db byte_sequence\r
645                 SECTION_INDEX = SECTION_INDEX + 1\r
647                 store _strtab at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr\r
648                 store $% at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr\r
649                 store STRING_TABLE_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr\r
650                 store 1 at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr\r
651                 store SHT_STRTAB at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr\r
652                 STRING_TABLE_SECTION_INDEX := SECTION_INDEX\r
653                 load byte_sequence : STRING_TABLE_SIZE from string_table:0\r
654                 db byte_sequence\r
655                 SECTION_INDEX = SECTION_INDEX + 1\r
657                 assert SECTION_INDEX <= SHN_LORESERVE\r
659                 NUMBER_OF_SECTIONS := SECTION_INDEX\r
660                 rb (-$%) and 111b\r
661                 SECTION_TABLE_OFFSET := $%\r
662                 load byte_sequence : NUMBER_OF_SECTIONS * sizeof Elf64_Shdr from section_table:0\r
663                 db byte_sequence\r
665         end namespace\r
666 end postpone\r