Skip to content

Commit

Permalink
Change MEMTAG_STACK to be d_val, and MEMTAG_GLOBALS to be d_ptr
Browse files Browse the repository at this point in the history
MEMTAG_STACK should be d_val (a bit to indicate that MTE stack is either on/off), and MEMTAG_GLOBALS should be d_ptr (a pointer offset to a section containing memtag globals descriptors).

This is the way that lld has implemented it, as it's the local semantics (MEMTAG_GLOBALS is a pointer-to-section that needs load bias adjustment, and MEMTAG_STACK is a single bit that enables PROT_MTE on the stack).

This unfortunatly does mean that we diverge from the accepted semantics of odd == d_val, and even == d_ptr, but this seems like the best trade-off as we've shipped a compiler that did the non-spec-but-more-logical thing and shipped binaries to end users. Much better than shipping a whole new set of MEMTAG_GLOBALS_2 and MEMTAG_STACK_2 to fix the mistake.

Found by eugenis@ in https://r.android.com/2765590
  • Loading branch information
hctim authored and smithp35 committed Oct 18, 2023
1 parent 72df8b1 commit e720cc2
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions memtagabielf64/memtagabielf64.rst
Original file line number Diff line number Diff line change
Expand Up @@ -366,13 +366,30 @@ MemtagABI adds the following processor-specific dynamic array tags:
+---------------------------------+------------+--------+-------------------+-------------------+
| ``DT_AARCH64_MEMTAG_HEAP`` | 0x7000000b | d\_val | Platform specific | Platform Specific |
+---------------------------------+------------+--------+-------------------+-------------------+
| ``DT_AARCH64_MEMTAG_STACK`` | 0x7000000c | d\_ptr | Platform specific | Platform Specific |
| ``DT_AARCH64_MEMTAG_STACK`` | 0x7000000c | d\_val | Platform specific | Platform Specific |
+---------------------------------+------------+--------+-------------------+-------------------+
| ``DT_AARCH64_MEMTAG_GLOBALS`` | 0x7000000d | d\_val | Platform specific | Platform Specific |
| ``DT_AARCH64_MEMTAG_GLOBALS`` | 0x7000000d | d\_ptr | Platform specific | Platform Specific |
+---------------------------------+------------+--------+-------------------+-------------------+
| ``DT_AARCH64_MEMTAG_GLOBALSSZ`` | 0x7000000f | d\_val | Platform specific | Platform Specific |
+---------------------------------+------------+--------+-------------------+-------------------+

.. warning::

Earlier revisions of this document had ``DT_AARCH64_MEMTAG_STACK`` and
``DT_AARCH64_MEMTAG_GLOBALS`` with incorrect ``d_un`` (``d_ptr`` and ``d_val``
respectively). Binaries compiled with clang-17 and lld-17 produced the dynamic
entries with ``DT_AARCH64_MEMTAG_STACK`` as ``d_val`` and
``DT_AARCH64_MEMTAG_GLOBALS`` as ``d_ptr`` as this was the intended semantics,
and they were shipped on Android devices. The values were thus updated to
their more fitting semantic types (without updating the ``Value``), but this
does mean that ``DT_AARCH64_MEMTAG_STACK`` is a ``d_val`` with an even
``Value``, and ``DT_AARCH64_MEMTAG_GLOBALS`` is a ``d_ptr`` with an odd
``Value`` (where the normal semantics are ``odd == d_val``, and ``even ==
d_ptr``). Implementations of dynamic loaders need to be careful to apply these
semantics correctly - notably the load bias should not be applied to
``DT_AARCH64_MEMTAG_STACK``, as it's a ``d_val``, even though the ``Value`` is
even.

``DT_AARCH64_MEMTAG_MODE`` indicates the initial MTE mode that should be set. It
has two possible values: ``0``, indicating that the desired MTE mode is
Synchronous, and ``1``, indicating that the desired mode is Asynchronous. This
Expand Down

0 comments on commit e720cc2

Please sign in to comment.