1 #ifndef REGISTERS_H 2 #define REGISTERS_H 3 4 /** @file 5 * 6 * i386 registers. 7 * 8 * This file defines data structures that allow easy access to i386 9 * register dumps. 10 * 11 */ 12 13 FILE_LICENCE ( GPL2_OR_LATER ); 14 15 #include <stdint.h> 16 17 /** 18 * A 16-bit general register. 19 * 20 * This type encapsulates a 16-bit register such as %ax, %bx, %cx, 21 * %dx, %si, %di, %bp or %sp. 22 * 23 */ 24 typedef union { 25 struct { 26 union { 27 uint8_t l; 28 uint8_t byte; 29 }; 30 uint8_t h; 31 } PACKED; 32 uint16_t word; 33 } PACKED reg16_t; 34 35 /** 36 * A 32-bit general register. 37 * 38 * This type encapsulates a 32-bit register such as %eax, %ebx, %ecx, 39 * %edx, %esi, %edi, %ebp or %esp. 40 * 41 */ 42 typedef union { 43 struct { 44 union { 45 uint8_t l; 46 uint8_t byte; 47 }; 48 uint8_t h; 49 } PACKED; 50 uint16_t word; 51 uint32_t dword; 52 } PACKED reg32_t; 53 54 /** 55 * A 32-bit general register dump. 56 * 57 * This is the data structure that is created on the stack by the @c 58 * pushal instruction, and can be read back using the @c popal 59 * instruction. 60 * 61 */ 62 struct i386_regs { 63 union { 64 uint16_t di; 65 uint32_t edi; 66 }; 67 union { 68 uint16_t si; 69 uint32_t esi; 70 }; 71 union { 72 uint16_t bp; 73 uint32_t ebp; 74 }; 75 union { 76 uint16_t sp; 77 uint32_t esp; 78 }; 79 union { 80 struct { 81 uint8_t bl; 82 uint8_t bh; 83 } PACKED; 84 uint16_t bx; 85 uint32_t ebx; 86 }; 87 union { 88 struct { 89 uint8_t dl; 90 uint8_t dh; 91 } PACKED; 92 uint16_t dx; 93 uint32_t edx; 94 }; 95 union { 96 struct { 97 uint8_t cl; 98 uint8_t ch; 99 } PACKED; 100 uint16_t cx; 101 uint32_t ecx; 102 }; 103 union { 104 struct { 105 uint8_t al; 106 uint8_t ah; 107 } PACKED; 108 uint16_t ax; 109 uint32_t eax; 110 }; 111 } PACKED; 112 113 /** 114 * A segment register dump. 115 * 116 * The i386 has no equivalent of the @c pushal or @c popal 117 * instructions for the segment registers. We adopt the convention of 118 * always using the sequences 119 * 120 * @code 121 * 122 * pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs 123 * 124 * @endcode 125 * 126 * and 127 * 128 * @code 129 * 130 * addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs 131 * 132 * @endcode 133 * 134 * This is the data structure that is created and read back by these 135 * instruction sequences. 136 * 137 */ 138 struct i386_seg_regs { 139 uint16_t cs; 140 uint16_t ss; 141 uint16_t ds; 142 uint16_t es; 143 uint16_t fs; 144 uint16_t gs; 145 } PACKED; 146 147 /** 148 * A full register dump. 149 * 150 * This data structure is created by the instructions 151 * 152 * @code 153 * 154 * pushfl 155 * pushal 156 * pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs 157 * 158 * @endcode 159 * 160 * and can be read back using the instructions 161 * 162 * @code 163 * 164 * addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs 165 * popal 166 * popfl 167 * 168 * @endcode 169 * 170 * prot_call() and kir_call() create this data structure on the stack 171 * and pass in a pointer to this structure. 172 * 173 */ 174 struct i386_all_regs { 175 struct i386_seg_regs segs; 176 struct i386_regs regs; 177 uint32_t flags; 178 } PACKED; 179 180 /* Flags */ 181 #define CF ( 1 << 0 ) 182 #define PF ( 1 << 2 ) 183 #define AF ( 1 << 4 ) 184 #define ZF ( 1 << 6 ) 185 #define SF ( 1 << 7 ) 186 #define OF ( 1 << 11 ) 187 188 /* Segment:offset structure. Note that the order within the structure 189 * is offset:segment. 190 */ 191 struct segoff { 192 uint16_t offset; 193 uint16_t segment; 194 } PACKED; 195 196 typedef struct segoff segoff_t; 197 198 #endif /* REGISTERS_H */ 199