]>
Commit | Line | Data |
---|---|---|
e88de099 FB |
1 | #ifndef QEMU_H |
2 | #define QEMU_H | |
31e31b8a | 3 | |
6180a181 | 4 | #include "cpu.h" |
f08b6170 | 5 | #include "exec/cpu_ldst.h" |
992f48a0 | 6 | |
06177d36 | 7 | #undef DEBUG_REMAP |
06177d36 | 8 | |
022c62cb | 9 | #include "exec/user/abitypes.h" |
992f48a0 | 10 | |
992f48a0 | 11 | #include "syscall_defs.h" |
460c579f | 12 | #include "target_syscall.h" |
66fb9763 | 13 | |
400b7f6d PM |
14 | /* |
15 | * This is the size of the host kernel's sigset_t, needed where we make | |
1d48fdd9 PM |
16 | * direct system calls that take a sigset_t pointer and a size. |
17 | */ | |
18 | #define SIGSET_T_SIZE (_NSIG / 8) | |
19 | ||
400b7f6d PM |
20 | /* |
21 | * This struct is used to hold certain information about the image. | |
31e31b8a FB |
22 | * Basically, it replicates in user space what would be certain |
23 | * task_struct fields in the kernel | |
24 | */ | |
25 | struct image_info { | |
9955ffac | 26 | abi_ulong load_bias; |
992f48a0 BS |
27 | abi_ulong load_addr; |
28 | abi_ulong start_code; | |
29 | abi_ulong end_code; | |
30 | abi_ulong start_data; | |
31 | abi_ulong end_data; | |
32 | abi_ulong start_brk; | |
33 | abi_ulong brk; | |
6fd59449 | 34 | abi_ulong reserve_brk; |
992f48a0 | 35 | abi_ulong start_mmap; |
992f48a0 | 36 | abi_ulong start_stack; |
97374d38 | 37 | abi_ulong stack_limit; |
992f48a0 BS |
38 | abi_ulong entry; |
39 | abi_ulong code_offset; | |
40 | abi_ulong data_offset; | |
edf8e2af | 41 | abi_ulong saved_auxv; |
125b0f55 | 42 | abi_ulong auxv_len; |
edf8e2af MW |
43 | abi_ulong arg_start; |
44 | abi_ulong arg_end; | |
7c4ee5bc RH |
45 | abi_ulong arg_strings; |
46 | abi_ulong env_strings; | |
47 | abi_ulong file_string; | |
d8fd2954 | 48 | uint32_t elf_flags; |
400b7f6d | 49 | int personality; |
33143c44 | 50 | abi_ulong alignment; |
a99856cd CL |
51 | |
52 | /* The fields below are used in FDPIC mode. */ | |
1af02e83 MF |
53 | abi_ulong loadmap_addr; |
54 | uint16_t nsegs; | |
400b7f6d | 55 | void *loadsegs; |
1af02e83 | 56 | abi_ulong pt_dynamic_addr; |
3cb10cfa CL |
57 | abi_ulong interpreter_loadmap_addr; |
58 | abi_ulong interpreter_pt_dynamic_addr; | |
1af02e83 | 59 | struct image_info *other_info; |
83f990eb RH |
60 | |
61 | /* For target-specific processing of NT_GNU_PROPERTY_TYPE_0. */ | |
62 | uint32_t note_flags; | |
63 | ||
74cfc704 SM |
64 | #ifdef TARGET_MIPS |
65 | int fp_abi; | |
66 | int interp_fp_abi; | |
67 | #endif | |
31e31b8a FB |
68 | }; |
69 | ||
b346ff46 | 70 | #ifdef TARGET_I386 |
851e67a1 FB |
71 | /* Information about the current linux thread */ |
72 | struct vm86_saved_state { | |
73 | uint32_t eax; /* return code */ | |
74 | uint32_t ebx; | |
75 | uint32_t ecx; | |
76 | uint32_t edx; | |
77 | uint32_t esi; | |
78 | uint32_t edi; | |
79 | uint32_t ebp; | |
80 | uint32_t esp; | |
81 | uint32_t eflags; | |
82 | uint32_t eip; | |
83 | uint16_t cs, ss, ds, es, fs, gs; | |
84 | }; | |
b346ff46 | 85 | #endif |
851e67a1 | 86 | |
848d72cd | 87 | #if defined(TARGET_ARM) && defined(TARGET_ABI32) |
28c4f361 FB |
88 | /* FPU emulator */ |
89 | #include "nwfpe/fpa11.h" | |
28c4f361 FB |
90 | #endif |
91 | ||
624f7979 PB |
92 | struct emulated_sigtable { |
93 | int pending; /* true if signal is pending */ | |
907f5fdd | 94 | target_siginfo_t info; |
624f7979 PB |
95 | }; |
96 | ||
400b7f6d PM |
97 | /* |
98 | * NOTE: we force a big alignment so that the stack stored after is | |
99 | * aligned too | |
100 | */ | |
851e67a1 | 101 | typedef struct TaskState { |
edf8e2af | 102 | pid_t ts_tid; /* tid (or pid) of this task */ |
28c4f361 | 103 | #ifdef TARGET_ARM |
848d72cd | 104 | # ifdef TARGET_ABI32 |
28c4f361 FB |
105 | /* FPA state */ |
106 | FPA11 fpa; | |
848d72cd | 107 | # endif |
a10b9d93 KP |
108 | #endif |
109 | #if defined(TARGET_ARM) || defined(TARGET_RISCV) | |
a4f81979 | 110 | int swi_errno; |
28c4f361 | 111 | #endif |
84409ddb | 112 | #if defined(TARGET_I386) && !defined(TARGET_X86_64) |
992f48a0 | 113 | abi_ulong target_v86; |
851e67a1 | 114 | struct vm86_saved_state vm86_saved_regs; |
b333af06 | 115 | struct target_vm86plus_struct vm86plus; |
631271d7 FB |
116 | uint32_t v86flags; |
117 | uint32_t v86mask; | |
e6e5906b | 118 | #endif |
c2764719 | 119 | abi_ulong child_tidptr; |
e6e5906b | 120 | #ifdef TARGET_M68K |
1ccd9374 | 121 | abi_ulong tp_value; |
a87295e8 | 122 | #endif |
a10b9d93 | 123 | #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_RISCV) |
a87295e8 | 124 | /* Extra fields for semihosted binaries. */ |
d317091d PM |
125 | abi_ulong heap_base; |
126 | abi_ulong heap_limit; | |
b346ff46 | 127 | #endif |
d317091d | 128 | abi_ulong stack_base; |
851e67a1 | 129 | int used; /* non zero if used */ |
978efd6a | 130 | struct image_info *info; |
edf8e2af | 131 | struct linux_binprm *bprm; |
624f7979 | 132 | |
655ed67c | 133 | struct emulated_sigtable sync_signal; |
624f7979 | 134 | struct emulated_sigtable sigtab[TARGET_NSIG]; |
400b7f6d PM |
135 | /* |
136 | * This thread's signal mask, as requested by the guest program. | |
3d3efba0 PM |
137 | * The actual signal mask of this thread may differ: |
138 | * + we don't let SIGSEGV and SIGBUS be blocked while running guest code | |
139 | * + sometimes we block all signals to avoid races | |
140 | */ | |
141 | sigset_t signal_mask; | |
400b7f6d PM |
142 | /* |
143 | * The signal mask imposed by a guest sigsuspend syscall, if we are | |
3d3efba0 PM |
144 | * currently in the middle of such a syscall |
145 | */ | |
146 | sigset_t sigsuspend_mask; | |
147 | /* Nonzero if we're leaving a sigsuspend and sigsuspend_mask is valid. */ | |
148 | int in_sigsuspend; | |
149 | ||
400b7f6d PM |
150 | /* |
151 | * Nonzero if process_pending_signals() needs to do something (either | |
3d3efba0 PM |
152 | * handle a pending signal or unblock signals). |
153 | * This flag is written from a signal handler so should be accessed via | |
d73415a3 | 154 | * the qatomic_read() and qatomic_set() functions. (It is not accessed |
3d3efba0 PM |
155 | * from multiple threads.) |
156 | */ | |
157 | int signal_pending; | |
158 | ||
5bfce0b7 PM |
159 | /* This thread's sigaltstack, if it has one */ |
160 | struct target_sigaltstack sigaltstack_used; | |
851e67a1 FB |
161 | } __attribute__((aligned(16))) TaskState; |
162 | ||
3b249d26 | 163 | abi_long do_brk(abi_ulong new_brk); |
631271d7 | 164 | |
edf779ff FB |
165 | /* user access */ |
166 | ||
68f77666 RH |
167 | #define VERIFY_READ PAGE_READ |
168 | #define VERIFY_WRITE (PAGE_READ | PAGE_WRITE) | |
edf779ff | 169 | |
c7169b02 | 170 | static inline bool access_ok_untagged(int type, abi_ulong addr, abi_ulong size) |
dae3270c | 171 | { |
114556c5 | 172 | if (size == 0 |
46b12f46 RH |
173 | ? !guest_addr_valid_untagged(addr) |
174 | : !guest_range_valid_untagged(addr, size)) { | |
4feac83a RH |
175 | return false; |
176 | } | |
68f77666 | 177 | return page_check_range((target_ulong)addr, size, type) == 0; |
dae3270c | 178 | } |
edf779ff | 179 | |
c7169b02 RH |
180 | static inline bool access_ok(CPUState *cpu, int type, |
181 | abi_ulong addr, abi_ulong size) | |
182 | { | |
183 | return access_ok_untagged(type, cpu_untagged_addr(cpu, addr), size); | |
184 | } | |
185 | ||
658f2dc9 RH |
186 | /* NOTE __get_user and __put_user use host pointers and don't check access. |
187 | These are usually used to access struct data members once the struct has | |
188 | been locked - usually with lock_user_struct. */ | |
189 | ||
850d5e33 PM |
190 | /* |
191 | * Tricky points: | |
192 | * - Use __builtin_choose_expr to avoid type promotion from ?:, | |
193 | * - Invalid sizes result in a compile time error stemming from | |
194 | * the fact that abort has no parameters. | |
195 | * - It's easier to use the endian-specific unaligned load/store | |
196 | * functions than host-endian unaligned load/store plus tswapN. | |
197 | * - The pragmas are necessary only to silence a clang false-positive | |
198 | * warning: see https://bugs.llvm.org/show_bug.cgi?id=39113 . | |
850d5e33 PM |
199 | * - gcc has bugs in its _Pragma() support in some versions, eg |
200 | * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83256 -- so we only | |
201 | * include the warning-suppression pragmas for clang | |
202 | */ | |
798b8581 | 203 | #if defined(__clang__) && __has_warning("-Waddress-of-packed-member") |
850d5e33 PM |
204 | #define PRAGMA_DISABLE_PACKED_WARNING \ |
205 | _Pragma("GCC diagnostic push"); \ | |
850d5e33 PM |
206 | _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\"") |
207 | ||
208 | #define PRAGMA_REENABLE_PACKED_WARNING \ | |
209 | _Pragma("GCC diagnostic pop") | |
210 | ||
211 | #else | |
212 | #define PRAGMA_DISABLE_PACKED_WARNING | |
213 | #define PRAGMA_REENABLE_PACKED_WARNING | |
214 | #endif | |
215 | ||
216 | #define __put_user_e(x, hptr, e) \ | |
217 | do { \ | |
218 | PRAGMA_DISABLE_PACKED_WARNING; \ | |
219 | (__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p, \ | |
220 | __builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p, \ | |
221 | __builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p, \ | |
222 | __builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort)))) \ | |
223 | ((hptr), (x)), (void)0); \ | |
224 | PRAGMA_REENABLE_PACKED_WARNING; \ | |
225 | } while (0) | |
226 | ||
227 | #define __get_user_e(x, hptr, e) \ | |
228 | do { \ | |
229 | PRAGMA_DISABLE_PACKED_WARNING; \ | |
230 | ((x) = (typeof(*hptr))( \ | |
231 | __builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p, \ | |
232 | __builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p, \ | |
233 | __builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p, \ | |
234 | __builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort)))) \ | |
235 | (hptr)), (void)0); \ | |
236 | PRAGMA_REENABLE_PACKED_WARNING; \ | |
237 | } while (0) | |
238 | ||
658f2dc9 RH |
239 | |
240 | #ifdef TARGET_WORDS_BIGENDIAN | |
241 | # define __put_user(x, hptr) __put_user_e(x, hptr, be) | |
242 | # define __get_user(x, hptr) __get_user_e(x, hptr, be) | |
243 | #else | |
244 | # define __put_user(x, hptr) __put_user_e(x, hptr, le) | |
245 | # define __get_user(x, hptr) __get_user_e(x, hptr, le) | |
246 | #endif | |
edf779ff | 247 | |
579a97f7 FB |
248 | /* put_user()/get_user() take a guest address and check access */ |
249 | /* These are usually used to access an atomic data type, such as an int, | |
250 | * that has been passed by address. These internally perform locking | |
251 | * and unlocking on the data type. | |
252 | */ | |
253 | #define put_user(x, gaddr, target_type) \ | |
254 | ({ \ | |
255 | abi_ulong __gaddr = (gaddr); \ | |
256 | target_type *__hptr; \ | |
a42267ef | 257 | abi_long __ret = 0; \ |
579a97f7 | 258 | if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \ |
a42267ef | 259 | __put_user((x), __hptr); \ |
579a97f7 FB |
260 | unlock_user(__hptr, __gaddr, sizeof(target_type)); \ |
261 | } else \ | |
262 | __ret = -TARGET_EFAULT; \ | |
263 | __ret; \ | |
edf779ff FB |
264 | }) |
265 | ||
579a97f7 FB |
266 | #define get_user(x, gaddr, target_type) \ |
267 | ({ \ | |
268 | abi_ulong __gaddr = (gaddr); \ | |
269 | target_type *__hptr; \ | |
a42267ef | 270 | abi_long __ret = 0; \ |
579a97f7 | 271 | if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \ |
a42267ef | 272 | __get_user((x), __hptr); \ |
579a97f7 | 273 | unlock_user(__hptr, __gaddr, 0); \ |
2f619698 FB |
274 | } else { \ |
275 | /* avoid warning */ \ | |
276 | (x) = 0; \ | |
579a97f7 | 277 | __ret = -TARGET_EFAULT; \ |
2f619698 | 278 | } \ |
579a97f7 | 279 | __ret; \ |
edf779ff FB |
280 | }) |
281 | ||
2f619698 FB |
282 | #define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong) |
283 | #define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long) | |
284 | #define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t) | |
285 | #define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t) | |
286 | #define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t) | |
287 | #define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t) | |
288 | #define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t) | |
289 | #define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t) | |
290 | #define put_user_u8(x, gaddr) put_user((x), (gaddr), uint8_t) | |
291 | #define put_user_s8(x, gaddr) put_user((x), (gaddr), int8_t) | |
292 | ||
293 | #define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong) | |
294 | #define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long) | |
295 | #define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t) | |
296 | #define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t) | |
297 | #define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t) | |
298 | #define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t) | |
299 | #define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t) | |
300 | #define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t) | |
301 | #define get_user_u8(x, gaddr) get_user((x), (gaddr), uint8_t) | |
302 | #define get_user_s8(x, gaddr) get_user((x), (gaddr), int8_t) | |
303 | ||
579a97f7 FB |
304 | /* copy_from_user() and copy_to_user() are usually used to copy data |
305 | * buffers between the target and host. These internally perform | |
306 | * locking/unlocking of the memory. | |
307 | */ | |
360f0abd RH |
308 | int copy_from_user(void *hptr, abi_ulong gaddr, ssize_t len); |
309 | int copy_to_user(abi_ulong gaddr, void *hptr, ssize_t len); | |
579a97f7 | 310 | |
53a5960a | 311 | /* Functions for accessing guest memory. The tget and tput functions |
6f20f55b | 312 | read/write single values, byteswapping as necessary. The lock_user function |
53a5960a | 313 | gets a pointer to a contiguous area of guest memory, but does not perform |
6f20f55b | 314 | any byteswapping. lock_user may return either a pointer to the guest |
53a5960a PB |
315 | memory, or a temporary buffer. */ |
316 | ||
317 | /* Lock an area of guest memory into the host. If copy is true then the | |
318 | host area will have the same contents as the guest. */ | |
360f0abd | 319 | void *lock_user(int type, abi_ulong guest_addr, ssize_t len, bool copy); |
edf779ff | 320 | |
579a97f7 | 321 | /* Unlock an area of guest memory. The first LEN bytes must be |
1235fc06 | 322 | flushed back to guest memory. host_ptr = NULL is explicitly |
579a97f7 | 323 | allowed and does nothing. */ |
687ca797 | 324 | #ifndef DEBUG_REMAP |
360f0abd RH |
325 | static inline void unlock_user(void *host_ptr, abi_ulong guest_addr, |
326 | ssize_t len) | |
327 | { | |
328 | /* no-op */ | |
329 | } | |
687ca797 | 330 | #else |
360f0abd | 331 | void unlock_user(void *host_ptr, abi_ulong guest_addr, ssize_t len); |
53a5960a | 332 | #endif |
edf779ff | 333 | |
579a97f7 FB |
334 | /* Return the length of a string in target memory or -TARGET_EFAULT if |
335 | access error. */ | |
09f679b6 | 336 | ssize_t target_strlen(abi_ulong gaddr); |
53a5960a PB |
337 | |
338 | /* Like lock_user but for null terminated strings. */ | |
687ca797 | 339 | void *lock_user_string(abi_ulong guest_addr); |
edf779ff | 340 | |
41d1af4d | 341 | /* Helper macros for locking/unlocking a target struct. */ |
579a97f7 FB |
342 | #define lock_user_struct(type, host_ptr, guest_addr, copy) \ |
343 | (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy)) | |
344 | #define unlock_user_struct(host_ptr, guest_addr, copy) \ | |
53a5960a PB |
345 | unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0) |
346 | ||
e88de099 | 347 | #endif /* QEMU_H */ |