extable.h (1459B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _ASM_EXTABLE_H 3#define _ASM_EXTABLE_H 4 5/* 6 * About the exception table: 7 * 8 * - insn is a 32-bit pc-relative offset from the faulting insn. 9 * - nextinsn is a 16-bit offset off of the faulting instruction 10 * (not off of the *next* instruction as branches are). 11 * - errreg is the register in which to place -EFAULT. 12 * - valreg is the final target register for the load sequence 13 * and will be zeroed. 14 * 15 * Either errreg or valreg may be $31, in which case nothing happens. 16 * 17 * The exception fixup information "just so happens" to be arranged 18 * as in a MEM format instruction. This lets us emit our three 19 * values like so: 20 * 21 * lda valreg, nextinsn(errreg) 22 * 23 */ 24 25struct exception_table_entry 26{ 27 signed int insn; 28 union exception_fixup { 29 unsigned unit; 30 struct { 31 signed int nextinsn : 16; 32 unsigned int errreg : 5; 33 unsigned int valreg : 5; 34 } bits; 35 } fixup; 36}; 37 38/* Returns the new pc */ 39#define fixup_exception(map_reg, _fixup, pc) \ 40({ \ 41 if ((_fixup)->fixup.bits.valreg != 31) \ 42 map_reg((_fixup)->fixup.bits.valreg) = 0; \ 43 if ((_fixup)->fixup.bits.errreg != 31) \ 44 map_reg((_fixup)->fixup.bits.errreg) = -EFAULT; \ 45 (pc) + (_fixup)->fixup.bits.nextinsn; \ 46}) 47 48#define ARCH_HAS_RELATIVE_EXTABLE 49 50#define swap_ex_entry_fixup(a, b, tmp, delta) \ 51 do { \ 52 (a)->fixup.unit = (b)->fixup.unit; \ 53 (b)->fixup.unit = (tmp).fixup.unit; \ 54 } while (0) 55 56#endif