#include <stdlib.h>
#endif /* DEBUG_REMAP */
-#include "qemu-types.h"
+#include "exec/user/abitypes.h"
-#include "thunk.h"
+#include "exec/user/thunk.h"
#include "syscall_defs.h"
#include "syscall.h"
#include "target_signal.h"
-#include "gdbstub.h"
-#include "qemu-queue.h"
+#include "exec/gdbstub.h"
+#include "qemu/queue.h"
#if defined(CONFIG_USE_NPTL)
#define THREAD __thread
abi_ulong code_offset;
abi_ulong data_offset;
abi_ulong saved_auxv;
+ abi_ulong auxv_len;
abi_ulong arg_start;
abi_ulong arg_end;
+ uint32_t elf_flags;
int personality;
#ifdef CONFIG_USE_FDPIC
abi_ulong loadmap_addr;
#endif
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
/* Extra fields for semihosted binaries. */
- uint32_t stack_base;
uint32_t heap_base;
uint32_t heap_limit;
#endif
+ uint32_t stack_base;
int used; /* non zero if used */
struct image_info *info;
struct linux_binprm *bprm;
char **argv;
char **envp;
char * filename; /* Name of binary */
- int (*core_dump)(int, const CPUState *); /* coredump routine */
+ int (*core_dump)(int, const CPUArchState *); /* coredump routine */
};
void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
abi_long arg5, abi_long arg6, abi_long arg7,
abi_long arg8);
void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
-extern THREAD CPUState *thread_env;
-void cpu_loop(CPUState *env);
+extern THREAD CPUArchState *thread_env;
+void cpu_loop(CPUArchState *env);
char *target_strerror(int err);
int get_osversion(void);
void fork_start(void);
void fork_end(int child);
-#include "qemu-log.h"
+/* Creates the initial guest address space in the host memory space using
+ * the given host start address hint and size. The guest_start parameter
+ * specifies the start address of the guest space. guest_base will be the
+ * difference between the host start address computed by this function and
+ * guest_start. If fixed is specified, then the mapped address space must
+ * start at host_start. The real start address of the mapped memory space is
+ * returned or -1 if there was an error.
+ */
+unsigned long init_guest_space(unsigned long host_start,
+ unsigned long host_size,
+ unsigned long guest_start,
+ bool fixed);
+
+#include "qemu/log.h"
+
+/* syscall.c */
+int host_to_target_waitstatus(int status);
/* strace.c */
void print_syscall(int num,
extern int do_strace;
/* signal.c */
-void process_pending_signals(CPUState *cpu_env);
+void process_pending_signals(CPUArchState *cpu_env);
void signal_init(void);
-int queue_signal(CPUState *env, int sig, target_siginfo_t *info);
+int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info);
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info);
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
int target_to_host_signal(int sig);
int host_to_target_signal(int sig);
-long do_sigreturn(CPUState *env);
-long do_rt_sigreturn(CPUState *env);
+long do_sigreturn(CPUArchState *env);
+long do_rt_sigreturn(CPUArchState *env);
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
#ifdef TARGET_I386
abi_ulong new_addr);
int target_msync(abi_ulong start, abi_ulong len, int flags);
extern unsigned long last_brk;
+extern abi_ulong mmap_next_start;
void mmap_lock(void);
void mmap_unlock(void);
abi_ulong mmap_find_vma(abi_ulong, abi_ulong);
(type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
}
-/* NOTE __get_user and __put_user use host pointers and don't check access. */
-/* These are usually used to access struct data members once the
- * struct has been locked - usually with lock_user_struct().
- */
-#define __put_user(x, hptr)\
-({\
- switch(sizeof(*hptr)) {\
- case 1:\
- *(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\
- break;\
- case 2:\
- *(uint16_t *)(hptr) = tswap16((uint16_t)(typeof(*hptr))(x));\
- break;\
- case 4:\
- *(uint32_t *)(hptr) = tswap32((uint32_t)(typeof(*hptr))(x));\
- break;\
- case 8:\
- *(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\
- break;\
- default:\
- abort();\
- }\
- 0;\
-})
-
-#define __get_user(x, hptr) \
-({\
- switch(sizeof(*hptr)) {\
- case 1:\
- x = (typeof(*hptr))*(uint8_t *)(hptr);\
- break;\
- case 2:\
- x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\
- break;\
- case 4:\
- x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\
- break;\
- case 8:\
- x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
- break;\
- default:\
- /* avoid warning */\
- x = 0;\
- abort();\
- }\
- 0;\
-})
+/* NOTE __get_user and __put_user use host pointers and don't check access.
+ These are usually used to access struct data members once the struct has
+ been locked - usually with lock_user_struct. */
+
+/* Tricky points:
+ - Use __builtin_choose_expr to avoid type promotion from ?:,
+ - Invalid sizes result in a compile time error stemming from
+ the fact that abort has no parameters.
+ - It's easier to use the endian-specific unaligned load/store
+ functions than host-endian unaligned load/store plus tswapN. */
+
+#define __put_user_e(x, hptr, e) \
+ (__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort)))) \
+ ((hptr), (x)), 0)
+
+#define __get_user_e(x, hptr, e) \
+ ((x) = \
+ __builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort)))) \
+ (hptr), 0)
+
+#ifdef TARGET_WORDS_BIGENDIAN
+# define __put_user(x, hptr) __put_user_e(x, hptr, be)
+# define __get_user(x, hptr) __get_user_e(x, hptr, be)
+#else
+# define __put_user(x, hptr) __put_user_e(x, hptr, le)
+# define __get_user(x, hptr) __get_user_e(x, hptr, le)
+#endif
/* put_user()/get_user() take a guest address and check access */
/* These are usually used to access an atomic data type, such as an int,