00001 #ifndef QEMU_H
00002 #define QEMU_H
00003
00004 #include <signal.h>
00005 #include <string.h>
00006
00007 #include "cpu.h"
00008
00009 #undef DEBUG_REMAP
00010 #ifdef DEBUG_REMAP
00011 #include <stdlib.h>
00012 #endif
00013
00014 #include "qemu-types.h"
00015
00016 enum BSDType {
00017 target_freebsd,
00018 target_netbsd,
00019 target_openbsd,
00020 };
00021
00022 #include "syscall_defs.h"
00023 #include "syscall.h"
00024 #include "target_signal.h"
00025 #include "gdbstub.h"
00026
00027 #if defined(USE_NPTL)
00028 #define THREAD __thread
00029 #else
00030 #define THREAD
00031 #endif
00032
00033
00034
00035
00036
00037 struct image_info {
00038 abi_ulong load_addr;
00039 abi_ulong start_code;
00040 abi_ulong end_code;
00041 abi_ulong start_data;
00042 abi_ulong end_data;
00043 abi_ulong start_brk;
00044 abi_ulong brk;
00045 abi_ulong start_mmap;
00046 abi_ulong mmap;
00047 abi_ulong rss;
00048 abi_ulong start_stack;
00049 abi_ulong entry;
00050 abi_ulong code_offset;
00051 abi_ulong data_offset;
00052 char **host_argv;
00053 int personality;
00054 };
00055
00056 #define MAX_SIGQUEUE_SIZE 1024
00057
00058 struct sigqueue {
00059 struct sigqueue *next;
00060
00061 };
00062
00063 struct emulated_sigtable {
00064 int pending;
00065 struct sigqueue *first;
00066 struct sigqueue info;
00067
00068 };
00069
00070
00071
00072 typedef struct TaskState {
00073 struct TaskState *next;
00074 int used;
00075 struct image_info *info;
00076
00077 struct emulated_sigtable sigtab[TARGET_NSIG];
00078 struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE];
00079 struct sigqueue *first_free;
00080 int signal_pending;
00081
00082 uint8_t stack[0];
00083 } __attribute__((aligned(16))) TaskState;
00084
00085 void init_task_state(TaskState *ts);
00086 extern const char *qemu_uname_release;
00087
00088
00089
00090
00091
00092
00093
00094 #define MAX_ARG_PAGES 32
00095
00096
00097
00098
00099
00100 struct linux_binprm {
00101 char buf[128];
00102 void *page[MAX_ARG_PAGES];
00103 abi_ulong p;
00104 int fd;
00105 int e_uid, e_gid;
00106 int argc, envc;
00107 char **argv;
00108 char **envp;
00109 char * filename;
00110 };
00111
00112 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
00113 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
00114 abi_ulong stringp, int push_ptr);
00115 int loader_exec(const char * filename, char ** argv, char ** envp,
00116 struct target_pt_regs * regs, struct image_info *infop);
00117
00118 int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
00119 struct image_info * info);
00120 int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
00121 struct image_info * info);
00122
00123 abi_long memcpy_to_target(abi_ulong dest, const void *src,
00124 unsigned long len);
00125 void target_set_brk(abi_ulong new_brk);
00126 abi_long do_brk(abi_ulong new_brk);
00127 void syscall_init(void);
00128 abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
00129 abi_long arg2, abi_long arg3, abi_long arg4,
00130 abi_long arg5, abi_long arg6);
00131 abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
00132 abi_long arg2, abi_long arg3, abi_long arg4,
00133 abi_long arg5, abi_long arg6);
00134 abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
00135 abi_long arg2, abi_long arg3, abi_long arg4,
00136 abi_long arg5, abi_long arg6);
00137 void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2)));
00138 extern THREAD CPUState *thread_env;
00139 void cpu_loop(CPUState *env, enum BSDType bsd_type);
00140 void init_paths(const char *prefix);
00141 const char *path(const char *pathname);
00142 char *target_strerror(int err);
00143 int get_osversion(void);
00144 void fork_start(void);
00145 void fork_end(int child);
00146
00147 #include "qemu-log.h"
00148
00149
00150 void
00151 print_freebsd_syscall(int num,
00152 abi_long arg1, abi_long arg2, abi_long arg3,
00153 abi_long arg4, abi_long arg5, abi_long arg6);
00154 void print_freebsd_syscall_ret(int num, abi_long ret);
00155 void
00156 print_netbsd_syscall(int num,
00157 abi_long arg1, abi_long arg2, abi_long arg3,
00158 abi_long arg4, abi_long arg5, abi_long arg6);
00159 void print_netbsd_syscall_ret(int num, abi_long ret);
00160 void
00161 print_openbsd_syscall(int num,
00162 abi_long arg1, abi_long arg2, abi_long arg3,
00163 abi_long arg4, abi_long arg5, abi_long arg6);
00164 void print_openbsd_syscall_ret(int num, abi_long ret);
00165 extern int do_strace;
00166
00167
00168 void process_pending_signals(CPUState *cpu_env);
00169 void signal_init(void);
00170
00171
00172
00173 long do_sigreturn(CPUState *env);
00174 long do_rt_sigreturn(CPUState *env);
00175 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
00176
00177
00178 int target_mprotect(abi_ulong start, abi_ulong len, int prot);
00179 abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
00180 int flags, int fd, abi_ulong offset);
00181 int target_munmap(abi_ulong start, abi_ulong len);
00182 abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
00183 abi_ulong new_size, unsigned long flags,
00184 abi_ulong new_addr);
00185 int target_msync(abi_ulong start, abi_ulong len, int flags);
00186 extern unsigned long last_brk;
00187 void mmap_lock(void);
00188 void mmap_unlock(void);
00189 #if defined(USE_NPTL)
00190 void mmap_fork_start(void);
00191 void mmap_fork_end(int child);
00192 #endif
00193
00194
00195
00196 #define VERIFY_READ 0
00197 #define VERIFY_WRITE 1
00198
00199 static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
00200 {
00201 return page_check_range((target_ulong)addr, size,
00202 (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
00203 }
00204
00205
00206
00207
00208
00209 #define __put_user(x, hptr)\
00210 ({\
00211 int size = sizeof(*hptr);\
00212 switch(size) {\
00213 case 1:\
00214 *(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\
00215 break;\
00216 case 2:\
00217 *(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\
00218 break;\
00219 case 4:\
00220 *(uint32_t *)(hptr) = tswap32((typeof(*hptr))(x));\
00221 break;\
00222 case 8:\
00223 *(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\
00224 break;\
00225 default:\
00226 abort();\
00227 }\
00228 0;\
00229 })
00230
00231 #define __get_user(x, hptr) \
00232 ({\
00233 int size = sizeof(*hptr);\
00234 switch(size) {\
00235 case 1:\
00236 x = (typeof(*hptr))*(uint8_t *)(hptr);\
00237 break;\
00238 case 2:\
00239 x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\
00240 break;\
00241 case 4:\
00242 x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\
00243 break;\
00244 case 8:\
00245 x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
00246 break;\
00247 default:\
00248 \
00249 x = 0;\
00250 abort();\
00251 }\
00252 0;\
00253 })
00254
00255
00256
00257
00258
00259
00260 #define put_user(x, gaddr, target_type) \
00261 ({ \
00262 abi_ulong __gaddr = (gaddr); \
00263 target_type *__hptr; \
00264 abi_long __ret; \
00265 if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \
00266 __ret = __put_user((x), __hptr); \
00267 unlock_user(__hptr, __gaddr, sizeof(target_type)); \
00268 } else \
00269 __ret = -TARGET_EFAULT; \
00270 __ret; \
00271 })
00272
00273 #define get_user(x, gaddr, target_type) \
00274 ({ \
00275 abi_ulong __gaddr = (gaddr); \
00276 target_type *__hptr; \
00277 abi_long __ret; \
00278 if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \
00279 __ret = __get_user((x), __hptr); \
00280 unlock_user(__hptr, __gaddr, 0); \
00281 } else { \
00282 \
00283 (x) = 0; \
00284 __ret = -TARGET_EFAULT; \
00285 } \
00286 __ret; \
00287 })
00288
00289 #define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong)
00290 #define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long)
00291 #define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t)
00292 #define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t)
00293 #define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t)
00294 #define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t)
00295 #define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t)
00296 #define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t)
00297 #define put_user_u8(x, gaddr) put_user((x), (gaddr), uint8_t)
00298 #define put_user_s8(x, gaddr) put_user((x), (gaddr), int8_t)
00299
00300 #define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong)
00301 #define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long)
00302 #define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t)
00303 #define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t)
00304 #define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t)
00305 #define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t)
00306 #define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t)
00307 #define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t)
00308 #define get_user_u8(x, gaddr) get_user((x), (gaddr), uint8_t)
00309 #define get_user_s8(x, gaddr) get_user((x), (gaddr), int8_t)
00310
00311
00312
00313
00314
00315 abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
00316 abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
00327 {
00328 if (!access_ok(type, guest_addr, len))
00329 return NULL;
00330 #ifdef DEBUG_REMAP
00331 {
00332 void *addr;
00333 addr = malloc(len);
00334 if (copy)
00335 memcpy(addr, g2h(guest_addr), len);
00336 else
00337 memset(addr, 0, len);
00338 return addr;
00339 }
00340 #else
00341 return g2h(guest_addr);
00342 #endif
00343 }
00344
00345
00346
00347
00348 static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
00349 long len)
00350 {
00351
00352 #ifdef DEBUG_REMAP
00353 if (!host_ptr)
00354 return;
00355 if (host_ptr == g2h(guest_addr))
00356 return;
00357 if (len > 0)
00358 memcpy(g2h(guest_addr), host_ptr, len);
00359 free(host_ptr);
00360 #endif
00361 }
00362
00363
00364
00365 abi_long target_strlen(abi_ulong gaddr);
00366
00367
00368 static inline void *lock_user_string(abi_ulong guest_addr)
00369 {
00370 abi_long len;
00371 len = target_strlen(guest_addr);
00372 if (len < 0)
00373 return NULL;
00374 return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
00375 }
00376
00377
00378 #define lock_user_struct(type, host_ptr, guest_addr, copy) \
00379 (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy))
00380 #define unlock_user_struct(host_ptr, guest_addr, copy) \
00381 unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
00382
00383 #if defined(USE_NPTL)
00384 #include <pthread.h>
00385 #endif
00386
00387 #endif