1 #include <xtf/asm_macros.h>
2 #include <xtf/extable.h>
3 #include <arch/segment.h>
5 .section .text.user, "ax", @progbits
7 .macro GEN_ABS_STUB seg load_seg
9 ENTRY(stub_\seg\()_abs) /* exinfo_t stub_\seg_abs(unsigned long addr) */
12 * Switch segment if necessary. The old segment is preserved on the
13 * stack for the duration of the test.
21 push $(GDTE_AVAIL1 << 3 | 3)
25 push $(GDTE_AVAIL1 << 3 | 3)
32 /* No exception if we don't fault. Also reused by the 64bit case. */
35 /* The bottom bit of 'addr' encodes FEP. */
37 testb $1, (1 + stack_adj)*4(%esp)
46 1: movb $0, 0xc0000000
48 1: movabsb %al, 0x8000000040000000
52 1: movb $0, %\seg:0xc0000000
54 1: movabsb %al, %\seg:0x8000000040000000
60 /* Restore the old segment if necessary. */
72 _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
73 ENDFUNC(stub_\seg\()_abs)
76 .macro GEN_REG_STUB seg reg load_seg preserve_reg
78 ENTRY(stub_\seg\()_\reg) /* exinfo_t stub_\seg_\reg(unsigned long addr) */
82 * Switch segment if necessary. The old segment is preserved on the
83 * stack for the duration of the test.
91 push $(GDTE_AVAIL1 << 3 | 3)
95 push $(GDTE_AVAIL1 << 3 | 3)
102 /* Preserve the subject register if necessary. */
107 /* Move 'addr' into \reg */
109 mov (1 + stack_adj)*4(%esp), %\reg
114 /* The bottom bit of 'addr' encodes FEP. */
119 .ifeqs "\seg", "none"
122 1: movb $0, %\seg:(%\reg)
125 /* No exception if we didn't fault. */
128 /* Restore the register if necessary. */
134 /* Restore the old segment if necessary. */
136 .ifeqs "\seg", "none"
146 _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
147 ENDFUNC(stub_\seg\()_\reg)
151 * Instantiate `GEN_ABS_STUB foreach segment` and `GEN_REG_STUB foreach
152 * segment, foreach register`, calculaing whether the segment needs loading
153 * (implicit %ds, explicit %{e,d,f,g}s), and whether the register needs
154 * preserving (depends on the calling ABI).
156 .local seg_mask, seg_idx, reg_mask, reg_idx
164 .irp seg, none, es, cs, ss, ds, fs, gs
166 GEN_ABS_STUB \seg, (seg_mask & (1 << seg_idx))
169 reg_mask = 0b00011111
171 .irp reg, eax, ecx, edx, ebx, esp, ebp, esi, edi
173 reg_mask = 0b0001110000001111
175 .irp reg, rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15
178 GEN_REG_STUB \seg, \reg, (seg_mask & (1 << seg_idx)), (reg_mask & (1 << reg_idx))
179 reg_idx = reg_idx - 1
182 seg_idx = seg_idx - 1
189 * indent-tabs-mode: nil