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