zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

rseq.h (3250B) - Raw


      1 /* Restartable Sequences Linux arm architecture header.
      2    Copyright (C) 2021-2025 Free Software Foundation, Inc.
      3 
      4    The GNU C Library is free software; you can redistribute it and/or
      5    modify it under the terms of the GNU Lesser General Public
      6    License as published by the Free Software Foundation; either
      7    version 2.1 of the License, or (at your option) any later version.
      8 
      9    The GNU C Library is distributed in the hope that it will be useful,
     10    but WITHOUT ANY WARRANTY; without even the implied warranty of
     11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12    Lesser General Public License for more details.
     13 
     14    You should have received a copy of the GNU Lesser General Public
     15    License along with the GNU C Library; if not, see
     16    <https://www.gnu.org/licenses/>.  */
     17 
     18 #ifndef _SYS_RSEQ_H
     19 # error "Never use <bits/rseq.h> directly; include <sys/rseq.h> instead."
     20 #endif
     21 
     22 /*
     23    RSEQ_SIG is a signature required before each abort handler code.
     24 
     25    It is a 32-bit value that maps to actual architecture code compiled
     26    into applications and libraries.  It needs to be defined for each
     27    architecture.  When choosing this value, it needs to be taken into
     28    account that generating invalid instructions may have ill effects on
     29    tools like objdump, and may also have impact on the CPU speculative
     30    execution efficiency in some cases.
     31 
     32    - ARM little endian
     33 
     34    RSEQ_SIG uses the udf A32 instruction with an uncommon immediate operand
     35    value 0x5de3.  This traps if user-space reaches this instruction by mistake,
     36    and the uncommon operand ensures the kernel does not move the instruction
     37    pointer to attacker-controlled code on rseq abort.
     38 
     39    The instruction pattern in the A32 instruction set is:
     40 
     41    e7f5def3    udf    #24035    ; 0x5de3
     42 
     43    This translates to the following instruction pattern in the T16 instruction
     44    set:
     45 
     46    little endian:
     47    def3        udf    #243      ; 0xf3
     48    e7f5        b.n    <7f5>
     49 
     50    - ARMv6+ big endian (BE8):
     51 
     52    ARMv6+ -mbig-endian generates mixed endianness code vs data: little-endian
     53    code and big-endian data.  The data value of the signature needs to have its
     54    byte order reversed to generate the trap instruction:
     55 
     56    Data: 0xf3def5e7
     57 
     58    Translates to this A32 instruction pattern:
     59 
     60    e7f5def3    udf    #24035    ; 0x5de3
     61 
     62    Translates to this T16 instruction pattern:
     63 
     64    def3        udf    #243      ; 0xf3
     65    e7f5        b.n    <7f5>
     66 
     67    - Prior to ARMv6 big endian (BE32):
     68 
     69    Prior to ARMv6, -mbig-endian generates big-endian code and data
     70    (which match), so the endianness of the data representation of the
     71    signature should not be reversed.  However, the choice between BE32
     72    and BE8 is done by the linker, so we cannot know whether code and
     73    data endianness will be mixed before the linker is invoked.  So rather
     74    than try to play tricks with the linker, the rseq signature is simply
     75    data (not a trap instruction) prior to ARMv6 on big endian.  This is
     76    why the signature is expressed as data (.word) rather than as
     77    instruction (.inst) in assembler.  */
     78 
     79 #ifdef __ARMEB__
     80 # define RSEQ_SIG    0xf3def5e7      /* udf    #24035    ; 0x5de3 (ARMv6+) */
     81 #else
     82 # define RSEQ_SIG    0xe7f5def3      /* udf    #24035    ; 0x5de3 */
     83 #endif