VirtualBox

source: vbox/trunk/include/iprt/asmdefs.mac@ 93176

Last change on this file since 93176 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.4 KB
Line 
1;; @file
2; IPRT - Global YASM/NASM macros
3;
4
5;
6; Copyright (C) 2006-2022 Oracle Corporation
7;
8; This file is part of VirtualBox Open Source Edition (OSE), as
9; available from http://www.virtualbox.org. This file is free software;
10; you can redistribute it and/or modify it under the terms of the GNU
11; General Public License (GPL) as published by the Free Software
12; Foundation, in version 2 as it comes in the "COPYING" file of the
13; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15;
16; The contents of this file may alternatively be used under the terms
17; of the Common Development and Distribution License Version 1.0
18; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19; VirtualBox OSE distribution, in which case the provisions of the
20; CDDL are applicable instead of those of the GPL.
21;
22; You may elect to license modified versions of this file under the
23; terms and conditions of either the GPL or the CDDL or both.
24;
25
26; Special hack for bs3kit.
27%ifdef RT_ASMDEFS_INC_FIRST_FILE
28 %include "asmdefs-first.mac"
29%endif
30
31%ifndef ___iprt_asmdefs_mac
32%define ___iprt_asmdefs_mac
33
34
35;; @defgroup grp_rt_cdefs_size Size Constants
36; (Of course, these are binary computer terms, not SI.)
37; @{
38;; 1 K (Kilo) (1 024).
39%define _1K 000000400h
40;; 4 K (Kilo) (4 096).
41%define _4K 000001000h
42;; 8 K (Kilo) (8 192).
43%define _8K 000002000h
44;; 16 K (Kilo) (16 384).
45%define _16K 000004000h
46;; 32 K (Kilo) (32 768).
47%define _32K 000008000h
48;; 64 K (Kilo) (65 536).
49%define _64K 000010000h
50;; 128 K (Kilo) (131 072).
51%define _128K 000020000h
52;; 256 K (Kilo) (262 144).
53%define _256K 000040000h
54;; 512 K (Kilo) (524 288).
55%define _512K 000080000h
56;; 1 M (Mega) (1 048 576).
57%define _1M 000100000h
58;; 2 M (Mega) (2 097 152).
59%define _2M 000200000h
60;; 4 M (Mega) (4 194 304).
61%define _4M 000400000h
62;; 1 G (Giga) (1 073 741 824).
63%define _1G 040000000h
64;; 2 G (Giga) (2 147 483 648).
65%define _2G 00000000080000000h
66;; 4 G (Giga) (4 294 967 296).
67%define _4G 00000000100000000h
68;; 1 T (Tera) (1 099 511 627 776).
69%define _1T 00000010000000000h
70;; 1 P (Peta) (1 125 899 906 842 624).
71%define _1P 00004000000000000h
72;; 1 E (Exa) (1 152 921 504 606 846 976).
73%define _1E 01000000000000000h
74;; 2 E (Exa) (2 305 843 009 213 693 952).
75%define _2E 02000000000000000h
76;; @}
77
78
79;;
80; Make the mask for the given bit.
81%define RT_BIT(bit) (1 << bit)
82
83;;
84; Make the mask for the given bit.
85%define RT_BIT_32(bit) (1 << bit)
86;;
87; Make the mask for the given bit.
88%define RT_BIT_64(bit) (1 << bit)
89
90;;
91; Makes a 32-bit unsigned (not type safe, but whatever) out of four byte values.
92%define RT_MAKE_U32_FROM_U8(b0, b1, b2, b3) ( (b3 << 24) | (b2 << 16) | (b1 << 8) | b0 )
93
94;; Preprocessor concatenation macro.
95%define RT_CONCAT(a_1,a_2) a_1 %+ a_2
96
97;; Preprocessor concatenation macro, three arguments.
98%define RT_CONCAT3(a_1,a_2,a_3) a_1 %+ a_2 %+ a_3
99
100;; Preprocessor concatenation macro, four arguments.
101%define RT_CONCAT4(a_1,a_2,a_3,a_4) a_1 %+ a_2 %+ a_3 %+ a_4
102
103;;
104; Trick for using RT_CONCAT and the like on %define names.
105; @param 1 The name (expression.
106; @param 2 The value.
107%macro RT_DEFINE_EX 2
108 %error 1=%1 2=%2
109 %define %1 %2
110%endmacro
111
112;;
113; Trick for using RT_CONCAT and the like on %xdefine names.
114; @param 1 The name (expression.
115; @param 2 The value.
116%macro RT_XDEFINE_EX 2
117 %xdefine %1 %2
118%endmacro
119
120;;
121; Trick for using RT_CONCAT and the like on %undef names.
122; @param 1 The name (expression.
123%macro RT_UNDEF_EX 1
124 %error 1=%1
125 %undef %1
126%endmacro
127
128
129;; Define ASM_FORMAT_PE64 if applicable.
130%ifdef ASM_FORMAT_PE
131 %ifdef RT_ARCH_AMD64
132 %define ASM_FORMAT_PE64 1
133 %endif
134%endif
135
136;;
137; SEH64 macros.
138%ifdef RT_ASM_WITH_SEH64
139 %ifndef ASM_FORMAT_PE64
140 %undef RT_ASM_WITH_SEH64
141 %endif
142%endif
143
144%ifdef RT_ASM_WITH_SEH64_ALT
145 %ifdef ASM_FORMAT_PE64
146 ;; @name Register numbers. Used with RT_CONCAT to convert macro inputs to numbers.
147 ;; @{
148 %define SEH64_PE_GREG_rax 0
149 %define SEH64_PE_GREG_xAX 0
150 %define SEH64_PE_GREG_rcx 1
151 %define SEH64_PE_GREG_xCX 1
152 %define SEH64_PE_GREG_rdx 2
153 %define SEH64_PE_GREG_xDX 2
154 %define SEH64_PE_GREG_rbx 3
155 %define SEH64_PE_GREG_xBX 3
156 %define SEH64_PE_GREG_rsp 4
157 %define SEH64_PE_GREG_xSP 4
158 %define SEH64_PE_GREG_rbp 5
159 %define SEH64_PE_GREG_xBP 5
160 %define SEH64_PE_GREG_rsi 6
161 %define SEH64_PE_GREG_xSI 6
162 %define SEH64_PE_GREG_rdi 7
163 %define SEH64_PE_GREG_xDI 7
164 %define SEH64_PE_GREG_r8 8
165 %define SEH64_PE_GREG_r9 9
166 %define SEH64_PE_GREG_r10 10
167 %define SEH64_PE_GREG_r11 11
168 %define SEH64_PE_GREG_r12 12
169 %define SEH64_PE_GREG_r13 13
170 %define SEH64_PE_GREG_r14 14
171 %define SEH64_PE_GREG_r15 15
172 ;; @}
173
174 ;; @name PE unwind operations.
175 ;; @{
176 %define SEH64_PE_PUSH_NONVOL 0
177 %define SEH64_PE_ALLOC_LARGE 1
178 %define SEH64_PE_ALLOC_SMALL 2
179 %define SEH64_PE_SET_FPREG 3
180 %define SEH64_PE_SAVE_NONVOL 4
181 %define SEH64_PE_SAVE_NONVOL_FAR 5
182 %define SEH64_PE_SAVE_XMM128 8
183 %define SEH64_PE_SAVE_XMM128_FAR 9
184 ;; @}
185
186 ;;
187 ; Starts the unwind info for the manual SEH64 info generation.
188 ; @param 1 Function name.
189 %macro SEH64_ALT_START_UNWIND_INFO 1
190 %assign seh64_idxOps 0
191 %assign seh64_FrameReg SEH64_PE_GREG_rsp
192 %assign seh64_offFrame 0
193 %define asm_seh64_proc %1
194 %undef seh64_slot_bytes
195 %endmacro
196
197 ;; We keep the unwind bytes in the seh64_slot_bytes (x)define, in reverse order as per spec.
198 %macro SEH64_APPEND_SLOT_PAIR 2
199 %ifdef seh64_slot_bytes
200 %xdefine seh64_slot_bytes %1, %2, seh64_slot_bytes
201 %else
202 %xdefine seh64_slot_bytes %1, %2
203 %endif
204 %endmacro
205
206 ;; For multi-slot unwind info.
207 %macro SEH64_APPEND_SLOT_BYTES 2+
208 %rep %0
209 %rotate -1
210 %ifdef seh64_slot_bytes
211 %xdefine seh64_slot_bytes %1, seh64_slot_bytes
212 %else
213 %xdefine seh64_slot_bytes %1
214 %endif
215 %endrep
216 %endmacro
217
218 %else
219 %undef RT_ASM_WITH_SEH64_ALT
220 %endif
221%endif
222
223;;
224; Records a xBP push.
225%macro SEH64_PUSH_xBP 0
226 %ifdef RT_ASM_WITH_SEH64
227 [pushreg rbp]
228
229 %elifdef RT_ASM_WITH_SEH64_ALT
230RT_CONCAT(.seh64_op_label_,seh64_idxOps):
231 %ifdef ASM_FORMAT_PE64
232 SEH64_APPEND_SLOT_PAIR RT_CONCAT(.seh64_op_label_,seh64_idxOps) - .start_of_prologue, \
233 SEH64_PE_PUSH_NONVOL | (SEH64_PE_GREG_rbp << 4)
234 %endif
235 %assign seh64_idxOps seh64_idxOps + 1
236 %endif
237%endmacro
238
239;;
240; Records a general register push.
241; @param 1 Register name.
242%macro SEH64_PUSH_GREG 1
243 %ifdef RT_ASM_WITH_SEH64
244 [pushreg %1]
245
246 %elifdef RT_ASM_WITH_SEH64_ALT
247RT_CONCAT(.seh64_op_label_,seh64_idxOps):
248 %ifdef ASM_FORMAT_PE64
249 SEH64_APPEND_SLOT_PAIR RT_CONCAT(.seh64_op_label_,seh64_idxOps) - .start_of_prologue, \
250 SEH64_PE_PUSH_NONVOL | (RT_CONCAT(SEH64_PE_GREG_,%1) << 4)
251 %endif
252 %assign seh64_idxOps seh64_idxOps + 1
253 %endif
254%endmacro
255
256;;
257; Sets xBP as frame pointer that's pointing to a stack position %1 relative to xBP.
258%macro SEH64_SET_FRAME_xBP 1
259 %ifdef RT_ASM_WITH_SEH64
260 [setframe rbp, %1]
261
262 %elifdef RT_ASM_WITH_SEH64_ALT
263RT_CONCAT(.seh64_op_label_,seh64_idxOps):
264 %ifdef ASM_FORMAT_PE64
265 SEH64_APPEND_SLOT_PAIR RT_CONCAT(.seh64_op_label_,seh64_idxOps) - .start_of_prologue, \
266 SEH64_PE_SET_FPREG | 0 ; vs2019 seems to put the offset in the info field
267 %assign seh64_FrameReg SEH64_PE_GREG_rbp
268 %assign seh64_offFrame %1
269 %endif
270 %assign seh64_idxOps seh64_idxOps + 1
271 %endif
272%endmacro
273
274;;
275; Records an ADD xSP, %1.
276%macro SEH64_ALLOCATE_STACK 1
277 %ifdef RT_ASM_WITH_SEH64
278 [allocstack %1]
279
280 %elifdef RT_ASM_WITH_SEH64_ALT
281RT_CONCAT(.seh64_op_label_,seh64_idxOps):
282 %ifdef ASM_FORMAT_PE64
283 %if (%1) & 7
284 %error "SEH64_ALLOCATE_STACK must be a multiple of 8"
285 %endif
286 %if (%1) < 8
287 %error "SEH64_ALLOCATE_STACK must have an argument that's 8 or higher."
288 %elif (%1) <= 128
289 SEH64_APPEND_SLOT_PAIR RT_CONCAT(.seh64_op_label_,seh64_idxOps) - .start_of_prologue, \
290 SEH64_PE_ALLOC_SMALL | ((((%1) / 8) - 1) << 4)
291 %elif (%1) < 512
292 SEH64_APPEND_SLOT_BYTES RT_CONCAT(.seh64_op_label_,seh64_idxOps) - .start_of_prologue, \
293 SEH64_PE_ALLOC_LARGE | 0, \
294 ((%1) / 8) & 0xff, ((%1) / 8) >> 8
295 %else
296 SEH64_APPEND_SLOT_BYTES RT_CONCAT(.seh64_op_label_,seh64_idxOps) - .start_of_prologue, \
297 SEH64_PE_ALLOC_LARGE | 1, \
298 (%1) & 0xff, ((%1) >> 8) & 0xff, ((%1) >> 16) & 0xff, ((%1) >> 24) & 0xff
299 %endif
300 %endif
301 %assign seh64_idxOps seh64_idxOps + 1
302 %endif
303%endmacro
304
305%macro SEH64_INFO_HELPER 1
306%if defined(%1)
307 dw %1
308%endif
309%endmacro
310
311;;
312; Ends the prologue.
313%macro SEH64_END_PROLOGUE 0
314.end_of_prologue:
315 %ifdef RT_ASM_WITH_SEH64
316 [endprolog]
317
318 %elifdef RT_ASM_WITH_SEH64_ALT
319 %ifdef ASM_FORMAT_PE
320 ; Emit the unwind info now.
321 %ifndef ASM_DEFINED_XDATA_SECTION
322 %define ASM_DEFINED_XDATA_SECTION
323 section .xdata rdata align=4
324 %else
325 section .xdata
326 align 4, db 0
327 %endif
328.unwind_info:
329 db 1 ; version 1 (3 bit), no flags (5 bits)
330 db .end_of_prologue - .start_of_prologue
331
332 db (.unwind_info_array_end - .unwind_info_array) / 2
333 db seh64_FrameReg | (seh64_offFrame & 0xf0) ; framereg and offset/16.
334.unwind_info_array:
335 %ifdef seh64_slot_bytes
336 db seh64_slot_bytes
337 %undef seh64_slot_bytes
338 %endif
339.unwind_info_array_end:
340
341 ; Reset the segment
342 BEGINCODE
343 %endif
344 %endif
345%endmacro
346
347
348;;
349; Align code, pad with INT3.
350%define ALIGNCODE(alignment) align alignment, db 0cch
351
352;;
353; Align data, pad with ZEROs.
354%define ALIGNDATA(alignment) align alignment, db 0
355
356;;
357; Align BSS, pad with ZEROs.
358%define ALIGNBSS(alignment) align alignment, resb 1
359
360;;
361; NAME_OVERLOAD can be defined by a .asm module to modify all the
362; names created using the name macros in this files.
363; This is handy when you've got some kind of template code.
364%ifndef NAME_OVERLOAD
365 %ifdef RT_MANGLER_PREFIX
366 %define NAME_OVERLOAD(name) RT_MANGLER_PREFIX %+ name
367 %else
368 %define NAME_OVERLOAD(name) name
369 %endif
370%endif
371
372;;
373; Mangles the given name so it can be referenced using DECLASM() in the
374; C/C++ world.
375%ifndef ASM_FORMAT_BIN
376 %ifdef RT_ARCH_X86
377 %ifdef RT_OS_OS2
378 %define NAME(name) _ %+ NAME_OVERLOAD(name)
379 %endif
380 %ifdef RT_OS_WINDOWS
381 %define NAME(name) _ %+ NAME_OVERLOAD(name)
382 %endif
383 %endif
384 %ifdef RT_OS_DARWIN
385 %define NAME(name) _ %+ NAME_OVERLOAD(name)
386 %endif
387%endif
388%ifndef NAME
389 %define NAME(name) NAME_OVERLOAD(name)
390%endif
391
392;;
393; Mangles the given C name so it will _import_ the right symbol.
394%ifdef ASM_FORMAT_PE
395 %define IMPNAME(name) __imp_ %+ NAME(name)
396%else
397 %define IMPNAME(name) NAME(name)
398%endif
399
400;;
401; Gets the pointer to an imported object.
402%ifdef ASM_FORMAT_PE
403 %ifdef RT_ARCH_AMD64
404 %define IMP(name) qword [IMPNAME(name) wrt rip]
405 %else
406 %define IMP(name) dword [IMPNAME(name)]
407 %endif
408%else
409 %define IMP(name) IMPNAME(name)
410%endif
411
412;;
413; Gets the pointer to an imported object.
414%ifdef ASM_FORMAT_PE
415 %ifdef RT_ARCH_AMD64
416 %define IMP_SEG(SegOverride, name) qword [SegOverride:IMPNAME(name) wrt rip]
417 %else
418 %define IMP_SEG(SegOverride, name) dword [SegOverride:IMPNAME(name)]
419 %endif
420%else
421 %define IMP_SEG(SegOverride, name) IMPNAME(name)
422%endif
423
424;;
425; Declares an imported object for use with IMP2.
426; @note May change the current section!
427%macro EXTERN_IMP2 1
428 extern IMPNAME(%1)
429 BEGINDATA
430 %ifdef ASM_FORMAT_MACHO
431 g_Imp2_ %+ %1: RTCCPTR_DEF IMPNAME(%1)
432 %endif
433%endmacro
434
435;;
436; Gets the pointer to an imported object, version 2.
437%ifdef ASM_FORMAT_PE
438 %ifdef RT_ARCH_AMD64
439 %define IMP2(name) qword [IMPNAME(name) wrt rip]
440 %else
441 %define IMP2(name) dword [IMPNAME(name)]
442 %endif
443%elifdef ASM_FORMAT_ELF
444 %ifdef PIC
445 %ifdef RT_ARCH_AMD64
446 %define IMP2(name) qword [rel IMPNAME(name) wrt ..got]
447 %else
448 %define IMP2(name) IMPNAME(name) wrt ..plt
449 %endif
450 %endif
451%elifdef ASM_FORMAT_MACHO
452 %define IMP2(name) RTCCPTR_PRE [g_Imp2_ %+ name xWrtRIP]
453%endif
454%ifndef IMP2
455 %define IMP2(name) IMPNAME(name)
456%endif
457
458
459
460;;
461; Global marker which is DECLASM() compatible.
462%macro GLOBALNAME 1
463%ifndef ASM_FORMAT_BIN
464global NAME(%1)
465%endif
466NAME(%1):
467%endmacro
468
469;;
470; Global exported marker which is DECLASM() compatible.
471%macro EXPORTEDNAME 1
472 %ifdef ASM_FORMAT_PE
473 export %1=NAME(%1)
474 %endif
475 %ifdef __NASM__
476 %ifdef ASM_FORMAT_OMF
477 export NAME(%1) NAME(%1)
478 %endif
479%endif
480GLOBALNAME %1
481%endmacro
482
483;;
484; Global marker which is DECLASM() compatible.
485%macro GLOBALNAME_EX 2
486%ifndef ASM_FORMAT_BIN
487 %ifdef ASM_FORMAT_ELF
488global NAME(%1):%2
489 %else
490global NAME(%1)
491 %endif
492%endif
493NAME(%1):
494%endmacro
495
496;;
497; Global exported marker which is DECLASM() compatible.
498%macro EXPORTEDNAME_EX 2
499 %ifdef ASM_FORMAT_PE
500 export %1=NAME(%1)
501 %endif
502 %ifdef __NASM__
503 %ifdef ASM_FORMAT_OMF
504 export NAME(%1) NAME(%1)
505 %endif
506%endif
507GLOBALNAME_EX %1, %2
508%endmacro
509
510;;
511; Begins a C callable procedure.
512%macro BEGINPROC 1
513 %ifdef RT_ASM_WITH_SEH64_ALT
514 SEH64_ALT_START_UNWIND_INFO %1
515 %endif
516 %ifdef RT_ASM_WITH_SEH64
517global NAME(%1):function
518proc_frame NAME(%1)
519 %else
520GLOBALNAME_EX %1, function hidden
521 %endif
522.start_of_prologue:
523%endmacro
524
525;;
526; Begins a C callable exported procedure.
527%macro BEGINPROC_EXPORTED 1
528 %ifdef RT_ASM_WITH_SEH64_ALT
529 SEH64_ALT_START_UNWIND_INFO %1
530 %endif
531 %ifdef RT_ASM_WITH_SEH64
532 %ifdef ASM_FORMAT_PE
533export %1=NAME(%1)
534 %endif
535global NAME(%1):function
536proc_frame NAME(%1)
537 %else
538EXPORTEDNAME_EX %1, function
539 %endif
540.start_of_prologue:
541%endmacro
542
543;;
544; Ends a C callable procedure.
545%macro ENDPROC 1
546 %ifdef RT_ASM_WITH_SEH64
547endproc_frame
548 %endif
549GLOBALNAME_EX %1 %+ _EndProc, function hidden
550%ifdef ASM_FORMAT_ELF
551 %ifndef __NASM__ ; nasm does this in the global directive.
552size NAME(%1) NAME(%1 %+ _EndProc) - NAME(%1)
553size NAME(%1 %+ _EndProc) 4 ; make it non-zero to shut up warnigns from Linux's objtool.
554 %endif
555%endif
556 db 0xCC, 0xCC, 0xCC, 0xCC
557
558 %ifdef RT_ASM_WITH_SEH64_ALT
559 %ifdef ASM_FORMAT_PE
560 ; Emit the RUNTIME_FUNCTION entry. The linker is picky here, no label.
561 %ifndef ASM_DEFINED_PDATA_SECTION
562 %define ASM_DEFINED_PDATA_SECTION
563 section .pdata rdata align=4
564 %else
565 section .pdata
566 %endif
567 dd NAME(%1) wrt ..imagebase
568 dd NAME(%1 %+ _EndProc) wrt ..imagebase
569 dd NAME(%1 %+ .unwind_info) wrt ..imagebase
570
571 ; Restore code section.
572 BEGINCODE
573 %endif
574 %endif
575%endmacro
576
577
578;
579; Do OMF and Mach-O/Yasm segment definitions
580;
581; Both format requires this to get the segment order right, in the Mach-O/Yasm case
582; it's only to make sure the .bss section ends up last (it's not declared here).
583;
584%ifdef ASM_FORMAT_OMF
585 %ifndef RT_NOINC_SEGMENTS
586
587 ; 16-bit segments first (OMF / OS/2 specific).
588 %ifdef RT_INCL_16BIT_SEGMENTS
589 segment DATA16 public CLASS=FAR_DATA align=16 use16
590 segment DATA16_INIT public CLASS=FAR_DATA align=16 use16
591 group DGROUP16 DATA16 DATA16_INIT
592
593 ;;
594 ; Begins 16-bit data
595 %macro BEGINDATA16 0
596 segment DATA16
597 %endmacro
598
599 ;;
600 ; Begins 16-bit init data
601 %macro BEGINDATA16INIT 0
602 segment DATA16_INIT
603 %endmacro
604
605 segment CODE16 public CLASS=FAR_CODE align=16 use16
606 segment CODE16_INIT public CLASS=FAR_CODE align=16 use16
607 group CGROUP16 CODE16 CODE16_INIT
608
609 ;;
610 ; Begins 16-bit code
611 %macro BEGINCODE16 0
612 segment CODE16
613 %endmacro
614
615 ;;
616 ; Begins 16-bit init code
617 %macro BEGINCODE16INIT 0
618 segment CODE16_INIT
619 %endmacro
620
621 %endif
622
623 ; 32-bit segments.
624 segment TEXT32 public CLASS=CODE align=16 use32 flat
625 segment DATA32 public CLASS=DATA align=16 use32 flat
626 segment BSS32 public CLASS=BSS align=16 use32 flat
627
628 ; Make the TEXT32 segment default.
629 segment TEXT32
630 %endif ; RT_NOINC_SEGMENTS
631%endif
632
633%ifdef ASM_FORMAT_MACHO
634 %ifdef __YASM__
635 section .text
636 section .data
637 %endif
638%endif
639
640
641;;
642; Begins code
643%ifdef ASM_FORMAT_OMF
644 %macro BEGINCODE 0
645 segment TEXT32
646 %endmacro
647%else
648%macro BEGINCODE 0
649 section .text
650%endmacro
651%endif
652
653;;
654; Begins constant (read-only) data
655;
656; @remarks This is mapped to the CODE section/segment when there isn't
657; any dedicated const section/segment. (There is code that
658; assumes this, so don't try change it.)
659%ifdef ASM_FORMAT_OMF
660 %macro BEGINCONST 0
661 segment TEXT32
662 %endmacro
663%else
664 %macro BEGINCONST 0
665 %ifdef ASM_FORMAT_MACHO ;; @todo check the other guys too.
666 section .rodata
667 %else
668 section .text
669 %endif
670 %endmacro
671%endif
672
673;;
674; Begins initialized data
675%ifdef ASM_FORMAT_OMF
676 %macro BEGINDATA 0
677 segment DATA32
678 %endmacro
679%else
680%macro BEGINDATA 0
681 section .data
682%endmacro
683%endif
684
685;;
686; Begins uninitialized data
687%ifdef ASM_FORMAT_OMF
688 %macro BEGINBSS 0
689 segment BSS32
690 %endmacro
691%else
692%macro BEGINBSS 0
693 section .bss
694%endmacro
695%endif
696
697
698
699;; @def ARCH_BITS
700; Defines the bit count of the current context.
701%ifndef ARCH_BITS
702 %ifdef RT_ARCH_AMD64
703 %define ARCH_BITS 64
704 %else
705 %define ARCH_BITS 32
706 %endif
707%endif
708
709;; @def HC_ARCH_BITS
710; Defines the host architechture bit count.
711%ifndef HC_ARCH_BITS
712 %ifndef IN_RC
713 %define HC_ARCH_BITS ARCH_BITS
714 %else
715 %define HC_ARCH_BITS 32
716 %endif
717%endif
718
719;; @def R3_ARCH_BITS
720; Defines the host ring-3 architechture bit count.
721%ifndef R3_ARCH_BITS
722 %ifdef IN_RING3
723 %define R3_ARCH_BITS ARCH_BITS
724 %else
725 %define R3_ARCH_BITS HC_ARCH_BITS
726 %endif
727%endif
728
729;; @def R0_ARCH_BITS
730; Defines the host ring-0 architechture bit count.
731%ifndef R0_ARCH_BITS
732 %ifdef IN_RING0
733 %define R0_ARCH_BITS ARCH_BITS
734 %else
735 %define R0_ARCH_BITS HC_ARCH_BITS
736 %endif
737%endif
738
739;; @def GC_ARCH_BITS
740; Defines the guest architechture bit count.
741%ifndef GC_ARCH_BITS
742 %ifdef IN_RC
743 %define GC_ARCH_BITS ARCH_BITS
744 %else
745 %define GC_ARCH_BITS 32
746 %endif
747%endif
748
749
750
751;; @def RTHCPTR_DEF
752; The pesudo-instruction used to declare an initialized pointer variable in the host context.
753%if HC_ARCH_BITS == 64
754 %define RTHCPTR_DEF dq
755%else
756 %define RTHCPTR_DEF dd
757%endif
758
759;; @def RTHCPTR_RES
760; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
761; variable of the host context.
762%if HC_ARCH_BITS == 64
763 %define RTHCPTR_RES resq
764%else
765 %define RTHCPTR_RES resd
766%endif
767
768;; @def RTHCPTR_PRE
769; The memory operand prefix used for a pointer in the host context.
770%if HC_ARCH_BITS == 64
771 %define RTHCPTR_PRE qword
772%else
773 %define RTHCPTR_PRE dword
774%endif
775
776;; @def RTHCPTR_CB
777; The size in bytes of a pointer in the host context.
778%if HC_ARCH_BITS == 64
779 %define RTHCPTR_CB 8
780%else
781 %define RTHCPTR_CB 4
782%endif
783
784
785
786;; @def RTR0PTR_DEF
787; The pesudo-instruction used to declare an initialized pointer variable in the ring-0 host context.
788%if R0_ARCH_BITS == 64
789 %define RTR0PTR_DEF dq
790%else
791 %define RTR0PTR_DEF dd
792%endif
793
794;; @def RTR0PTR_RES
795; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
796; variable of the ring-0 host context.
797%if R0_ARCH_BITS == 64
798 %define RTR0PTR_RES resq
799%else
800 %define RTR0PTR_RES resd
801%endif
802
803;; @def RTR0PTR_PRE
804; The memory operand prefix used for a pointer in the ring-0 host context.
805%if R0_ARCH_BITS == 64
806 %define RTR0PTR_PRE qword
807%else
808 %define RTR0PTR_PRE dword
809%endif
810
811;; @def RTR0PTR_CB
812; The size in bytes of a pointer in the ring-0 host context.
813%if R0_ARCH_BITS == 64
814 %define RTR0PTR_CB 8
815%else
816 %define RTR0PTR_CB 4
817%endif
818
819
820
821;; @def RTR3PTR_DEF
822; The pesudo-instruction used to declare an initialized pointer variable in the ring-3 host context.
823%if R3_ARCH_BITS == 64
824 %define RTR3PTR_DEF dq
825%else
826 %define RTR3PTR_DEF dd
827%endif
828
829;; @def RTR3PTR_RES
830; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
831; variable of the ring-3 host context.
832%if R3_ARCH_BITS == 64
833 %define RTR3PTR_RES resq
834%else
835 %define RTR3PTR_RES resd
836%endif
837
838;; @def RTR3PTR_PRE
839; The memory operand prefix used for a pointer in the ring-3 host context.
840%if R3_ARCH_BITS == 64
841 %define RTR3PTR_PRE qword
842%else
843 %define RTR3PTR_PRE dword
844%endif
845
846;; @def RTR3PTR_CB
847; The size in bytes of a pointer in the ring-3 host context.
848%if R3_ARCH_BITS == 64
849 %define RTR3PTR_CB 8
850%else
851 %define RTR3PTR_CB 4
852%endif
853
854
855
856;; @def RTGCPTR_DEF
857; The pesudo-instruction used to declare an initialized pointer variable in the guest context.
858%if GC_ARCH_BITS == 64
859 %define RTGCPTR_DEF dq
860%else
861 %define RTGCPTR_DEF dd
862%endif
863
864;; @def RTGCPTR_RES
865; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
866; variable of the guest context.
867%if GC_ARCH_BITS == 64
868 %define RTGCPTR_RES resq
869%else
870 %define RTGCPTR_RES resd
871%endif
872
873%define RTGCPTR32_RES resd
874%define RTGCPTR64_RES resq
875
876;; @def RTGCPTR_PRE
877; The memory operand prefix used for a pointer in the guest context.
878%if GC_ARCH_BITS == 64
879 %define RTGCPTR_PRE qword
880%else
881 %define RTGCPTR_PRE dword
882%endif
883
884;; @def RTGCPTR_CB
885; The size in bytes of a pointer in the guest context.
886%if GC_ARCH_BITS == 64
887 %define RTGCPTR_CB 8
888%else
889 %define RTGCPTR_CB 4
890%endif
891
892
893;; @def RTRCPTR_DEF
894; The pesudo-instruction used to declare an initialized pointer variable in the raw mode context.
895%define RTRCPTR_DEF dd
896
897;; @def RTRCPTR_RES
898; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
899; variable of the raw mode context.
900%define RTRCPTR_RES resd
901
902;; @def RTRCPTR_PRE
903; The memory operand prefix used for a pointer in the raw mode context.
904%define RTRCPTR_PRE dword
905
906;; @def RTRCPTR_CB
907; The size in bytes of a pointer in the raw mode context.
908%define RTRCPTR_CB 4
909
910
911;; @def RT_CCPTR_DEF
912; The pesudo-instruction used to declare an initialized pointer variable in the current context.
913
914;; @def RT_CCPTR_RES
915; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
916; variable of the current context.
917
918;; @def RT_CCPTR_PRE
919; The memory operand prefix used for a pointer in the current context.
920
921;; @def RT_CCPTR_CB
922; The size in bytes of a pointer in the current context.
923
924%ifdef IN_RC
925 %define RTCCPTR_DEF RTRCPTR_DEF
926 %define RTCCPTR_RES RTRCPTR_RES
927 %define RTCCPTR_PRE RTRCPTR_PRE
928 %define RTCCPTR_CB RTRCPTR_CB
929%else
930 %ifdef IN_RING0
931 %define RTCCPTR_DEF RTR0PTR_DEF
932 %define RTCCPTR_RES RTR0PTR_RES
933 %define RTCCPTR_PRE RTR0PTR_PRE
934 %define RTCCPTR_CB RTR0PTR_CB
935 %else
936 %define RTCCPTR_DEF RTR3PTR_DEF
937 %define RTCCPTR_RES RTR3PTR_RES
938 %define RTCCPTR_PRE RTR3PTR_PRE
939 %define RTCCPTR_CB RTR3PTR_CB
940 %endif
941%endif
942
943
944
945;; @def RTHCPHYS_DEF
946; The pesudo-instruction used to declare an initialized host physical address.
947%define RTHCPHYS_DEF dq
948
949;; @def RTHCPTR_RES
950; The pesudo-instruction used to declare (=reserve space for) an uninitialized
951; host physical address variable
952%define RTHCPHYS_RES resq
953
954;; @def RTHCPTR_PRE
955; The memory operand prefix used for a host physical address.
956%define RTHCPHYS_PRE qword
957
958;; @def RTHCPHYS_CB
959; The size in bytes of a host physical address.
960%define RTHCPHYS_CB 8
961
962
963
964;; @def RTGCPHYS_DEF
965; The pesudo-instruction used to declare an initialized guest physical address.
966%define RTGCPHYS_DEF dq
967
968;; @def RTGCPHYS_RES
969; The pesudo-instruction used to declare (=reserve space for) an uninitialized
970; guest physical address variable
971%define RTGCPHYS_RES resq
972
973;; @def RTGCPTR_PRE
974; The memory operand prefix used for a guest physical address.
975%define RTGCPHYS_PRE qword
976
977;; @def RTGCPHYS_CB
978; The size in bytes of a guest physical address.
979%define RTGCPHYS_CB 8
980
981
982
983;;
984; The size of the long double C/C++ type.
985; On 32-bit Darwin this is 16 bytes, on L4, Linux, OS/2 and Windows
986; it's 12 bytes.
987; @todo figure out what 64-bit Windows does (I don't recall right now).
988%ifdef RT_ARCH_X86
989 %ifdef RT_OS_DARWIN
990 %define RTLRD_CB 16
991 %else
992 %define RTLRD_CB 12
993 %endif
994%else
995 %define RTLRD_CB 16
996%endif
997
998
999
1000;; @def ASM_CALL64_GCC
1001; Indicates that we're using the GCC 64-bit calling convention.
1002; @see @ref sec_vboxrem_amd64_compare (in VBoxREMWrapper.cpp) for an ABI description.
1003
1004;; @def ASM_CALL64_MSC
1005; Indicates that we're using the Microsoft 64-bit calling convention (fastcall on steroids).
1006; @see @ref sec_vboxrem_amd64_compare (in VBoxREMWrapper.cpp) for an ABI description.
1007
1008; Note: On X86 we're using cdecl unconditionally. There is not yet any common
1009; calling convention on AMD64, that's why we need to support two different ones.)
1010
1011%ifdef RT_ARCH_AMD64
1012 %ifndef ASM_CALL64_GCC
1013 %ifndef ASM_CALL64_MSC
1014 ; define it based on the object format.
1015 %ifdef ASM_FORMAT_PE
1016 %define ASM_CALL64_MSC
1017 %else
1018 %define ASM_CALL64_GCC
1019 %endif
1020 %endif
1021 %else
1022 ; sanity check.
1023 %ifdef ASM_CALL64_MSC
1024 %error "Only one of the ASM_CALL64_* defines should be defined!"
1025 %endif
1026 %endif
1027%else
1028 ;later; %ifdef ASM_CALL64_GCC
1029 ;later; %error "ASM_CALL64_GCC is defined without RT_ARCH_AMD64!" ASM_CALL64_GCC
1030 ;later; %endif
1031 ;later; %ifdef ASM_CALL64_MSC
1032 ;later; %error "ASM_CALL64_MSC is defined without RT_ARCH_AMD64!" ASM_CALL64_MSC
1033 ;later; %endif
1034%endif
1035
1036
1037;; @def RT_BEGINPROC
1038; Starts an IPRT procedure that should be exported unless IN_RT_STATIC is defined.
1039;
1040; @param 1 The function name. Will apply NAME macro to it.
1041%macro RT_BEGINPROC 1
1042 %ifdef IN_RT_STATIC
1043BEGINPROC %1
1044 %else
1045BEGINPROC_EXPORTED %1
1046 %endif
1047%endmacro ; RT_BEGINPROC
1048
1049
1050;; @def RT_NOCRT
1051; Symbol name wrapper for the No-CRT bits.
1052;
1053; In order to coexist in the same process as other CRTs, we need to
1054; decorate the symbols such that they don't conflict the ones in the
1055; other CRTs. The result of such conflicts / duplicate symbols can
1056; confuse the dynamic loader on unix like systems.
1057;
1058; @remark Always feed the name to this macro first and then pass the result
1059; on to the next *NAME* macro.
1060;
1061%ifndef RT_WITHOUT_NOCRT_WRAPPERS
1062 %define RT_NOCRT(name) nocrt_ %+ name
1063%else
1064 %define RT_NOCRT(name) name
1065%endif
1066
1067;; @def RT_NOCRT_BEGINPROC
1068; Starts a NOCRT procedure, taking care of name wrapping and aliasing.
1069;
1070; Aliasing (weak ones, if supported) will be created when RT_WITH_NOCRT_ALIASES
1071; is defined and RT_WITHOUT_NOCRT_WRAPPERS isn't.
1072;
1073%macro RT_NOCRT_BEGINPROC 1
1074 %ifdef RT_WITH_NOCRT_ALIASES
1075BEGINPROC_EXPORTED RT_NOCRT(%1)
1076 %ifdef ASM_FORMAT_ELF
1077global NAME(%1)
1078weak NAME(%1)
1079NAME(%1):
1080 %else
1081GLOBALNAME %1
1082 %endif
1083 %else ; !RT_WITH_NOCRT_ALIASES
1084BEGINPROC_EXPORTED RT_NOCRT(%1)
1085 %endif ; !RT_WITH_NOCRT_ALIASES
1086%endmacro ; RT_NOCRT_BEGINPROC
1087
1088%ifdef RT_WITH_NOCRT_ALIASES
1089 %ifdef RT_WITHOUT_NOCRT_WRAPPERS
1090 %error "RT_WITH_NOCRT_ALIASES and RT_WITHOUT_NOCRT_WRAPPERS doesn't mix."
1091 %endif
1092%endif
1093
1094
1095
1096;; @def xCB
1097; The stack unit size / The register unit size.
1098
1099;; @def xSP
1100; The stack pointer register (RSP or ESP).
1101
1102;; @def xBP
1103; The base pointer register (RBP or ESP).
1104
1105;; @def xAX
1106; RAX or EAX depending on context.
1107
1108;; @def xBX
1109; RBX or EBX depending on context.
1110
1111;; @def xCX
1112; RCX or ECX depending on context.
1113
1114;; @def xDX
1115; RDX or EDX depending on context.
1116
1117;; @def xDI
1118; RDI or EDI depending on context.
1119
1120;; @def xSI
1121; RSI or ESI depending on context.
1122
1123;; @def xWrtRIP
1124; 'wrt rip' for AMD64 targets, nothing for x86 ones.
1125
1126%ifdef RT_ARCH_AMD64
1127 %define xCB 8
1128 %define xSP rsp
1129 %define xBP rbp
1130 %define xAX rax
1131 %define xBX rbx
1132 %define xCX rcx
1133 %define xDX rdx
1134 %define xDI rdi
1135 %define xSI rsi
1136 %define xWrtRIP wrt rip
1137%else
1138 %define xCB 4
1139 %define xSP esp
1140 %define xBP ebp
1141 %define xAX eax
1142 %define xBX ebx
1143 %define xCX ecx
1144 %define xDX edx
1145 %define xDI edi
1146 %define xSI esi
1147 %define xWrtRIP
1148%endif
1149
1150
1151;
1152; NASM sets __PASS__ to 0 in preprocess-only mode, and to 3 when only generating dependencies.
1153; YASM has no such setting which is why we must rely on kBuild to tell us what we're doing.
1154; For simplicity, we'll set the kBuild macro when using NASM.
1155;
1156%ifndef KBUILD_GENERATING_MAKEFILE_DEPENDENCIES
1157 %ifdef __NASM__
1158 %if __PASS__ == 0 || __PASS__ == 3
1159 %define KBUILD_GENERATING_MAKEFILE_DEPENDENCIES
1160 %endif
1161 %endif
1162%endif
1163
1164
1165;
1166; Some simple compile time assertions.
1167;
1168; Note! Requires new kBuild to work with YASM (see above).
1169;
1170
1171;;
1172; Structure size assertion macro.
1173%define AssertCompileSize(a_Type, a_Size) AssertCompileSizeML a_Type, a_Size
1174%macro AssertCompileSizeML 2
1175 %ifndef KBUILD_GENERATING_MAKEFILE_DEPENDENCIES
1176 %assign AssertVar_cbActual %1 %+ _size
1177 %assign AssertVar_cbExpected %2
1178 %if AssertVar_cbActual != AssertVar_cbExpected
1179 %error %1 is AssertVar_cbActual bytes instead of AssertVar_cbExpected
1180 %endif
1181 %endif
1182%endmacro
1183
1184;;
1185; Structure size alignment assertion macro.
1186
1187%define AssertCompileSizeAlignment(a_Type, a_Align) AssertCompileSizeAlignmentML a_Type, a_Align
1188%macro AssertCompileSizeAlignmentML 2
1189 %ifndef KBUILD_GENERATING_MAKEFILE_DEPENDENCIES
1190 %assign AssertVar_cbActual %1 %+ _size
1191 %assign AssertVar_cbAlignment %2
1192 %if (AssertVar_cbActual & (AssertVar_cbAlignment - 1)) != 0
1193 %error %1 is AssertVar_cbActual bytes, expected size with AssertVar_cbAlignment bytes alignment.
1194 %endif
1195 %endif
1196%endmacro
1197
1198;;
1199; Structure member offset assertion macro.
1200%define AssertCompileMemberOffset(a_Type, a_Member, a_off) AssertCompileMemberOffsetML a_Type, a_Member, a_off
1201%macro AssertCompileMemberOffsetML 3
1202 %ifndef KBUILD_GENERATING_MAKEFILE_DEPENDENCIES
1203 %assign AssertVar_offActual %1 %+ . %+ %2
1204 %assign AssertVar_offExpected %3
1205 %if AssertVar_offActual != AssertVar_offExpected
1206 %error %1 %+ . %+ %2 is at AssertVar_offActual instead of AssertVar_offExpected
1207 %endif
1208 %endif
1209%endmacro
1210
1211;;
1212; Structure member alignment assertion macro.
1213%define AssertCompileMemberAlignment(a_Type, a_Member, a_cbAlign) AssertCompileMemberAlignmentML a_Type, a_Member, a_cbAlign
1214%macro AssertCompileMemberAlignmentML 3
1215 %ifndef KBUILD_GENERATING_MAKEFILE_DEPENDENCIES
1216 %assign AssertVar_offActual %1 %+ . %+ %2
1217 %assign AssertVar_cbAlign %3
1218 %if AssertVar_offActual & (AssertVar_cbAlign - 1)
1219 %error %1 %+ . %+ %2 is at AssertVar_offActual, expected AssertVar_cbAlign alignment
1220 %endif
1221 %endif
1222%endmacro
1223
1224;;
1225; Generic compile time expression assertion.
1226%define AssertCompile(a_Expr) AssertCompileML { a_Expr }
1227%macro AssertCompileML 1
1228 %ifndef KBUILD_GENERATING_MAKEFILE_DEPENDENCIES
1229 %if (%1) != 1
1230 %assign AssertVar_uResult %1
1231 %error %1 => AssertVar_uResult
1232 %endif
1233 %endif
1234%endmacro
1235
1236%endif
1237
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette