symbian-qemu-0.9.1-12/qemu-symbian-svp/bsd-user/qemu.h
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 /* DEBUG_REMAP */
       
    13 
       
    14 #include "qemu-types.h"
       
    15 
       
    16 enum BSDType {
       
    17     target_freebsd,
       
    18     target_netbsd,
       
    19     target_openbsd,
       
    20 };
       
    21 
       
    22 #include "syscall_defs.h"
       
    23 #include "syscall.h"
       
    24 #include "target_signal.h"
       
    25 #include "gdbstub.h"
       
    26 
       
    27 #if defined(USE_NPTL)
       
    28 #define THREAD __thread
       
    29 #else
       
    30 #define THREAD
       
    31 #endif
       
    32 
       
    33 /* This struct is used to hold certain information about the image.
       
    34  * Basically, it replicates in user space what would be certain
       
    35  * task_struct fields in the kernel
       
    36  */
       
    37 struct image_info {
       
    38     abi_ulong load_addr;
       
    39     abi_ulong start_code;
       
    40     abi_ulong end_code;
       
    41     abi_ulong start_data;
       
    42     abi_ulong end_data;
       
    43     abi_ulong start_brk;
       
    44     abi_ulong brk;
       
    45     abi_ulong start_mmap;
       
    46     abi_ulong mmap;
       
    47     abi_ulong rss;
       
    48     abi_ulong start_stack;
       
    49     abi_ulong entry;
       
    50     abi_ulong code_offset;
       
    51     abi_ulong data_offset;
       
    52     char      **host_argv;
       
    53     int       personality;
       
    54 };
       
    55 
       
    56 #define MAX_SIGQUEUE_SIZE 1024
       
    57 
       
    58 struct sigqueue {
       
    59     struct sigqueue *next;
       
    60     //target_siginfo_t info;
       
    61 };
       
    62 
       
    63 struct emulated_sigtable {
       
    64     int pending; /* true if signal is pending */
       
    65     struct sigqueue *first;
       
    66     struct sigqueue info; /* in order to always have memory for the
       
    67                              first signal, we put it here */
       
    68 };
       
    69 
       
    70 /* NOTE: we force a big alignment so that the stack stored after is
       
    71    aligned too */
       
    72 typedef struct TaskState {
       
    73     struct TaskState *next;
       
    74     int used; /* non zero if used */
       
    75     struct image_info *info;
       
    76 
       
    77     struct emulated_sigtable sigtab[TARGET_NSIG];
       
    78     struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
       
    79     struct sigqueue *first_free; /* first free siginfo queue entry */
       
    80     int signal_pending; /* non zero if a signal may be pending */
       
    81 
       
    82     uint8_t stack[0];
       
    83 } __attribute__((aligned(16))) TaskState;
       
    84 
       
    85 void init_task_state(TaskState *ts);
       
    86 extern const char *qemu_uname_release;
       
    87 
       
    88 /* ??? See if we can avoid exposing so much of the loader internals.  */
       
    89 /*
       
    90  * MAX_ARG_PAGES defines the number of pages allocated for arguments
       
    91  * and envelope for the new program. 32 should suffice, this gives
       
    92  * a maximum env+arg of 128kB w/4KB pages!
       
    93  */
       
    94 #define MAX_ARG_PAGES 32
       
    95 
       
    96 /*
       
    97  * This structure is used to hold the arguments that are
       
    98  * used when loading binaries.
       
    99  */
       
   100 struct linux_binprm {
       
   101         char buf[128];
       
   102         void *page[MAX_ARG_PAGES];
       
   103         abi_ulong p;
       
   104         int fd;
       
   105         int e_uid, e_gid;
       
   106         int argc, envc;
       
   107         char **argv;
       
   108         char **envp;
       
   109         char * filename;        /* Name of binary */
       
   110 };
       
   111 
       
   112 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
       
   113 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
       
   114                               abi_ulong stringp, int push_ptr);
       
   115 int loader_exec(const char * filename, char ** argv, char ** envp,
       
   116              struct target_pt_regs * regs, struct image_info *infop);
       
   117 
       
   118 int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
       
   119                     struct image_info * info);
       
   120 int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
       
   121                     struct image_info * info);
       
   122 
       
   123 abi_long memcpy_to_target(abi_ulong dest, const void *src,
       
   124                           unsigned long len);
       
   125 void target_set_brk(abi_ulong new_brk);
       
   126 abi_long do_brk(abi_ulong new_brk);
       
   127 void syscall_init(void);
       
   128 abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
       
   129                             abi_long arg2, abi_long arg3, abi_long arg4,
       
   130                             abi_long arg5, abi_long arg6);
       
   131 abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
       
   132                            abi_long arg2, abi_long arg3, abi_long arg4,
       
   133                            abi_long arg5, abi_long arg6);
       
   134 abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
       
   135                             abi_long arg2, abi_long arg3, abi_long arg4,
       
   136                             abi_long arg5, abi_long arg6);
       
   137 void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2)));
       
   138 extern THREAD CPUState *thread_env;
       
   139 void cpu_loop(CPUState *env, enum BSDType bsd_type);
       
   140 void init_paths(const char *prefix);
       
   141 const char *path(const char *pathname);
       
   142 char *target_strerror(int err);
       
   143 int get_osversion(void);
       
   144 void fork_start(void);
       
   145 void fork_end(int child);
       
   146 
       
   147 #include "qemu-log.h"
       
   148 
       
   149 /* strace.c */
       
   150 void
       
   151 print_freebsd_syscall(int num,
       
   152                       abi_long arg1, abi_long arg2, abi_long arg3,
       
   153                       abi_long arg4, abi_long arg5, abi_long arg6);
       
   154 void print_freebsd_syscall_ret(int num, abi_long ret);
       
   155 void
       
   156 print_netbsd_syscall(int num,
       
   157                      abi_long arg1, abi_long arg2, abi_long arg3,
       
   158                      abi_long arg4, abi_long arg5, abi_long arg6);
       
   159 void print_netbsd_syscall_ret(int num, abi_long ret);
       
   160 void
       
   161 print_openbsd_syscall(int num,
       
   162                       abi_long arg1, abi_long arg2, abi_long arg3,
       
   163                       abi_long arg4, abi_long arg5, abi_long arg6);
       
   164 void print_openbsd_syscall_ret(int num, abi_long ret);
       
   165 extern int do_strace;
       
   166 
       
   167 /* signal.c */
       
   168 void process_pending_signals(CPUState *cpu_env);
       
   169 void signal_init(void);
       
   170 //int queue_signal(CPUState *env, int sig, target_siginfo_t *info);
       
   171 //void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info);
       
   172 //void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
       
   173 long do_sigreturn(CPUState *env);
       
   174 long do_rt_sigreturn(CPUState *env);
       
   175 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
       
   176 
       
   177 /* mmap.c */
       
   178 int target_mprotect(abi_ulong start, abi_ulong len, int prot);
       
   179 abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
       
   180                      int flags, int fd, abi_ulong offset);
       
   181 int target_munmap(abi_ulong start, abi_ulong len);
       
   182 abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
       
   183                        abi_ulong new_size, unsigned long flags,
       
   184                        abi_ulong new_addr);
       
   185 int target_msync(abi_ulong start, abi_ulong len, int flags);
       
   186 extern unsigned long last_brk;
       
   187 void mmap_lock(void);
       
   188 void mmap_unlock(void);
       
   189 #if defined(USE_NPTL)
       
   190 void mmap_fork_start(void);
       
   191 void mmap_fork_end(int child);
       
   192 #endif
       
   193 
       
   194 /* user access */
       
   195 
       
   196 #define VERIFY_READ 0
       
   197 #define VERIFY_WRITE 1 /* implies read access */
       
   198 
       
   199 static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
       
   200 {
       
   201     return page_check_range((target_ulong)addr, size,
       
   202                             (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
       
   203 }
       
   204 
       
   205 /* NOTE __get_user and __put_user use host pointers and don't check access. */
       
   206 /* These are usually used to access struct data members once the
       
   207  * struct has been locked - usually with lock_user_struct().
       
   208  */
       
   209 #define __put_user(x, hptr)\
       
   210 ({\
       
   211     int size = sizeof(*hptr);\
       
   212     switch(size) {\
       
   213     case 1:\
       
   214         *(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\
       
   215         break;\
       
   216     case 2:\
       
   217         *(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\
       
   218         break;\
       
   219     case 4:\
       
   220         *(uint32_t *)(hptr) = tswap32((typeof(*hptr))(x));\
       
   221         break;\
       
   222     case 8:\
       
   223         *(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\
       
   224         break;\
       
   225     default:\
       
   226         abort();\
       
   227     }\
       
   228     0;\
       
   229 })
       
   230 
       
   231 #define __get_user(x, hptr) \
       
   232 ({\
       
   233     int size = sizeof(*hptr);\
       
   234     switch(size) {\
       
   235     case 1:\
       
   236         x = (typeof(*hptr))*(uint8_t *)(hptr);\
       
   237         break;\
       
   238     case 2:\
       
   239         x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\
       
   240         break;\
       
   241     case 4:\
       
   242         x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\
       
   243         break;\
       
   244     case 8:\
       
   245         x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
       
   246         break;\
       
   247     default:\
       
   248         /* avoid warning */\
       
   249         x = 0;\
       
   250         abort();\
       
   251     }\
       
   252     0;\
       
   253 })
       
   254 
       
   255 /* put_user()/get_user() take a guest address and check access */
       
   256 /* These are usually used to access an atomic data type, such as an int,
       
   257  * that has been passed by address.  These internally perform locking
       
   258  * and unlocking on the data type.
       
   259  */
       
   260 #define put_user(x, gaddr, target_type)                                 \
       
   261 ({                                                                      \
       
   262     abi_ulong __gaddr = (gaddr);                                        \
       
   263     target_type *__hptr;                                                \
       
   264     abi_long __ret;                                                     \
       
   265     if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \
       
   266         __ret = __put_user((x), __hptr);                                \
       
   267         unlock_user(__hptr, __gaddr, sizeof(target_type));              \
       
   268     } else                                                              \
       
   269         __ret = -TARGET_EFAULT;                                         \
       
   270     __ret;                                                              \
       
   271 })
       
   272 
       
   273 #define get_user(x, gaddr, target_type)                                 \
       
   274 ({                                                                      \
       
   275     abi_ulong __gaddr = (gaddr);                                        \
       
   276     target_type *__hptr;                                                \
       
   277     abi_long __ret;                                                     \
       
   278     if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \
       
   279         __ret = __get_user((x), __hptr);                                \
       
   280         unlock_user(__hptr, __gaddr, 0);                                \
       
   281     } else {                                                            \
       
   282         /* avoid warning */                                             \
       
   283         (x) = 0;                                                        \
       
   284         __ret = -TARGET_EFAULT;                                         \
       
   285     }                                                                   \
       
   286     __ret;                                                              \
       
   287 })
       
   288 
       
   289 #define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong)
       
   290 #define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long)
       
   291 #define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t)
       
   292 #define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t)
       
   293 #define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t)
       
   294 #define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t)
       
   295 #define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t)
       
   296 #define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t)
       
   297 #define put_user_u8(x, gaddr)  put_user((x), (gaddr), uint8_t)
       
   298 #define put_user_s8(x, gaddr)  put_user((x), (gaddr), int8_t)
       
   299 
       
   300 #define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong)
       
   301 #define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long)
       
   302 #define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t)
       
   303 #define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t)
       
   304 #define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t)
       
   305 #define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t)
       
   306 #define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t)
       
   307 #define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t)
       
   308 #define get_user_u8(x, gaddr)  get_user((x), (gaddr), uint8_t)
       
   309 #define get_user_s8(x, gaddr)  get_user((x), (gaddr), int8_t)
       
   310 
       
   311 /* copy_from_user() and copy_to_user() are usually used to copy data
       
   312  * buffers between the target and host.  These internally perform
       
   313  * locking/unlocking of the memory.
       
   314  */
       
   315 abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
       
   316 abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
       
   317 
       
   318 /* Functions for accessing guest memory.  The tget and tput functions
       
   319    read/write single values, byteswapping as neccessary.  The lock_user
       
   320    gets a pointer to a contiguous area of guest memory, but does not perform
       
   321    and byteswapping.  lock_user may return either a pointer to the guest
       
   322    memory, or a temporary buffer.  */
       
   323 
       
   324 /* Lock an area of guest memory into the host.  If copy is true then the
       
   325    host area will have the same contents as the guest.  */
       
   326 static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
       
   327 {
       
   328     if (!access_ok(type, guest_addr, len))
       
   329         return NULL;
       
   330 #ifdef DEBUG_REMAP
       
   331     {
       
   332         void *addr;
       
   333         addr = malloc(len);
       
   334         if (copy)
       
   335             memcpy(addr, g2h(guest_addr), len);
       
   336         else
       
   337             memset(addr, 0, len);
       
   338         return addr;
       
   339     }
       
   340 #else
       
   341     return g2h(guest_addr);
       
   342 #endif
       
   343 }
       
   344 
       
   345 /* Unlock an area of guest memory.  The first LEN bytes must be
       
   346    flushed back to guest memory. host_ptr = NULL is explicitly
       
   347    allowed and does nothing. */
       
   348 static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
       
   349                                long len)
       
   350 {
       
   351 
       
   352 #ifdef DEBUG_REMAP
       
   353     if (!host_ptr)
       
   354         return;
       
   355     if (host_ptr == g2h(guest_addr))
       
   356         return;
       
   357     if (len > 0)
       
   358         memcpy(g2h(guest_addr), host_ptr, len);
       
   359     free(host_ptr);
       
   360 #endif
       
   361 }
       
   362 
       
   363 /* Return the length of a string in target memory or -TARGET_EFAULT if
       
   364    access error. */
       
   365 abi_long target_strlen(abi_ulong gaddr);
       
   366 
       
   367 /* Like lock_user but for null terminated strings.  */
       
   368 static inline void *lock_user_string(abi_ulong guest_addr)
       
   369 {
       
   370     abi_long len;
       
   371     len = target_strlen(guest_addr);
       
   372     if (len < 0)
       
   373         return NULL;
       
   374     return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
       
   375 }
       
   376 
       
   377 /* Helper macros for locking/ulocking a target struct.  */
       
   378 #define lock_user_struct(type, host_ptr, guest_addr, copy)      \
       
   379     (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy))
       
   380 #define unlock_user_struct(host_ptr, guest_addr, copy)          \
       
   381     unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
       
   382 
       
   383 #if defined(USE_NPTL)
       
   384 #include <pthread.h>
       
   385 #endif
       
   386 
       
   387 #endif /* QEMU_H */