1#ifndef QEMU_H
2#define QEMU_H
3
4#include <signal.h>
5#include <string.h>
6
7#include "cpu.h"
8
9#undef DEBUG_REMAP
10#ifdef DEBUG_REMAP
11#include <stdlib.h>
12#endif
13
14#include "qemu-types.h"
15
16enum BSDType {
17 target_freebsd,
18 target_netbsd,
19 target_openbsd,
20};
21extern enum BSDType bsd_type;
22
23#include "syscall_defs.h"
24#include "syscall.h"
25#include "target_signal.h"
26#include "gdbstub.h"
27
28#if defined(CONFIG_USE_NPTL)
29#define THREAD __thread
30#else
31#define THREAD
32#endif
33
34
35
36
37
38struct image_info {
39 abi_ulong load_addr;
40 abi_ulong start_code;
41 abi_ulong end_code;
42 abi_ulong start_data;
43 abi_ulong end_data;
44 abi_ulong start_brk;
45 abi_ulong brk;
46 abi_ulong start_mmap;
47 abi_ulong mmap;
48 abi_ulong rss;
49 abi_ulong start_stack;
50 abi_ulong entry;
51 abi_ulong code_offset;
52 abi_ulong data_offset;
53 char **host_argv;
54 int personality;
55};
56
57#define MAX_SIGQUEUE_SIZE 1024
58
59struct sigqueue {
60 struct sigqueue *next;
61
62};
63
64struct emulated_sigtable {
65 int pending;
66 struct sigqueue *first;
67 struct sigqueue info;
68
69};
70
71
72
73typedef struct TaskState {
74 struct TaskState *next;
75 int used;
76 struct image_info *info;
77
78 struct emulated_sigtable sigtab[TARGET_NSIG];
79 struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE];
80 struct sigqueue *first_free;
81 int signal_pending;
82
83 uint8_t stack[0];
84} __attribute__((aligned(16))) TaskState;
85
86void init_task_state(TaskState *ts);
87extern const char *qemu_uname_release;
88#if defined(CONFIG_USE_GUEST_BASE)
89extern unsigned long mmap_min_addr;
90#endif
91
92
93
94
95
96
97
98#define MAX_ARG_PAGES 32
99
100
101
102
103
104struct linux_binprm {
105 char buf[128];
106 void *page[MAX_ARG_PAGES];
107 abi_ulong p;
108 int fd;
109 int e_uid, e_gid;
110 int argc, envc;
111 char **argv;
112 char **envp;
113 char * filename;
114};
115
116void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
117abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
118 abi_ulong stringp, int push_ptr);
119int loader_exec(const char * filename, char ** argv, char ** envp,
120 struct target_pt_regs * regs, struct image_info *infop);
121
122int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
123 struct image_info * info);
124int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
125 struct image_info * info);
126
127abi_long memcpy_to_target(abi_ulong dest, const void *src,
128 unsigned long len);
129void target_set_brk(abi_ulong new_brk);
130abi_long do_brk(abi_ulong new_brk);
131void syscall_init(void);
132abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
133 abi_long arg2, abi_long arg3, abi_long arg4,
134 abi_long arg5, abi_long arg6, abi_long arg7,
135 abi_long arg8);
136abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
137 abi_long arg2, abi_long arg3, abi_long arg4,
138 abi_long arg5, abi_long arg6);
139abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
140 abi_long arg2, abi_long arg3, abi_long arg4,
141 abi_long arg5, abi_long arg6);
142void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2)));
143extern THREAD CPUState *thread_env;
144void cpu_loop(CPUState *env);
145char *target_strerror(int err);
146int get_osversion(void);
147void fork_start(void);
148void fork_end(int child);
149
150#include "qemu-log.h"
151
152
153void
154print_freebsd_syscall(int num,
155 abi_long arg1, abi_long arg2, abi_long arg3,
156 abi_long arg4, abi_long arg5, abi_long arg6);
157void print_freebsd_syscall_ret(int num, abi_long ret);
158void
159print_netbsd_syscall(int num,
160 abi_long arg1, abi_long arg2, abi_long arg3,
161 abi_long arg4, abi_long arg5, abi_long arg6);
162void print_netbsd_syscall_ret(int num, abi_long ret);
163void
164print_openbsd_syscall(int num,
165 abi_long arg1, abi_long arg2, abi_long arg3,
166 abi_long arg4, abi_long arg5, abi_long arg6);
167void print_openbsd_syscall_ret(int num, abi_long ret);
168extern int do_strace;
169
170
171void process_pending_signals(CPUState *cpu_env);
172void signal_init(void);
173
174
175
176long do_sigreturn(CPUState *env);
177long do_rt_sigreturn(CPUState *env);
178abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
179
180
181int target_mprotect(abi_ulong start, abi_ulong len, int prot);
182abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
183 int flags, int fd, abi_ulong offset);
184int target_munmap(abi_ulong start, abi_ulong len);
185abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
186 abi_ulong new_size, unsigned long flags,
187 abi_ulong new_addr);
188int target_msync(abi_ulong start, abi_ulong len, int flags);
189extern unsigned long last_brk;
190void mmap_lock(void);
191void mmap_unlock(void);
192void cpu_list_lock(void);
193void cpu_list_unlock(void);
194#if defined(CONFIG_USE_NPTL)
195void mmap_fork_start(void);
196void mmap_fork_end(int child);
197#endif
198
199
200extern unsigned long x86_stack_size;
201
202
203
204#define VERIFY_READ 0
205#define VERIFY_WRITE 1
206
207static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
208{
209 return page_check_range((target_ulong)addr, size,
210 (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
211}
212
213
214
215
216
217#define __put_user(x, hptr)\
218({\
219 int size = sizeof(*hptr);\
220 switch(size) {\
221 case 1:\
222 *(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\
223 break;\
224 case 2:\
225 *(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\
226 break;\
227 case 4:\
228 *(uint32_t *)(hptr) = tswap32((typeof(*hptr))(x));\
229 break;\
230 case 8:\
231 *(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\
232 break;\
233 default:\
234 abort();\
235 }\
236 0;\
237})
238
239#define __get_user(x, hptr) \
240({\
241 int size = sizeof(*hptr);\
242 switch(size) {\
243 case 1:\
244 x = (typeof(*hptr))*(uint8_t *)(hptr);\
245 break;\
246 case 2:\
247 x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\
248 break;\
249 case 4:\
250 x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\
251 break;\
252 case 8:\
253 x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
254 break;\
255 default:\
256 \
257 x = 0;\
258 abort();\
259 }\
260 0;\
261})
262
263
264
265
266
267
268#define put_user(x, gaddr, target_type) \
269({ \
270 abi_ulong __gaddr = (gaddr); \
271 target_type *__hptr; \
272 abi_long __ret; \
273 if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \
274 __ret = __put_user((x), __hptr); \
275 unlock_user(__hptr, __gaddr, sizeof(target_type)); \
276 } else \
277 __ret = -TARGET_EFAULT; \
278 __ret; \
279})
280
281#define get_user(x, gaddr, target_type) \
282({ \
283 abi_ulong __gaddr = (gaddr); \
284 target_type *__hptr; \
285 abi_long __ret; \
286 if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \
287 __ret = __get_user((x), __hptr); \
288 unlock_user(__hptr, __gaddr, 0); \
289 } else { \
290 \
291 (x) = 0; \
292 __ret = -TARGET_EFAULT; \
293 } \
294 __ret; \
295})
296
297#define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong)
298#define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long)
299#define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t)
300#define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t)
301#define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t)
302#define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t)
303#define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t)
304#define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t)
305#define put_user_u8(x, gaddr) put_user((x), (gaddr), uint8_t)
306#define put_user_s8(x, gaddr) put_user((x), (gaddr), int8_t)
307
308#define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong)
309#define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long)
310#define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t)
311#define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t)
312#define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t)
313#define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t)
314#define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t)
315#define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t)
316#define get_user_u8(x, gaddr) get_user((x), (gaddr), uint8_t)
317#define get_user_s8(x, gaddr) get_user((x), (gaddr), int8_t)
318
319
320
321
322
323abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
324abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
325
326
327
328
329
330
331
332
333
334static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
335{
336 if (!access_ok(type, guest_addr, len))
337 return NULL;
338#ifdef DEBUG_REMAP
339 {
340 void *addr;
341 addr = malloc(len);
342 if (copy)
343 memcpy(addr, g2h(guest_addr), len);
344 else
345 memset(addr, 0, len);
346 return addr;
347 }
348#else
349 return g2h(guest_addr);
350#endif
351}
352
353
354
355
356static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
357 long len)
358{
359
360#ifdef DEBUG_REMAP
361 if (!host_ptr)
362 return;
363 if (host_ptr == g2h(guest_addr))
364 return;
365 if (len > 0)
366 memcpy(g2h(guest_addr), host_ptr, len);
367 free(host_ptr);
368#endif
369}
370
371
372
373abi_long target_strlen(abi_ulong gaddr);
374
375
376static inline void *lock_user_string(abi_ulong guest_addr)
377{
378 abi_long len;
379 len = target_strlen(guest_addr);
380 if (len < 0)
381 return NULL;
382 return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
383}
384
385
386#define lock_user_struct(type, host_ptr, guest_addr, copy) \
387 (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy))
388#define unlock_user_struct(host_ptr, guest_addr, copy) \
389 unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
390
391#if defined(CONFIG_USE_NPTL)
392#include <pthread.h>
393#endif
394
395#endif
396