Skip to content

Commit 0671cb6

Browse files
committed
[Morello] Change the PCS to pass memory arguments through C9
instead of passing them on the stack. In practice for non-compartment calls the arguments are still passed on the stack, although now there is no explicit requirement for this. Variadic arguments are still passed through C9 in the same way, at the first 16-byte aligned location after the last non-variadic argument. This is done is such a way that reading more variadic arguments than were passed is guaranteed to cause an out-of-bounds fault. Implements #158.
1 parent 617079d commit 0671cb6

1 file changed

Lines changed: 35 additions & 28 deletions

File tree

aapcs64-morello/aapcs64-morello.rst

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ Additionally, a stack-pointer register, SP in a 64-bit context or CSP in a capab
380380
+------------+----------+----------------------------------------------------------------------------------------------------+
381381
| r10-r15 | | Temporary registers. |
382382
+------------+----------+----------------------------------------------------------------------------------------------------+
383-
| r9 | | Parameter register for variadic calls, temporary register otherwise. |
383+
| r9 | | Parameter register for memory passed arguments, temporary register otherwise. |
384384
+------------+----------+----------------------------------------------------------------------------------------------------+
385385
| r8 | | The capability indirect result location register. |
386386
+------------+----------+----------------------------------------------------------------------------------------------------+
@@ -420,7 +420,7 @@ Additionally, a stack-pointer register, SP in a 64-bit context or CSP in a capab
420420

421421
The first eight registers, r0-r7, are used to pass argument values into a subroutine and to return result values from a function. They may also be used to hold intermediate values within a routine (but, in general, only between subroutine calls).
422422

423-
In AAPCS64-cap the r9 register is used to pass anonymous arguments in variadic calls.
423+
In AAPCS64-cap the r9 register is used to pass arguments through memory.
424424

425425
Registers r16 (IP0/CIP0) and r17 (IP1/CIP1) may be used by a linker as a scratch register between a routine and any subroutine it calls (for details, see `Use of CIP0 and CIP1 by the linker`_). They can also be used within a routine to hold intermediate values between subroutine calls.
426426

@@ -446,7 +446,7 @@ Processes, Memory and the Stack
446446
The Stack in AAPCS64-cap
447447
^^^^^^^^^^^^^^^^^^^^^^^^
448448

449-
The stack is a contiguous area of memory that may be used for storage of local variables and, when there are insufficient argument registers available, for passing additional arguments to subroutines .
449+
The stack is a contiguous area of memory that may be used for storage of local variables. Memory passed arguments may be allocated on the stack, although this is not mandatory.
450450

451451
The stack implementation is full-descending, with the current extent of the stack held in the special-purpose register CSP. The stack will have both a base and a limit, and an application can get these values by observing the base and limit of CSP.
452452

@@ -496,7 +496,12 @@ The A64 and C64 branch instructions are unable to reach every destination in the
496496
Parameter Passing
497497
-----------------
498498

499-
The base standard provides for passing arguments in general-purpose registers (r0-r7), SIMD/floating-point registers (v0-v7) and on the stack. For subroutines that take a small number of small parameters, only registers are used.
499+
The base standard provides for passing arguments in general-purpose registers (r0-r7), SIMD/floating-point registers (v0-v7) and in memory. For subroutines that take a small number of small parameters, only registers are used.
500+
501+
Memory passed parameters
502+
^^^^^^^^^^^^^^^^^^^^^^^^
503+
504+
We define an argument as being memory passed if it copied to memory as part of Stage C from `Parameter Passing Rules`_. The addres of a memory passed argument is the address of the memory location where the argument was copied to as part of Stage C from `Parameter Passing Rules`_.
500505

