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_OR_UBDL );
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 	} __attribute__ (( packed ));
32 	uint16_t word;
33 } __attribute__ (( 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 	} __attribute__ (( packed ));
50 	uint16_t word;
51 	uint32_t dword;
52 } __attribute__ (( 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 		} __attribute__ (( packed ));
84 		uint16_t bx;
85 		uint32_t ebx;
86 	};
87 	union {
88 		struct {
89 			uint8_t dl;
90 			uint8_t dh;
91 		} __attribute__ (( packed ));
92 		uint16_t dx;
93 		uint32_t edx;
94 	};
95 	union {
96 		struct {
97 			uint8_t cl;
98 			uint8_t ch;
99 		} __attribute__ (( packed ));
100 		uint16_t cx;
101 		uint32_t ecx;
102 	};
103 	union {
104 		struct {
105 			uint8_t al;
106 			uint8_t ah;
107 		} __attribute__ (( packed ));
108 		uint16_t ax;
109 		uint32_t eax;
110 	};
111 } __attribute__ (( 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 } __attribute__ (( 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  * virt_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 } __attribute__ (( 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 } __attribute__ (( packed ));
195 
196 typedef struct segoff segoff_t;
197 
198 #endif /* REGISTERS_H */
199