initial commit: a mess of assembly code
[fmap.git] / x86_64_sse2_x87 / fasm / examples / x86 / include / format / coff.inc
blobe8bdde7da122e3b13d6bb0a620ba1c15c9eadf11
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 SCNHDR\r
18         s_name          db 8 dup ?\r
19         s_paddr         dd ?\r
20         s_vaddr         dd ?\r
21         s_size          dd ?\r
22         s_scnptr        dd ?\r
23         s_relptr        dd ?\r
24         s_lnnoptr       dd ?\r
25         s_nreloc        dw ?\r
26         s_nlnno         dw ?\r
27         s_flags         dd ?\r
28 end struct\r
30 SCNHSZ = sizeof SCNHDR\r
32 struct RELOC\r
33         r_vaddr         dd ?\r
34         r_symndx        dd ?\r
35         r_type          dw ?\r
36 end struct\r
38 RELSZ = sizeof RELOC\r
40 struct SYMENT\r
41         e_name          db 8 dup ?\r
42     virtual at e_name\r
43         e_zeroes        dd ?\r
44         e_offset        dd ?\r
45     end virtual\r
46         e_value         dd ?\r
47         e_scnum         dw ?\r
48         e_type          dw ?\r
49         e_sclass        db ?\r
50         e_numaux        db ?\r
51 end struct\r
53 SYMESZ = sizeof SYMENT\r
55 I386MAGIC = 0x14c\r
57 F_RELFLG = 0x0001\r
58 F_EXEC   = 0x0002\r
59 F_LNNO   = 0x0004\r
60 F_LSYMS  = 0x0008\r
61 F_AR32WR = 0x0100\r
63 STYP_TEXT = 0x0020\r
64 STYP_DATA = 0x0040\r
65 STYP_BSS  = 0x0080\r
67 N_UNDEF = 0\r
68 N_ABS   = -1\r
69 N_DEBUG = -2\r
71 T_NULL   = 0000b\r
72 T_VOID   = 0001b\r
73 T_CHAR   = 0010b\r
74 T_SHORT  = 0011b\r
75 T_INT    = 0100b\r
76 T_LONG   = 0101b\r
77 T_FLOAT  = 0110b\r
78 T_DOUBLE = 0111b\r
79 T_STRUCT = 1000b\r
80 T_UNION  = 1001b\r
81 T_ENUM   = 1010b\r
82 T_MOE    = 1011b\r
83 T_UCHAR  = 1100b\r
84 T_USHORT = 1101b\r
85 T_UINT   = 1110b\r
86 T_ULONG  = 1111b\r
87 T_LNGDBL = 01_0000b\r
89 DT_NON   = 00b\r
90 DT_PTR   = 01b\r
91 DT_FCN   = 10b\r
92 DT_ARY   = 11b\r
94 C_NULL    = 0\r
95 C_AUTO    = 1\r
96 C_EXT     = 2\r
97 C_STAT    = 3\r
98 C_REG     = 4\r
99 C_EXTDEF  = 5\r
100 C_LABEL   = 6\r
101 C_ULABEL  = 7\r
102 C_MOS     = 8\r
103 C_ARG     = 9\r
104 C_STRTAG  = 10\r
105 C_MOU     = 11\r
106 C_UNTAG   = 12\r
107 C_TPDEF   = 13\r
108 C_USTATIC = 14\r
109 C_ENTAG   = 15\r
110 C_MOE     = 16\r
111 C_REGPARM = 17\r
112 C_FIELD   = 18\r
113 C_AUTOARG = 19\r
114 C_LASTENT = 20\r
115 C_BLOCK   = 100\r
116 C_FCN     = 101\r
117 C_EOS     = 102\r
118 C_FILE    = 103\r
119 C_LINE    = 104\r
120 C_ALIAS   = 105\r
121 C_HIDDEN  = 106\r
122 C_EFCN    = 255\r
124 RELOC_ADDR32 = 6\r
125 RELOC_REL32  = 20\r
127 COFF::\r
129 namespace COFF\r
131         Header:\r
133         f_magic         dw I386MAGIC\r
134         f_nscns         dw NUMBER_OF_SECTIONS\r
135         f_timdat        dd __TIME__\r
136         f_symptr        dd SYMBOL_TABLE_OFFSET\r
137         f_nsyms         dd NUMBER_OF_SYMBOLS\r
138         f_opthdr        dw 0\r
139         f_flags         dw F_AR32WR + F_LNNO\r
141         Sections:       db NUMBER_OF_SECTIONS * SCNHSZ dup 0\r
143         virtual at 0\r
144                 symbol_table:: rb NUMBER_OF_SYMBOLS * SYMESZ\r
145         end virtual\r
147         virtual at 0\r
148                 string_table:: dd STRING_TABLE_SIZE\r
149                 STRING_POSITION = $\r
150                 rb STRING_TABLE_SIZE - $\r
151         end virtual\r
153         virtual at 0\r
154                 relocations:: rb NUMBER_OF_RELOCATIONS * RELSZ\r
155         end virtual\r
157         element relocatable?\r
159         macro section_start\r
160                 local sym\r
161                 element sym : relocatable * (1+SECTION_INDEX) + SYMBOL_INDEX\r
162                 SECTION_BASE = sym\r
163                 org sym\r
164                 if DEFINED_SECTION | DEFAULT_SECTION_PRESENT\r
165                         store SECTION_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name\r
166                         store C_STAT at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass\r
167                         store 1+SECTION_INDEX at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_scnum\r
168                         SYMBOL_INDEX = SYMBOL_INDEX + 1\r
169                 end if\r
170         end macro\r
172         RELOCATION_INDEX = 0\r
173         SECTION_INDEX = 0\r
174         SECTION_RELOCATION_INDEX = RELOCATION_INDEX\r
175         SYMBOL_INDEX = 0\r
177         SECTION_OFFSET = $%\r
178         SECTION_ALIGN = 4\r
179         SECTION_NAME = '.flat'\r
180         SECTION_FLAGS = STYP_TEXT + STYP_DATA\r
181         DEFINED_SECTION = 0\r
182         DEFAULT_SECTION_PRESENT = 0\r
183         section_start\r
185 end namespace\r
187 macro section?\r
188         namespace COFF\r
190                 SECTION_SIZE = $% - SECTION_OFFSET\r
192                 if DEFINED_SECTION | SECTION_SIZE > 0\r
194                         if ~ DEFINED_SECTION\r
195                                 DEFAULT_SECTION_PRESENT = 1\r
196                         end if\r
198                         if $%% = SECTION_OFFSET\r
199                                 SECTION_FLAGS = SECTION_FLAGS or STYP_BSS\r
200                                 SECTION_OFFSET = 0\r
201                                 section $\r
202                         else\r
203                                 UNINITIALIZED_LENGTH = $% - $%%\r
204                                 section $\r
205                                 db UNINITIALIZED_LENGTH dup 0\r
206                         end if\r
208                         store SECTION_NAME : 8 at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_name\r
209                         store SECTION_OFFSET at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_scnptr\r
210                         store SECTION_SIZE at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_size\r
211                         store SECTION_FLAGS at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_flags\r
213                         if RELOCATION_INDEX > SECTION_RELOCATION_INDEX\r
214                                 store RELOCATION_INDEX - SECTION_RELOCATION_INDEX at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_nreloc\r
215                                 store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * RELSZ at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_relptr\r
216                         end if\r
218                         SECTION_INDEX = SECTION_INDEX + 1\r
220                 end if\r
222         end namespace\r
223 end macro\r
225 macro section? declaration*\r
226         namespace COFF\r
228                 section\r
230                 DEFINED_SECTION = 1\r
231                 SECTION_FLAGS = 0\r
232                 SECTION_OFFSET = $%\r
233                 SECTION_ALIGN = 4\r
235                 match name attributes, declaration\r
237                         SECTION_NAME = name\r
239                         local seq,list\r
240                         define seq attributes\r
241                         while 1\r
242                                 match car cdr, seq\r
243                                         define list car\r
244                                         define seq cdr\r
245                                 else\r
246                                         match any, seq\r
247                                                 define list any\r
248                                         end match\r
249                                         break\r
250                                 end match\r
251                         end while\r
252                         irpv attribute, list\r
253                                 match =code?, attribute\r
254                                         SECTION_FLAGS = SECTION_FLAGS or STYP_TEXT\r
255                                 else match =data?, attribute\r
256                                         SECTION_FLAGS = SECTION_FLAGS or STYP_DATA\r
257                                 else\r
258                                         err 'unknown attribute "',`attribute,'"'\r
259                                 end match\r
260                         end irpv\r
262                 else\r
264                         SECTION_NAME = declaration\r
266                 end match\r
268                 section_start\r
270                 SECTION_RELOCATION_INDEX = RELOCATION_INDEX\r
272         end namespace\r
273 end macro\r
275 calminstruction align? boundary,value:?\r
276         check   COFF.SECTION_ALIGN mod (boundary) = 0\r
277         jyes    allowed\r
278         arrange value, =err 'section not aligned enough'\r
279         assemble value\r
280         exit\r
281     allowed:\r
282         compute boundary, (boundary-1)-($-COFF.SECTION_BASE+boundary-1) mod boundary\r
283         arrange value, =db boundary =dup value\r
284         assemble value\r
285 end calminstruction\r
287 macro public? declaration*\r
288         namespace COFF\r
289                 match =static? value =as? str, declaration\r
290                         SYMBOL_VALUE = value\r
291                         SYMBOL_NAME = string str\r
292                         SYMBOL_CLASS = C_STAT\r
293                 else match value =as? str, declaration\r
294                         SYMBOL_VALUE = value\r
295                         SYMBOL_NAME = string str\r
296                         SYMBOL_CLASS = C_EXT\r
297                 else match =static? value, declaration\r
298                         SYMBOL_VALUE = value\r
299                         SYMBOL_NAME = `value\r
300                         SYMBOL_CLASS = C_STAT\r
301                 else\r
302                         SYMBOL_VALUE = declaration\r
303                         SYMBOL_NAME = `declaration\r
304                         SYMBOL_CLASS = C_EXT\r
305                 end match\r
306                 if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & 1 scaleof (1 metadataof SYMBOL_VALUE) > 0\r
307                         SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE)\r
308                         SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE\r
309                 else\r
310                         SYMBOL_SECTION_INDEX = N_ABS\r
311                 end if\r
312                 if lengthof SYMBOL_NAME > 8\r
313                         store 0 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_zeroes\r
314                         store STRING_POSITION at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_offset\r
315                         store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION\r
316                         STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1\r
317                 else\r
318                         store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name\r
319                 end if\r
320                 store SYMBOL_VALUE at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_value\r
321                 store SYMBOL_SECTION_INDEX at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_scnum\r
322                 store SYMBOL_CLASS at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass\r
323                 SYMBOL_INDEX = SYMBOL_INDEX + 1\r
324         end namespace\r
325 end macro\r
327 macro extrn? declaration*\r
328         namespace COFF\r
329                 local sym,psym\r
330                 element sym : relocatable * (-1) + SYMBOL_INDEX\r
331                 match str =as? name:size, declaration\r
332                         label name:size at sym\r
333                         SYMBOL_NAME = string str\r
334                 else match name:size, declaration\r
335                         label name:size at sym\r
336                         SYMBOL_NAME = `name\r
337                 else match str =as? name, declaration\r
338                         label name at sym\r
339                         SYMBOL_NAME = string str\r
340                 else\r
341                         label declaration at sym\r
342                         SYMBOL_NAME = `declaration\r
343                 end match\r
344                 if lengthof SYMBOL_NAME > 8\r
345                         store 0 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_zeroes\r
346                         store STRING_POSITION at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_offset\r
347                         store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION\r
348                         STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1\r
349                 else\r
350                         store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name\r
351                 end if\r
352                 store C_EXT at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass\r
353                 SYMBOL_INDEX = SYMBOL_INDEX + 1\r
354         end namespace\r
355 end macro\r
357 calminstruction calminstruction?.init? var*, val:0\r
358         compute val, val\r
359         publish var, val\r
360 end calminstruction\r
362 calminstruction calminstruction?.initsym? var*, val&\r
363         publish var, val\r
364 end calminstruction\r
366 calminstruction calminstruction?.unique? name\r
367         local counter, buffer\r
368         init counter\r
369         compute counter, counter + 1\r
370         arrange buffer, name#counter\r
371         publish name, buffer\r
372 end calminstruction\r
374 calminstruction calminstruction?.asm? line&\r
375         local tmp, ln, buffer\r
376         initsym tmp, unique ln\r
377         assemble tmp\r
378         publish ln, line\r
379         arrange buffer, =assemble ln\r
380         assemble buffer\r
381 end calminstruction\r
383 calminstruction dword? value\r
384         compute value, value\r
385         check   ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable\r
386         jyes    addr32\r
387         check   ~ value relativeto 0 & (value + COFF.SECTION_BASE) relativeto 1 elementof (value + COFF.SECTION_BASE)\r
388         jno     plain\r
389         check   1 elementof (1 metadataof (value + COFF.SECTION_BASE)) relativeto COFF.relocatable\r
390         jyes    rel32\r
391     plain:\r
392         asm     emit 4: value\r
393         exit\r
394         local   offset, symndx, type\r
395     addr32:\r
396         compute symndx, 0 scaleof (1 metadataof value)\r
397         compute type, RELOC_ADDR32\r
398         jump    add_relocation\r
399     rel32:\r
400         compute value, value + COFF.SECTION_BASE\r
401         compute symndx, 0 scaleof (1 metadataof value)\r
402         compute type, RELOC_REL32\r
403         jump    add_relocation\r
404     add_relocation:\r
405         compute offset, $%\r
406         asm     emit 4: 0 scaleof value\r
407         check   $% > offset\r
408         jno     done\r
409         compute offset, offset - COFF.SECTION_OFFSET\r
410         local   reloc\r
411         compute reloc, COFF.RELOCATION_INDEX * RELSZ\r
412         asm     store offset at COFF.relocations : reloc + RELOC.r_vaddr\r
413         asm     store symndx at COFF.relocations : reloc + RELOC.r_symndx\r
414         asm     store type at COFF.relocations : reloc + RELOC.r_type\r
415         compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1\r
416     done:\r
417 end calminstruction\r
419 calminstruction dd? definitions&\r
420         local   value, n\r
421     start:\r
422         match   value=,definitions, definitions, ()\r
423         jyes    recognize\r
424         match   value, definitions\r
425         arrange definitions,\r
426     recognize:\r
427         match   n =dup? value, value, ()\r
428         jyes    duplicate\r
429         match   ?, value\r
430         jyes    reserve\r
431         arrange value, =dword value\r
432         assemble value\r
433     next:\r
434         match   , definitions\r
435         jno     start\r
436         take    , definitions\r
437         take    definitions, definitions\r
438         jyes    next\r
439         exit\r
440     reserve:\r
441         arrange value, =dd ?\r
442         assemble value\r
443         jump    next\r
444     duplicate:\r
445         match   (value), value\r
446     stack:\r
447         check   n\r
448         jno     next\r
449         take    definitions, value\r
450         arrange value, definitions\r
451         compute n, n - 1\r
452         jump    stack\r
453 end calminstruction\r
455 calminstruction (label) dd? definitions&\r
456         local   cmd\r
457         arrange cmd, =label label : =dword\r
458         assemble cmd\r
459         arrange cmd, =dd definitions\r
460         assemble cmd\r
461 end calminstruction\r
463 postpone\r
464         purge section?\r
465         section\r
466         namespace COFF\r
468                 NUMBER_OF_SECTIONS := SECTION_INDEX\r
469                 STRING_TABLE_SIZE := STRING_POSITION\r
470                 NUMBER_OF_SYMBOLS := SYMBOL_INDEX\r
471                 NUMBER_OF_RELOCATIONS := RELOCATION_INDEX\r
473                 RELOCATIONS_OFFSET = $%\r
474                 load byte_sequence : NUMBER_OF_RELOCATIONS * RELSZ from relocations:0\r
475                 db byte_sequence\r
477                 SYMBOL_TABLE_OFFSET = $%\r
478                 load byte_sequence : NUMBER_OF_SYMBOLS * SYMESZ from symbol_table:0\r
479                 db byte_sequence\r
481                 load byte_sequence : STRING_TABLE_SIZE from string_table:0\r
482                 db byte_sequence\r
484         end namespace\r
485 end postpone\r