501506
Parameter Passing Rules
502507
^^^^^^^^^^^^^^^^^^^^^^^
@@ -521,22 +526,22 @@ The differences in language bindings used for AAPCS64 and AAPCS64-cap are descri
521526
| | |
522527
| A.2 | |
523528
+------------------------------+------------------------------------------------------------------------------------------+
524-
| | The next stacked argument address (NSAA) is set to the current stack-pointer value (SP). |
525-
| | |
526-
| A.3 | |
527-
+------------------------------+------------------------------------------------------------------------------------------+
528-
| | If the callee is variadic in AAPCS64-cap, the Anonymous Arguments Memory area is |
529-
| | allocated in memory with a size of at least 16 * (number of Anonymous arguments) bytes. |
530-
| | The Anonymous Arguments Memory area is 16-byte aligned. The Anonymous Arguments |
531-
| | Capability points to the Anonymous Arguments Memory area and is copied to C9. If there |
532-
| A.4 | are no Anonymous arguments passed, C9 is set to NULL. |
529+
| | If any parameters are memory passed in AAPCS64-cap, the Arguments Memory Area is |
530+
| | allocated. |
531+
| | The Arguments Memory area is 16-byte aligned. The Arguments Capability has the |
532+
| | bounds of the Arguments Memory area and Arguments Memory area and the address of the |
533+
| | first memory passed argument. The Arguments capability is copied to C9. If there are no |
534+
| A.3 | Anonymous arguments and the callee is variadic, C9 is set to NULL. See notes. |
533535
+------------------------------+------------------------------------------------------------------------------------------+
534-
| | The Anonymous Arguments Index (AArgsIdx) is set to zero. |
535-
| | |
536-
| A.5 | |
536+
| | The next memory argument address (NMAA) is set to the value of C9 in AAPCS64-cap or the |
537+
| A.4 | current stack-pointer value (SP) otherwise. |
537538
+------------------------------+------------------------------------------------------------------------------------------+
538539

539540

541+
.. note::
542+
The Arguments Capability is a capability that has the bounds of the arguments memory area and its address will be that of the first memory passed argument. The address of the Arguments Capability is 16-byte aligned. The capability offset of the Arguments Capability may not be zero. The capability offset is such that the first 16-byte aligned location after the last memory passed argument will be larger or equal than capability limit of the Arguments Capability.
543+
544+
540545
.. rubric:: Stage B – Pre-padding and extension of arguments
541546

542547
.. class:: aapcs64-morello-parameter-passing
@@ -593,7 +598,7 @@ The differences in language bindings used for AAPCS64 and AAPCS64-cap are descri
593598
+------------------------------+----------------------------------------------------------------------------------------+
594599

595600

596-
.. rubric:: Stage C – Assignment of arguments to registers and stack
601+
.. rubric:: Stage C – Assignment of arguments to registers and memory
597602

598603
.. class:: aapcs64-morello-parameter-passing
599604

@@ -605,9 +610,9 @@ The differences in language bindings used for AAPCS64 and AAPCS64-cap are descri
605610
| | to the least significant bits of a 128-bit register and the remaining bits filled with |
606611
| | unspecified values. |
607612
+-------------------------------+----------------------------------------------------------------------------------------+
608-
| | If the argument is Anonymous in AAPCS64-cap the argument is copied to memory at an |
609-
| C.2 | offset of (AArgsIdx * 16) bytes into the Anonymous Arguments Memory area. The |
610-
| | Anonymous Arguments Index is incremented by one. The argument has now been allocated. |
613+
| | If the argument is Anonymous in AAPCS64-cap NMAA is rounded up by 16. The argument is |
614+
| C.2 | copied to memory at the adjusted NMAA. The NMAA is incremented by 16. The argument has |
615+
| | now been allocated. |
611616
+-------------------------------+----------------------------------------------------------------------------------------+
612617
| | If the argument is a Half-, Single-, Double- or Quad- precision Floating-point or |
613618
| | Short Vector Type and the NSRN is less than 8, then the argument is allocated to the |
@@ -625,7 +630,7 @@ The differences in language bindings used for AAPCS64 and AAPCS64-cap are descri
625630
| C.5 | |
626631
+-------------------------------+----------------------------------------------------------------------------------------+
627632
| | If the argument is an HFA, an HVA, a Quad-precision Floating-point or Short Vector |
628-
| | Type then the NSAA is rounded up to the larger of 8 or the Natural Alignment of the |
633+
| | Type then the NMAA is rounded up to the larger of 8 or the Natural Alignment of the |
629634
| C.6 | argument type. |
630635
+-------------------------------+----------------------------------------------------------------------------------------+
631636
| | If the argument is a Half- or Single- precision Floating Point type, then the size of |
@@ -635,7 +640,7 @@ The differences in language bindings used for AAPCS64 and AAPCS64-cap are descri
635640
+-------------------------------+----------------------------------------------------------------------------------------+
636641
| | If the argument is an HFA, an HVA, a Half-, Single-, Double- or Quad- precision |
637642
| | Floating-point or Short Vector Type, then the argument is copied to memory at the |
638-
| C.8 | adjusted NSAA. The NSAA is incremented by the size of the argument. The argument has |
643+
| C.8 | adjusted NMAA. The NMAA is incremented by the size of the argument. The argument has |
639644
| | now been allocated. |
640645
+-------------------------------+----------------------------------------------------------------------------------------+
641646
| | If the argument is an Integral or Pointer Type, the size of the argument is less than |
@@ -674,26 +679,28 @@ The differences in language bindings used for AAPCS64 and AAPCS64-cap are descri
674679
| | |
675680
| C.14 | |
676681
+-------------------------------+----------------------------------------------------------------------------------------+
677-
| | The NSAA is rounded up to the larger of 8 or the Natural Alignment of the argument's |
682+
| | The NMAA is rounded up to the larger of 8 or the Natural Alignment of the argument's |
678683
| | type. |
679684
| C.15 | |
680685
+-------------------------------+----------------------------------------------------------------------------------------+
681686
| | If the argument is a composite type then the argument is copied to memory at the |
682-
| | adjusted NSAA. The NSAA is incremented by the size of the argument. The argument has |
687+
| | adjusted NMAA. The NMAA is incremented by the size of the argument. The argument has |
683688
| C.16 | now been allocated. |
684689
+-------------------------------+----------------------------------------------------------------------------------------+
685690
| | If the size of the argument is less than 8 bytes then the size of the argument is set |
686691
| | to 8 bytes. The effect is as if the argument was copied to the least significant bits |
687692
| C.17 | of a 64-bit register and the remaining bits filled with unspecified values. |
688693
+-------------------------------+----------------------------------------------------------------------------------------+
689-
| | The argument is copied to memory at the adjusted NSAA. The NSAA is incremented by the |
694+
| | The argument is copied to memory at the adjusted NMAA. The NMAA is incremented by the |
690695
| | size of the argument. The argument has now been allocated. |
691696
| C.18 | |
692697
+-------------------------------+----------------------------------------------------------------------------------------+
693698

694699
.. note::
700+
In AAPCS64-cap all Anonymous arguments are memory passed.
695701

696-
In AAPCS64-cap if the callee is variadic and there are fewer than 4096 Anonymous arguments, the length of C9 divided by 16 is equal to the number of Anonymous arguments. The length of C9 divided by 16 is always greater or equal to the number of Anonymous arguments.
702+
.. note::
703+
In AAPCS64-cap if the callee is variadic the number of Anonymous arguments is equal to (length(C)-offset(C)/16) where C is the adjusted value of C9 that has the address of the first Anonymous Argument.
697704

698705
Result Return
699706
-------------
@@ -799,7 +806,7 @@ Languages such as C and C++ permit routines that take a variable number of argum
799806
The va_list type
800807
----------------
801808

802-
The ``va_list`` type may refer to any parameter in a parameter list. All Anonymous parameters are passed on the stack in AAPCS64-cap.
809+
The ``va_list`` type may refer to any parameter in a parameter list. All Anonymous parameters are passed in memory in AAPCS64-cap.
803810

804811
.. code-block:: c
805812
@@ -808,7 +815,7 @@ The ``va_list`` type may refer to any parameter in a parameter list. All Anonymo
808815
The va_start() macro
809816
--------------------
810817

811-
The ``va_start`` macro shall initialize the ``va_list`` argument to the value of C9 as seen in the entry of the callee.
818+
The ``va_start`` macro shall initialize the ``va_list`` argument to the value of derived from C9 with the address of the first Anonymous argument.
812819

813820
The va_arg() macro
814821
------------------

0 commit comments

Comments
 (0)